Module :: variadic_from
The variadic_from crate provides a powerful procedural macro and helper traits to simplify the creation of flexible constructors for Rust structs. It automates the implementation of From-like traits, allowing structs to be instantiated from a variable number of arguments or tuples, reducing boilerplate and enhancing code readability.
Features
- Variadic Constructors: Easily create instances of structs from 0 to 3 arguments using the
from!macro. - Derive Macro (
VariadicFrom): Automatically implementsFromNtraits and standardFrom<T>/From<tuple>for structs with 1, 2, or 3 fields. - Tuple Conversion: Seamlessly convert tuples into struct instances using the standard
FromandIntotraits. - Compile-time Safety: The
from!macro provides compile-time errors for invalid argument counts (e.g., more than 3 arguments). - No Code Generation for >3 Fields: The derive macro intelligently generates no code for structs with 0 or more than 3 fields, preventing unexpected behavior.
Quick Start
To get started with variadic_from, follow these simple steps:
-
Add to your
Cargo.toml:[] = "0.1" # Or the latest version = { = "../variadic_from_meta" } # If using from workspace -
Basic Usage Example:
This example demonstrates the use of the
variadic_frommacro to implement flexible constructors for a struct, allowing it to be instantiated from different numbers of arguments or tuples. It also showcases how to derive common traits likeDebug,PartialEq,Default, andVariadicFromfor the struct. -
Expanded Code Example (What the macro generates):
This section shows the code that the
VariadicFromderive macro generates forMyStruct(a two-field struct), including theFrom2trait implementation and the standardFrom<(T1, T2)>implementation.
Macro Behavior Details
-
#[derive(VariadicFrom)]:- For a struct with 1 field (e.g.,
struct MyStruct(i32)orstruct MyStruct { field: i32 }), it generates:impl From1<FieldType> for MyStructimpl From<FieldType> for MyStruct(delegating toFrom1)
- For a struct with 2 fields (e.g.,
struct MyStruct(i32, i32)orstruct MyStruct { a: i32, b: i32 }), it generates:impl From2<Field1Type, Field2Type> for MyStructimpl From<(Field1Type, Field2Type)> for MyStruct(delegating toFrom2)- Additionally, it generates
impl From1<Field1Type> for MyStruct(whereField1Typeis used for all fields, for convenience).
- For a struct with 3 fields, similar
From3andFrom<(T1, T2, T3)>implementations are generated, along withFrom1andFrom2convenience implementations. - For structs with 0 fields or more than 3 fields, the derive macro generates no code. This means you cannot use
from!orFromNtraits with such structs unless you implement them manually.
- For a struct with 1 field (e.g.,
-
from!Macro:from!()->Default::default()from!(arg1)->From1::from1(arg1)from!(arg1, arg2)->From2::from2(arg1, arg2)from!(arg1, arg2, arg3)->From3::from3(arg1, arg2, arg3)from!(...)with more than 3 arguments will result in a compile-time error.
API Documentation
For detailed API documentation, visit docs.rs/variadic_from.
Contributing
We welcome contributions! Please see our CONTRIBUTING.md for guidelines on how to contribute.
License
This project is licensed under the License file.
Troubleshooting
Too many argumentscompile error withfrom!macro: This means you are trying to usefrom!with more than 3 arguments. The macro currently only supports up to 3 arguments. Consider using a regular struct constructor or manually implementingFromNfor more fields.FromNtrait not implemented: Ensure your struct has#[derive(VariadicFrom)]and the number of fields is between 1 and 3 (inclusive). If it's a 0-field or >3-field struct, the derive macro will not generateFromNimplementations.- Conflicting
Fromimplementations: If you manually implementFrom<T>orFrom<(T1, ...)>for a struct that also derivesVariadicFrom, you might encounter conflicts. Prefer using the derive macro for automatic implementations, or manually implementFromNtraits and use thefrom!macro.
Project Structure
The variadic_from project consists of two main crates:
variadic_from: The main library crate, containing theFromNtraits, thefrom!declarative macro, and blanket implementations.variadic_from_meta: A procedural macro crate that implements the#[derive(VariadicFrom)]macro.
Testing
To run all tests for the project, including unit tests, integration tests, and doc tests:
To run tests for a specific crate:
To run only the doc tests:
Debugging
For debugging procedural macros, you can use cargo expand to see the code generated by the macro. Add #[debug] attribute to your struct to see the expanded code.
You can also use a debugger attached to your test runner.
# Example for VS Code with CodeLLDB
# In .vscode/launch.json:
# {
# "type": "lldb",
# "request": "launch",
# "name": "Debug variadic_from_tests",
# "cargo": {
# "args": [
# "test",
# "--package=variadic_from",
# "--test=variadic_from_tests",
# "--no-run",
# "--message-format=json-render-diagnostics"
# ],
# "filter": {
# "name": "variadic_from_tests",
# "kind": "test"
# }
# },
# "args": [],
# "cwd": "${workspaceFolder}"
# }
Try out from the repository