Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Meta variants #35

Merged
merged 8 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions book/src/codegen/meta-variants.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Meta variant structs and enums

Meta variants are an optional feature, useful for scenarios where you'd want nested
enums at the top-level. structs will be created for all combinations of `meta_variants`
and `variants`, names in the format `{BaseName}{MetaVariantName}{VariantName}`.
Additionally, enums will be created for each `meta_variant` named `{BaseName}{MetaVariantName}`.

For example:

```rust,no_run,no_playground
#[superstruct(meta_variants(Baz, Qux), variants(Foo, Bar))]
struct MyStruct {
name: String,
#[superstruct(only(Foo))]
location: u16,
#[superstruct(meta_only(Baz))]
score: u64,
#[superstruct(only(Bar), meta_only(Qux))]
id: usize,
}
```

Here the `BaseName` is `MyStruct` and there are two variants in the meta-enum called
`Baz` and `Qux`.

The generated enums are:

```rust,no_run,no_playground
enum MyStruct {
Baz(MyStructBaz),
Qux(MyStructQux),
}

enum MyStructBaz {
Foo(MyStructBazFoo),
Bar(MyStructBazBar),
}

enum MyStructQux {
Foo(MyStructQuxFoo),
Bar(MyStructQuxBar),
}
```

The generated variant structs are:

```rust,no_run,no_playground
struct MyStructBazFoo {
name: String,
location: u16,
score: u64,
}

struct MyStructBazBar {
name: String,
score: u64,
}

struct MyStructQuxFoo {
name: String,
location: u16,
}

struct MyStructQuxBar {
name: String,
id: usize,
}
```

Note how the `only` attribute still applies, and a new `meta_only` attribute can be used to
control the presence of fields in each meta variant.

For more information see [Struct attributes](../config/struct.md).
13 changes: 13 additions & 0 deletions book/src/config/struct.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,16 @@ Please see the documentation on [Mapping into other types](./codegen/map-macros.
for an explanation of how these macros operate.

**Format**: one or more `superstruct` type names

## Meta variants

```
#[superstruct(meta_variants(A, B, ...), variants(C, D, ...))]
```

Generate a two-dimensional superstruct.
See [meta variant structs](../codegen/meta-variants.md).

The `meta_variants` attribute is optional.

**Format**: 1+ comma-separated identifiers.
2 changes: 1 addition & 1 deletion src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl FromMeta for NestedMetaList {
/// List of identifiers implementing `FromMeta`.
///
/// Useful for imposing ordering, unlike the `HashMap` options provided by `darling`.
#[derive(Debug)]
#[derive(Debug, Default, Clone)]
pub struct IdentList {
pub idents: Vec<Ident>,
}
Expand Down
Loading
Loading