Nestify
Nestify is a Rust library offering a powerful macro to streamline the definition of nested structs and enums. Designed to improve code readability and maintainability
Abstract
Nestify re-imagines Rust struct and enum definitions with its "Type is Definition" approach, streamlining the way you handle nested structures. Gone are the days of flipping back and forth between type definitions—Nestify Unifies your codebase, making your code cleaner and far more readable.
Nestify is crafted for ease of learning, with its syntax tailored to be comfortable for Rust developers. The aim is for anyone, even those unfamiliar with the Nest macro, to quickly grasp its concept upon first glance.
Features
- Simplify nested struct and enum definitions in Rust.
- Make your codebase more readable and less verbose.
- Ideal for modeling complex API responses.
- Advanced attribute modifiers.
- Works well with Serde.
- Intuitive syntax
Installation
Add this to your Cargo.toml:
[]
= "0.3.1"
Then use the macro:
use nest;
[!NOTE] A nightly toolchain might provide better error diagnostics
Quick Examples
Simple Nested Structures
Here's a quick example to show how Nestify simplifies nested struct definitions:
// Define a user profile with nested address and preferences structures
nest!
}
Simple Nested Enums
// Define a task with a nested status enum
nest!
}
Supported definitions
Nestify supports both structs and enums.
// field structs (named)
nest!
}
// tuple structs (unnamed)
nest!
// unit structs
nest!
// enums
nest!
// field structs (named)
// tuple structs (unnamed)
;
;
// unit structs
;
// enums
;
Generics
Nestify fully supports Rust's generic parameters. This compatibility ensures that you can incorporate both lifetime and type parameters within your nested struct definitions, just as you would in standard Rust code.
nest!
Nested Generics
When defining nested generics, you need to add generics to types. Enter "FishHook" syntax.
To define generics on the field use ||<...>. This will let you specify the nested generic types.
It also works with lifetimes if needed.
nest!
}
Attributes
You can apply attributes just like you would with a normal struct.
nest!
let x = CloneMe ;
let cl = x.clone;
Recursive Attributes #[meta]*
Using * syntax you can inherit attributes to child structures easily. The attribute
will propagate to each nested structure or enum.
nest!
}
}
Removal Syntax
Disable Propagation #[meta]/
You can end the recursion of an attribute with a / attribute modifier.
It will remove a recursive attribute from the current structure and all nested structures
nest!
}
}
}
Disable Single #[meta]-
Using the - modifier will remove a recursive attribute from a single structure
To use the previous example using - instead of /:
nest!
}
}
}
Field Attributes #>[meta]
If you structure has many defined attributes, it can become awkward to define attributes before the nested structure. To combat this, you can define attributes that apply to nested objects before fields and enum variants. This can be accomplished by using #>[meta] syntax. #> will apply the attribute to the next struct.
nest!
}
// ^^^^^ applied to structure and not field `f`
Enum Variant Attributes
Field attributes can also be applied to an enum variant. If there are multiple items defined in a single variant then the attribute will be applied to each.
nest!
;
;
Semicolons
Rust mandates semicolons to mark the end of tuple struct and unit struct declarations. Nestify, however, introduces flexibility by making this semicolon optional.
Rust Standard
- Tuple struct:
struct MyTuple(i32, String); - Unit struct:
struct MyUnit;
Nestify Flexibility
With Nestify, you can omit the semicolon without any impact:
// Unit struct without a semicolon
nest!
;
// ^ automaticly added
;
// ^ automaticly added
This adjustment simplifies syntax, particularly in the context of defining nested structures, aligning with Nestify's goal of enhancing code readability and maintenance. Whether you include the semicolon or not, Nestify processes the definitions correctly, thanks to its domain-specific optimizations.
Limitations
In Nestify, while you can work with a wide range of complex types to structure your data effectively, there's a specific limitation regarding the definition of new types directly within the generics of other types. This limitation affects scenarios where you might want to dynamically define a struct or enum inside a generic container like Vec<T>, Option<T>, or Result<T, E> as part of the type declaration.
The limitation is specifically around embedding a new type definition within the generic parameters of another type. For instance:
// This pattern is not supported:
;
Here, struct Two is being defined directly within the generic parameter of Vec<T>, which is not currently possible with Nestify.
Another Example
To further illustrate, consider a scenario where you want to include an optional configuration struct within another struct:
// This pattern is also not supported:
;
In this example, struct DatabaseConfig is defined directly within the Option<T> generic type in the declaration of AppConfig. This specific way of defining DatabaseConfig inline as part of the AppConfig declaration is not supported by Nestify at the moment.
Notice how #[derive(Debug)] is applied not to the field as an attribute
but to the nested structure. Applied field attributes are compatible with attribute modifiers.
Regular field attributes are not compatible with attributes.
Contributing
I love contributors. I'm a bad writer, so I would love community support to improve this guide!
To make code changes:
- Fork the repository.
- Create a new branch for your features or bug fixes.
- Write tests for your changes.
- Make sure all tests pass.
- Submit a pull request.
Standard stuff!
License
This project is licensed under the MIT License. If you need it under a different license Contact Me. MIT license support will always be maintained. Don't fear!
Contact me
Check github for information @snowfoxsh