pub struct Schema {
pub meta: Option<Meta>,
pub internal: Option<Internal>,
}
Expand description
Type of a node: leaf or internal
Fields§
§meta: Option<Meta>
Inner metadata
internal: Option<Internal>
Internal schemata
Implementations§
Source§impl Schema
impl Schema
Sourcepub const fn numbered(numbered: &'static [Numbered]) -> Self
pub const fn numbered(numbered: &'static [Numbered]) -> Self
Create a new internal node schema with named children and without innner metadata
Sourcepub const fn named(named: &'static [Named]) -> Self
pub const fn named(named: &'static [Named]) -> Self
Create a new internal node schema with numbered children and without innner metadata
Sourcepub const fn homogeneous(homogeneous: Homogeneous) -> Self
pub const fn homogeneous(homogeneous: Homogeneous) -> Self
Create a new internal node schema with homogenous children and without innner metadata
Sourcepub const fn is_empty(&self) -> bool
pub const fn is_empty(&self) -> bool
See Self::is_leaf()
Sourcepub fn descend<'a, T, E>(
&'a self,
keys: impl Keys,
func: impl FnMut(&'a Self, Option<(usize, &'a Internal)>) -> Result<T, E>,
) -> Result<T, DescendError<E>>
pub fn descend<'a, T, E>( &'a self, keys: impl Keys, func: impl FnMut(&'a Self, Option<(usize, &'a Internal)>) -> Result<T, E>, ) -> Result<T, DescendError<E>>
Traverse from the root to a leaf and call a function for each node.
If a leaf is found early (keys
being longer than required)
Err(KeyError::TooLong)
is returned.
If keys
is exhausted before reaching a leaf node,
Err(KeyError::TooShort)
is returned.
use miniconf::{IntoKeys, TreeSchema};
#[derive(TreeSchema)]
struct S {
foo: u32,
bar: [u16; 2],
};
let mut ret = [
(S::SCHEMA, Some(1usize)),
(<[u16; 2]>::SCHEMA, Some(0)),
(u16::SCHEMA, None),
].into_iter();
let func = |schema, idx_internal: Option<_>| {
assert_eq!(ret.next().unwrap(), (schema, idx_internal.map(|(idx, _)| idx)));
Ok::<_, Infallible>(())
};
assert_eq!(S::SCHEMA.descend(["bar", "0"].into_keys(), func), Ok(()));
§Args
keys
: AKey
s identifying the node.func
: AFnMut
to be called for each (internal and leaf) node on the path. Its arguments are outer schema and optionally the inner index and internal schema. ReturningErr(E)
aborts the traversal. ReturningOk(T)
continues the downward traversal.
§Returns
The leaf func
call return value.
Sourcepub fn get_meta(
&self,
keys: impl IntoKeys,
) -> Result<(Option<&Option<Meta>>, &Option<Meta>), KeyError>
pub fn get_meta( &self, keys: impl IntoKeys, ) -> Result<(Option<&Option<Meta>>, &Option<Meta>), KeyError>
Look up outer and inner metadata given keys.
Sourcepub fn get(&self, keys: impl IntoKeys) -> Result<&Self, KeyError>
pub fn get(&self, keys: impl IntoKeys) -> Result<&Self, KeyError>
Get the schema of the node identified by keys.
Sourcepub fn transcode<N: Transcode + Default>(
&self,
keys: impl IntoKeys,
) -> Result<N, DescendError<N::Error>>
pub fn transcode<N: Transcode + Default>( &self, keys: impl IntoKeys, ) -> Result<N, DescendError<N::Error>>
Transcode keys to a new keys type representation
The keys can be
- too short: the internal node is returned
- matched length: the leaf node is returned
- too long: Err(TooLong(depth)) is returned
In order to not require N: Default
, use Transcode::transcode
on
an existing &mut N
.
use miniconf::{Indices, JsonPath, Packed, Track, Short, Path, TreeSchema};
#[derive(TreeSchema)]
struct S {
foo: u32,
bar: [u16; 5],
};
let idx = [1, 1];
let sch = S::SCHEMA;
let path = sch.transcode::<Path<String, '/'>>(idx).unwrap();
assert_eq!(path.0.as_str(), "/bar/1");
let path = sch.transcode::<JsonPath<String>>(idx).unwrap();
assert_eq!(path.0.as_str(), ".bar[1]");
let indices = sch.transcode::<Indices<[usize; 2]>>(&path).unwrap();
assert_eq!(indices.as_ref(), idx);
let indices = sch.transcode::<Indices<[usize; 2]>>(["bar", "1"]).unwrap();
assert_eq!(indices.as_ref(), [1, 1]);
let packed = sch.transcode::<Packed>(["bar", "4"]).unwrap();
assert_eq!(packed.into_lsb().get(), 0b1_1_100);
let path = sch.transcode::<Path<String, '/'>>(packed).unwrap();
assert_eq!(path.0.as_str(), "/bar/4");
let node = sch.transcode::<Short<Track<()>>>(&path).unwrap();
assert_eq!((node.leaf(), node.inner().depth()), (true, 2));
§Args
keys
:IntoKeys
to identify the node.
§Returns
Transcoded target and node information on success
Sourcepub const fn nodes<N: Transcode + Default, const D: usize>(
&'static self,
) -> ExactSize<NodeIter<N, D>> ⓘ
pub const fn nodes<N: Transcode + Default, const D: usize>( &'static self, ) -> ExactSize<NodeIter<N, D>> ⓘ
Return an iterator over nodes of a given type
This is a walk of all leaf nodes.
The iterator will walk all paths, including those that may be absent at
runtime (see crate::TreeSchema
).
The iterator has an exact and trusted size_hint()
.
The D
const generic of NodeIter
is the maximum key depth.
use miniconf::{Indices, JsonPath, Short, Track, Packed, Path, TreeSchema};
#[derive(TreeSchema)]
struct S {
foo: u32,
bar: [u16; 2],
};
const MAX_DEPTH: usize = S::SCHEMA.shape().max_depth;
assert_eq!(MAX_DEPTH, 2);
let paths: Vec<_> = S::SCHEMA.nodes::<Path<String, '/'>, MAX_DEPTH>()
.map(|p| p.unwrap().into_inner())
.collect();
assert_eq!(paths, ["/foo", "/bar/0", "/bar/1"]);
let paths: Vec<_> = S::SCHEMA.nodes::<JsonPath<String>, MAX_DEPTH>()
.map(|p| p.unwrap().into_inner())
.collect();
assert_eq!(paths, [".foo", ".bar[0]", ".bar[1]"]);
let indices: Vec<_> = S::SCHEMA.nodes::<Indices<[_; 2]>, MAX_DEPTH>()
.map(|p| p.unwrap().into_inner())
.collect();
assert_eq!(indices, [([0, 0], 1), ([1, 0], 2), ([1, 1], 2)]);
let packed: Vec<_> = S::SCHEMA.nodes::<Packed, MAX_DEPTH>()
.map(|p| p.unwrap().into_lsb().get())
.collect();
assert_eq!(packed, [0b1_0, 0b1_1_0, 0b1_1_1]);
let nodes: Vec<_> = S::SCHEMA.nodes::<Short<Track<()>>, MAX_DEPTH>()
.map(|p| {
let p = p.unwrap();
(p.leaf(), p.inner().depth())
})
.collect();
assert_eq!(nodes, [(true, 1), (true, 2), (true, 2)]);