Expand description
A helper macros implementation to build a string that represents struct fields path at compile time.
Library provides a tiny macro implementation to reference Rust struct fields at compile time to represent its string format. This is needed to work with JSON paths, and some others protocols when we still want to rely on the compiler to avoid inconsistent changes.
Features:
- Fast and no macro parsing without huge deps;
- Macro produces the code to verify if the specified path really exists;
- Multiple fields/arrays support
- Optional camelCase and PascalCase conversion support;
- Optional delimiter parameter;
#[derive(StructPath)]to return all of a struct’s declared fields viaType::*, without listing them by hand;Type::*nested under a field path,Parent::child.(Child::*), to prefix every one ofChild’s fields withchild;
Example:
use struct_path::*;
fn example() {
pub struct TestStructParent {
pub value_str: String,
pub value_num: u64,
pub value_child: TestStructChild,
pub opt_value_child: Option<TestStructChild>,
}
pub struct TestStructChild {
pub child_value_str: String,
pub child_value_num: u64,
}
// returns "value_str"
let s1: &str = path!(TestStructParent::value_str);
// returns "value_child.child_value_str"
let s2: &str = path!(TestStructParent::value_child.child_value_str) ;
// returns also "value_child.child_value_str"
let s3: &str = path!(TestStructParent::value_child,TestStructChild::child_value_str);
// options, returns "valueChild/childValueStr"
let s4: &str = path!(TestStructParent::value_child.child_value_str; delim="/", case="camel") ;
// `~` steps through a collection field (Vec, Option, ...) while still
// verifying the path; returns "optValueChild/childValueStr"
let s5: &str = path!(TestStructParent::opt_value_child~child_value_str; delim="/", case="camel") ;
// returns ["value_str", "value_num"]
let arr: [&str; 2] = paths!(TestStructParent::{ value_str, value_num });
}
All fields with Type::*, needing #[derive(StructPath)]; none of the calls above need it.
use struct_path::*;
fn example_all_fields() {
#[derive(StructPath)]
pub struct TestStructWithPrivate {
pub value_str: String,
value_internal: String,
}
// `Type::*` needs `#[derive(StructPath)]` on `Type`; returns ["value_str"],
// only the field declared with plain `pub`
let pub_only: [&str; 1] = paths!(TestStructWithPrivate::*);
// `visibility="all"` returns every declared field instead
let all_fields: [&str; 2] = paths!(TestStructWithPrivate::*; visibility="all");
#[derive(StructPath)]
pub struct TestStructChild {
pub child_value_str: String,
pub child_value_num: u64,
}
pub struct TestStructParent {
pub value_child: TestStructChild,
pub opt_value_child: Option<TestStructChild>,
}
// nested `Type::*`: `TestStructChild` also needs `#[derive(StructPath)]`,
// and is named again inside the parens; returns
// ["value_child.child_value_str", "value_child.child_value_num"]
let nested: [&str; 2] = paths!(TestStructParent::value_child.(TestStructChild::*));
// `~` before the parens steps through the `Option` the same way it does
// for a single field; returns ["opt_value_child.child_value_str", ...]
let nested_opt: [&str; 2] = paths!(TestStructParent::opt_value_child~(TestStructChild::*));
}
Macros§
Derive Macros§
- Struct
Path #[derive(StructPath)]records a struct’s declared field names as#[doc(hidden)]associated consts, sopaths!(Type::*)can return them without the caller listing every field by hand. Supports only a struct with named fields and, at most, lifetime generic parameters; anything else is acompile_error!on the offending item, spanned at the specific token that disqualifies it.