macro_rules! dyn_access {
($head:ident $($rest:tt)*) => { ... };
(($head:expr) $($rest:tt)*) => { ... };
(@recurse $acc:expr, . $field:ident $($rest:tt)*) => { ... };
(@recurse $acc:expr, [$idx:expr] $($rest:tt)*) => { ... };
(@recurse $acc:expr,) => { ... };
}
Expand description
§dyn_access
The dyn_access
has a specific use-case, which is
accessing very deeply nested values in parsed structures.
For example, imagine you have an API, which you only need some
data for. Usually in JavaScript you simply fetch a value and
access it dinamically with a path like value?.nested?.nested[0]
then simply check for undefined.
This macro permits you access to very nested objects with javascript
like indexers, with the exception you don’t need to use ?
, as you
get an Option<T>
instead.
This macro is recursive and will stop working when the value
doesn’t have a .get
method that returns an Option
To invoke this macro you just use a path like
use serde_json::json;
use dyn_path::dyn_access;
let object = json!({
"very": {
"nested": {
"value": [
"hello",
"world"
]
}
}
});
let hello = dyn_access!(object.very.nested.value[0]).unwrap();
let world = dyn_access!(object.very.nested.value[1]).unwrap();
assert_eq!(hello, "hello");
assert_eq!(world, "world");
You also have indices available to you, whether it is for an array or an object.
Notice how the first element is the name of the variable,
you can have an expression in there with parenthesis like
(value.parse::<serde_json::Value>()?).very.nested.value
,
the parenthesis are due to parsing system limitation since
this is a macro_rules
and not a proc_macro
.