pub trait Parameterized<P: Parameter>: Sized {
type Family: ParameterizedFamily<P, To = Self> + ParameterizedFamily<Placeholder, To = Self::ParameterStructure>;
type To<T: Parameter>: Parameterized<T, Family = Self::Family, ParameterStructure = Self::ParameterStructure> + SameAs<<Self::Family as ParameterizedFamily<T>>::To>
where Self::Family: ParameterizedFamily<T>;
type ParameterStructure: Parameterized<Placeholder, Family = Self::Family, To<P> = Self> + SameAs<Self::To<Placeholder>>;
type ParameterIterator<'t, T: 't + Parameter>: 't + Iterator<Item = &'t T>
where Self: 't;
type ParameterIteratorMut<'t, T: 't + Parameter>: 't + Iterator<Item = &'t mut T>
where Self: 't;
type ParameterIntoIterator<T: Parameter>: Iterator<Item = T>;
type NamedParameterIterator<'t, T: 't + Parameter>: 't + Iterator<Item = (ParameterPath, &'t T)>
where Self: 't;
type NamedParameterIteratorMut<'t, T: 't + Parameter>: 't + Iterator<Item = (ParameterPath, &'t mut T)>
where Self: 't;
type NamedParameterIntoIterator<T: Parameter>: Iterator<Item = (ParameterPath, T)>;
Show 19 methods
// Required methods
fn parameter_count(&self) -> usize;
fn parameter_structure(&self) -> Self::ParameterStructure;
fn parameters(&self) -> Self::ParameterIterator<'_, P>;
fn parameters_mut(&mut self) -> Self::ParameterIteratorMut<'_, P>;
fn into_parameters(self) -> Self::ParameterIntoIterator<P>;
fn named_parameters(&self) -> Self::NamedParameterIterator<'_, P>;
fn named_parameters_mut(&mut self) -> Self::NamedParameterIteratorMut<'_, P>;
fn into_named_parameters(self) -> Self::NamedParameterIntoIterator<P>;
fn from_parameters_with_remainder<I: Iterator<Item = P>>(
structure: Self::ParameterStructure,
parameters: &mut I,
) -> Result<Self, Error>;
// Provided methods
fn parameter_paths<'p>(&'p self) -> impl 'p + Iterator<Item = ParameterPath>
where P: 'p { ... }
fn from_parameters<I: IntoIterator<Item = P>>(
structure: Self::ParameterStructure,
parameters: I,
) -> Result<Self, Error> { ... }
fn from_named_parameters<I: IntoIterator<Item = (ParameterPath, P)>>(
structure: Self::ParameterStructure,
parameters: I,
) -> Result<Self, Error> { ... }
fn from_broadcasted_named_parameters<I: IntoIterator<Item = (ParameterPath, P)>>(
structure: Self::ParameterStructure,
parameters: I,
) -> Result<Self, Error>
where P: Clone { ... }
fn map_parameters<T: Parameter, F: FnMut(P) -> T>(
self,
map_fn: F,
) -> Result<Self::To<T>, Error>
where Self::Family: ParameterizedFamily<T> { ... }
fn map_named_parameters<T: Parameter, F: FnMut(&ParameterPath, P) -> T>(
self,
map_fn: F,
) -> Result<Self::To<T>, Error>
where Self::Family: ParameterizedFamily<T> { ... }
fn filter_parameters<F: FnMut(&ParameterPath, &P) -> bool>(
self,
predicate: F,
) -> Result<Self::To<Option<P>>, Error>
where Self::Family: ParameterizedFamily<Option<P>> { ... }
fn partition_parameters<F: FnMut(&ParameterPath, &P) -> bool>(
self,
predicate: F,
) -> Result<(Self::To<Option<P>>, Self::To<Option<P>>), Error>
where Self::Family: ParameterizedFamily<Option<P>> { ... }
fn combine_parameters<I: IntoIterator<Item = Self::To<Option<P>>>>(
structure: Self::ParameterStructure,
values: I,
) -> Result<Self, Error>
where P: Debug + PartialEq,
Self::Family: ParameterizedFamily<Option<P>> { ... }
fn replace_parameters(
self,
replacement: Self::To<Option<P>>,
) -> Result<Self, Error>
where Self::Family: ParameterizedFamily<Option<P>> { ... }
}Expand description
Recursively traversable data structure that contains arbitrarily nested Parameter values of type P.
§What is a Parameterized type?
A Parameterized type is a container-like structure that typically contains other container-like structures
that eventually bottom out to Parameter values. For example, we may have a ((usize, P), HashMap<String, P>)
type which contains parameters of type P nested inside it. Parameterized types can be thought of as tree-like
structures that contain Parameter values at their leaves (of type P). Values of such types can be viewed as
having two parts:
- Their structure, which can be obtained via
Self::parameter_structure. - Their parameter values, which can be obtained via
Self::parameters,Self::parameters_mut,Self::into_parameters,Self::named_parameters,Self::named_parameters_mut, andSelf::into_named_parameters.
In the context of machine learning (ML), a Parameterized can contain model parameters, dataset entries,
reinforcement learning agent observations, etc. Ryft provides built-in Parameterized implementations for a wide
range of container-like types, including but not limited to:
- Parameters: All
P: ParameterareParameterized<P>. - Tuples:
()isParameterized<P>for allP: Parameter,(V0)isParameterized<P>whenV0: Parameterized<P>,(V0, V1)isParameterized<P>whenV0: Parameterized<P>andV1: Parameterized<P>, etc., up to size 12. Note that tuples with mixedParameterizedand non-Parameterizedelements are supported only when they appear within types for which we deriveParameterizedimplementations using the#[derive(Parameterized)]macro (described in the Custom Parameterized Types section below). - Options:
Option<V>isParameterized<P>whenV: Parameterized<P>, only when it appears within a type for which we derive aParameterizedimplementation using the#[derive(Parameterized)]macro. That is because we needOption<P>to be aParameterwhenP: Parameterin order to support some of the manipulation functions that are described in the Working with Parameterized Values section below. - Arrays:
[V; N]isParameterized<P>for anyNwhenV: Parameterized<P>. - Vectors:
Vec<V>isParameterized<P>whenV: Parameterized<P>. - Maps:
HashMap<K, V>isParameterized<P>whenK: Clone + Debug + OrdandV: Parameterized<P>, andBTreeMap<K, V>isParameterized<P>whenK: Clone + Debug + OrdandV: Parameterized<P>. - Phantom Data:
PhantomData<P>isParameterized<P>for allP: Parameter, containing no parameters.
Note that Ryft does not provide a generic impl<P: Parameter, V: Parameterized<P>> Parameterized<P> for Box<V>
because it overlaps with the blanket leaf implementation impl<P: Parameter> Parameterized<P> for P. Since Box
is a fundamental type, downstream crates may implement Parameter for Box<T> for some local type T, and
the generic Box implementation would then become non-coherent under Rust’s orphan/coherence rules.
Ryft also provides a convenient #[derive(Parameterized)] macro that can be used to automatically derive
Parameterized implementations for custom types. Refer to the
Custom Parameterized Types section below for information on that macro.
The Parameterized type and the functionality it provides is inspired by and shares a lot of commonalities with
JAX PyTrees and
Equinox’s PyTree manipulation APIs.
§Examples
The following are simple examples showing what Parameterized types are and how they are structured:
// Simple tuple with 3 [`Parameter`]s.
let value = (1, 2, 3);
let parameters = value.parameters().collect::<Vec<_>>();
assert_eq!(value.parameter_count(), 3);
assert_eq!(parameters, vec![&1, &2, &3]);
assert_eq!(value.parameter_structure(), (Placeholder, Placeholder, Placeholder));
// Nested tuple structure with 3 [`Parameter`]s.
let value = (1, (2, 3), ());
let parameters = value.parameters().collect::<Vec<_>>();
assert_eq!(value.parameter_count(), 3);
assert_eq!(parameters, vec![&1, &2, &3]);
assert_eq!(value.parameter_structure(), (Placeholder, (Placeholder, Placeholder), ()));
// Nested map and tuple structure with 5 [`Parameter`]s.
let value = (1, BTreeMap::from([("a", vec![2]), ("b", vec![3, 4])]), (5,));
let parameters = value.parameters().collect::<Vec<_>>();
assert_eq!(value.parameter_count(), 5);
assert_eq!(parameters, vec![&1, &2, &3, &4, &5]);
assert_eq!(
value.parameter_structure(),
(Placeholder, BTreeMap::from([("a", vec![Placeholder]), ("b", vec![Placeholder, Placeholder])]), (Placeholder,)),
);Note that the value returned by Parameterized::parameter_structure is effectively a “shape template”
for a Parameterized value: every parameter in that value is replaced by Placeholder, while values of
non-parameter types are preserved exactly as they are (i.e., they are cloned). This is useful because flattening,
which is described in more detail in the next section, discards structural boundary information, and
Parameterized::ParameterStructure keeps that information so functions like Self::from_parameters
can rebuild values that have the same structure as the original value, but different parameters.
§Working with Parameterized Values
The more interesting part about Parameterized types is what they enable us to do. The following operations are
fundamental to Parameterized types and are almost always involved when working with such types and values:
- Flattening: Given a parameterized value, flattening consists of obtaining a flat iterator over the
parameters that are contained in that value. These parameters may be arbitrarily nested in the value, but we
guarantee that they will always be returned in the same order. This is crucial in enabling the next operation,
unflattening, which is the inverse of the flattening operation. This operation is exposed via the
Self::parameters,Self::parameters_mut, andSelf::into_parametersfunctions. - Unflattening: Given a
Parameterized::ParameterStructureand an iterator over parameter values, unflattening consists of constructing the fully structuredParameterizedvalue that contains those parameters. TheParameterized::ParameterStructureis necessary in enabling this because flattening is a lossy operation for certain types. For example, consider a tuple with twoVec<P>elements. After flattening we obtain a single iterator over parameters of typePwithout having any way of recovering the number of parameters that should go in the first vector versus the second. TheParameterized::ParameterStructureis used to provide that information and make recovery possible. An even more straightforward example is a value contains additional non-parameter information (e.g., consider a(P, usize)tuple). The unflattening operation is exposed via theSelf::from_parametersfunction. - Mapping: Given a
Parameterized<P>value, mapping consists of using a function to map all the parameters nested in that value to new parameters of potentially different types yielding aParameterized<T>value with the same structure. This is effectively a composition of flattening, mapping the individual parameters, and unflattening to obtain the final structured value. This operation is important in enabling things like tracing of functions that take parameterized data structures as inputs, whereby we can map all the nested parameters to tracer variables. It can also be used in a similar way to enable automatic differentiation, etc. It is a fundamental component of how the core features of Ryft are implemented. This operation is exposed via theSelf::map_parametersfunction.
These core operations are also supported with named parameters, where each parameter is paired with a
ParameterPath specifying where in the nested data structure it belongs. This is useful for things like saving
model checkpoints, etc. These named parameter operation variants are exposed via the Self::named_parameters,
Self::named_parameters_mut, Self::into_named_parameters, Self::from_named_parameters,
Self::from_broadcasted_named_parameters, Self::map_named_parameters, and Self::map_named_parameters
functions.
Note that, the Parameterized trait also defines a bunch of additional functions that are implemented using the
aforementioned core primitives like Self::partition_parameters, Self::filter_parameters, etc. You should
refer to the full list of the Parameterized trait functions and their documentation for more information.
§Examples
The following examples show the flattening, unflattening, and mapping operations in action:
type Value = (i32, BTreeMap<&'static str, Vec<i32>>, (i32,));
let value = (1, BTreeMap::from([("a", vec![2]), ("b", vec![3, 4])]), (5,));
// Flattening:
assert_eq!(value.parameters().copied().collect::<Vec<_>>(), vec![1, 2, 3, 4, 5]);
// Unflattening:
assert_eq!(
Value::from_parameters(value.parameter_structure(), vec![10, 20, 30, 40, 50])?,
(10, BTreeMap::from([("a", vec![20]), ("b", vec![30, 40])]), (50,)),
);
// Mapping:
assert_eq!(
value.clone().map_parameters(|parameter| (parameter as i64) * 10)?,
(10_i64, BTreeMap::from([("a", vec![20_i64]), ("b", vec![30_i64, 40_i64])]), (50_i64,)),
);
// Flattening to named parameters:
assert_eq!(
value.named_parameters().map(|(path, parameter)| (path.to_string(), *parameter)).collect::<Vec<_>>(),
vec![
("$.0".to_string(), 1),
("$.1[\"a\"][0]".to_string(), 2),
("$.1[\"b\"][0]".to_string(), 3),
("$.1[\"b\"][1]".to_string(), 4),
("$.2.0".to_string(), 5),
],
);
// Unflattening from named parameters:
assert_eq!(
Value::from_named_parameters(
value.parameter_structure(),
value.clone().into_named_parameters().collect::<HashMap<_, _>>(),
)?,
value,
);
// Mapping named parameters:
assert_eq!(
value.clone().map_named_parameters(|path, parameter| (parameter as i64) + (path.len() as i64))?,
(2_i64, BTreeMap::from([("a", vec![5_i64]), ("b", vec![6_i64, 7_i64])]), (7_i64,)),
);
// Unflattening from broadcasted named parameters:
assert_eq!(
Value::from_broadcasted_named_parameters(
value.parameter_structure(),
HashMap::from([
(ParameterPath::root(), 0),
(ParameterPath::root().with_segment(ParameterPathSegment::TupleIndex(1)), 10),
(
ParameterPath::root()
.with_segment(ParameterPathSegment::TupleIndex(1))
.with_segment(ParameterPathSegment::Key(format!("{:?}", "b")))
.with_segment(ParameterPathSegment::Index(1)),
30,
),
]),
)?,
(0, BTreeMap::from([("a", vec![10]), ("b", vec![10, 30])]), (0,)),
);
§Custom Parameterized Types
Ryft provides a #[derive(Parameterized)] procedural macro (via the ryft-macros crate) that can be used to
generate implementations of both ParameterizedFamily and Parameterized for custom structs and enums.
Concretely, the derived implementations:
- Preserve the container shape and non-parameter data.
- Treat every field or nested field that references the parameter type as part of the types parameters.
- Recursively delegate traversal to nested
Parameterizedfield types. - Preserve the variant information when traversing and rebuilding enums.
The macro has the following requirements:
- The type on which it is used must be a struct or an enum. Unions are not supported.
- There must be exactly one generic type bounded by
Parameter. - The parameter type must be owned in parameter fields (i.e., parameter references or pointers are not allowed).
- Nested tuples that mix parameterized and non-parameterized elements are supported inside derived structs and
enums. However, the same kinds of mixed tuples are not generally supported inside other generic containers
(e.g.,
Vec<(P, usize)>), unless those container element types already satisfy the requiredParameterizedbounds. - The generated implementation reserves internal identifiers (e.g.,
'__pand__P) for macro-internal lifetime and type parameters. User-defined generics should avoid these names. The safest approach is not use names that start with__but, if you do, be aware of the possibility for name conflicts due to these internal identifiers.
Furthermore, it makes the following assumptions:
- All fields that reference or depend on the parameter type are treated as parameter fields.
- Non-parameter fields are carried through unchanged and may induce additional trait bounds in the generated
implementations (e.g., a
Clonebound is required for implementingSelf::parameter_structure). - Generic parameters and their attributes are otherwise carried through as they are.
This macro also supports a container-level derive attribute, #[ryft(crate = "...")], that overrides the path used
reference Ryft types from the generated code. This is primarily meant for deriving implementations inside wrapper
crates that re-export ryft under a different path. It should not be needed for the majority of use cases. Note
also that the #[ryft(...)] attribute is not supported on individual struct fields or enum variants.
§Examples
The following examples show how to use the #[derive(Parameterized)] macro:
#[derive(Debug, Clone, PartialEq, Eq, Parameterized)]
struct Layer<P: Parameter> {
weights: Vec<P>,
bias: P,
metadata: (usize, usize),
}
#[derive(Debug, Clone, PartialEq, Eq, Parameterized)]
enum Block<P: Parameter> {
Identity,
Residual {
trunk: Layer<P>,
shortcut: (P, usize),
tag: &'static str,
},
}
let layer = Layer { weights: vec![1, 2, 3], bias: 4, metadata: (3, 1) };
assert_eq!(layer.parameter_count(), 4);
assert_eq!(layer.parameters().collect::<Vec<_>>(), vec![&1, &2, &3, &4]);
assert_eq!(
layer.named_parameters().map(|(path, parameter)| (path.to_string(), *parameter)).collect::<Vec<_>>(),
vec![
("$.weights[0]".to_string(), 1),
("$.weights[1]".to_string(), 2),
("$.weights[2]".to_string(), 3),
("$.bias".to_string(), 4),
],
);
assert_eq!(
layer.parameter_structure(),
Layer {
weights: vec![Placeholder, Placeholder, Placeholder],
bias: Placeholder,
metadata: (3, 1),
},
);
let block = Block::Residual {
trunk: Layer { weights: vec![10_i32, 20, 30], bias: 40, metadata: (2, 3) },
shortcut: (50, 7),
tag: "residual",
};
assert_eq!(block.parameter_count(), 5);
assert_eq!(block.parameters().collect::<Vec<_>>(), vec![&10, &20, &30, &40, &50]);
assert_eq!(
block.named_parameters().map(|(path, parameter)| (path.to_string(), *parameter)).collect::<Vec<_>>(),
vec![
("$.residual.trunk.weights[0]".to_string(), 10),
("$.residual.trunk.weights[1]".to_string(), 20),
("$.residual.trunk.weights[2]".to_string(), 30),
("$.residual.trunk.bias".to_string(), 40),
("$.residual.shortcut.0".to_string(), 50),
],
);
assert_eq!(
block.parameter_structure(),
Block::Residual {
trunk: Layer {
weights: vec![Placeholder, Placeholder, Placeholder],
bias: Placeholder,
metadata: (2, 3),
},
shortcut: (Placeholder, 7),
tag: "residual",
},
);
assert_eq!(
Block::from_parameters(
block.parameter_structure(),
vec![1i64, 2i64, 3i64, 4i64, 5i64],
)?,
Block::Residual {
trunk: Layer { weights: vec![1i64, 2i64, 3i64], bias: 4i64, metadata: (2, 3) },
shortcut: (5i64, 7),
tag: "residual",
},
);
Required Associated Types§
Sourcetype Family: ParameterizedFamily<P, To = Self> + ParameterizedFamily<Placeholder, To = Self::ParameterStructure>
type Family: ParameterizedFamily<P, To = Self> + ParameterizedFamily<Placeholder, To = Self::ParameterStructure>
ParameterizedFamily that this type belongs to and which can be used to reparameterize it.
Sourcetype To<T: Parameter>: Parameterized<T, Family = Self::Family, ParameterStructure = Self::ParameterStructure> + SameAs<<Self::Family as ParameterizedFamily<T>>::To>
where
Self::Family: ParameterizedFamily<T>
type To<T: Parameter>: Parameterized<T, Family = Self::Family, ParameterStructure = Self::ParameterStructure> + SameAs<<Self::Family as ParameterizedFamily<T>>::To> where Self::Family: ParameterizedFamily<T>
Reparameterized form of this Parameterized type with all of its nested P parameter types replaced by T.
This preserves the same Family and ParameterStructure, and is
such that reparameterizing back to P recovers Self.
Sourcetype ParameterStructure: Parameterized<Placeholder, Family = Self::Family, To<P> = Self> + SameAs<Self::To<Placeholder>>
type ParameterStructure: Parameterized<Placeholder, Family = Self::Family, To<P> = Self> + SameAs<Self::To<Placeholder>>
Type that represents a shape-only representation of this Parameterized type with all nested P parameter
types replaced by Placeholder. This must always be set to Self::To<Placeholder>. The only reason this is
not done by default is that defaulted associated types are not supported in stable Rust, and this forces us to
require that all implementations provide an implementation for this associated type as well.
Sourcetype ParameterIterator<'t, T: 't + Parameter>: 't + Iterator<Item = &'t T>
where
Self: 't
type ParameterIterator<'t, T: 't + Parameter>: 't + Iterator<Item = &'t T> where Self: 't
Iterator returned by Self::parameters for a borrow of the underlying Parameters with lifetime 't.
This is an associated type instead of an impl Iterator in the corresponding function signature, so that
implementations can expose and reuse a concrete iterator type. In particular, #[derive(Parameterized)] for
enums synthesizes concrete enum iterators here, avoiding an additional heap allocation and dynamic dispatch.
Sourcetype ParameterIteratorMut<'t, T: 't + Parameter>: 't + Iterator<Item = &'t mut T>
where
Self: 't
type ParameterIteratorMut<'t, T: 't + Parameter>: 't + Iterator<Item = &'t mut T> where Self: 't
Iterator returned by Self::parameters_mut for a mutable borrow of the underlying Parameters with
lifetime 't. Similar to Self::ParameterIterator, this is an associated type instead of an impl Iterator
in the corresponding function signature, so that implementations can expose and reuse a concrete iterator type,
potentially avoiding additional heap allocations and dynamic dispatch.
Sourcetype ParameterIntoIterator<T: Parameter>: Iterator<Item = T>
type ParameterIntoIterator<T: Parameter>: Iterator<Item = T>
Iterator returned by Self::into_parameters, consuming self and returning the underlying Parameters.
Similar to Self::ParameterIterator, this is an associated type instead of an impl Iterator in the
corresponding function signature, so that implementations can expose and reuse a concrete iterator type,
potentially avoiding additional heap allocations and dynamic dispatch.
Sourcetype NamedParameterIterator<'t, T: 't + Parameter>: 't + Iterator<Item = (ParameterPath, &'t T)>
where
Self: 't
type NamedParameterIterator<'t, T: 't + Parameter>: 't + Iterator<Item = (ParameterPath, &'t T)> where Self: 't
Iterator returned by Self::named_parameters, borrowing the underlying Parameters and pairing them with
their corresponding ParameterPaths. Similar to Self::ParameterIterator, this is an associated type
instead of an impl Iterator in the corresponding function signature, so that implementations can expose and
reuse a concrete iterator type, potentially avoiding additional heap allocations and dynamic dispatch.
Sourcetype NamedParameterIteratorMut<'t, T: 't + Parameter>: 't + Iterator<Item = (ParameterPath, &'t mut T)>
where
Self: 't
type NamedParameterIteratorMut<'t, T: 't + Parameter>: 't + Iterator<Item = (ParameterPath, &'t mut T)> where Self: 't
Iterator returned by Self::named_parameters_mut, mutably borrowing the underlying Parameters and pairing
them with their corresponding ParameterPaths. Similar to Self::ParameterIterator, this is an associated
type instead of an impl Iterator in the corresponding function signature, so that implementations can expose
and reuse a concrete iterator type, potentially avoiding additional heap allocations and dynamic dispatch.
Sourcetype NamedParameterIntoIterator<T: Parameter>: Iterator<Item = (ParameterPath, T)>
type NamedParameterIntoIterator<T: Parameter>: Iterator<Item = (ParameterPath, T)>
Iterator returned by Self::into_named_parameters, consuming self and returning the underlying
Parameters together with their corresponding ParameterPaths. Similar to Self::ParameterIterator,
this is an associated type instead of an impl Iterator in the corresponding function signature, so that
implementations can expose and reuse a concrete iterator type, potentially avoiding additional heap allocations
and dynamic dispatch.
Required Methods§
Sourcefn parameter_count(&self) -> usize
fn parameter_count(&self) -> usize
Returns the number of parameters in this Parameterized value.
Sourcefn parameter_structure(&self) -> Self::ParameterStructure
fn parameter_structure(&self) -> Self::ParameterStructure
Returns the structure of this value by replacing all of its nested parameters with Placeholders.
Sourcefn parameters(&self) -> Self::ParameterIterator<'_, P>
fn parameters(&self) -> Self::ParameterIterator<'_, P>
Returns an iterator over references to all parameters in this Parameterized value. The returned
iterator traverses the parameters in the same order as Self::parameters_mut, Self::into_parameters,
Self::named_parameters, Self::named_parameters_mut, and Self::into_named_parameters.
Sourcefn parameters_mut(&mut self) -> Self::ParameterIteratorMut<'_, P>
fn parameters_mut(&mut self) -> Self::ParameterIteratorMut<'_, P>
Returns an iterator over mutable references to all parameters in this Parameterized value. The returned
iterator traverses the parameters in the same order as Self::parameters, Self::into_parameters,
Self::named_parameters, Self::named_parameters_mut, and Self::into_named_parameters.
Sourcefn into_parameters(self) -> Self::ParameterIntoIterator<P>
fn into_parameters(self) -> Self::ParameterIntoIterator<P>
Consumes this Parameterized value and returns an iterator over all parameters contained in it. The
returned iterator traverses the parameters in the same order as Self::parameters, Self::parameters_mut,
Self::named_parameters, Self::named_parameters_mut, and Self::into_named_parameters.
Sourcefn named_parameters(&self) -> Self::NamedParameterIterator<'_, P>
fn named_parameters(&self) -> Self::NamedParameterIterator<'_, P>
Returns an iterator over references to all parameters in this Parameterized value, paired with their
corresponding ParameterPaths. The returned iterator traverses the parameters in the same order as
Self::parameters, Self::parameters_mut, Self::into_parameters, Self::named_parameters_mut,
and Self::into_named_parameters.
Sourcefn named_parameters_mut(&mut self) -> Self::NamedParameterIteratorMut<'_, P>
fn named_parameters_mut(&mut self) -> Self::NamedParameterIteratorMut<'_, P>
Returns an iterator over mutable references to all parameters in this Parameterized value, paired with
their corresponding ParameterPaths. The returned iterator traverses the parameters in the same order as
Self::parameters, Self::parameters_mut, Self::into_parameters, Self::named_parameters, and
Self::into_named_parameters.
Sourcefn into_named_parameters(self) -> Self::NamedParameterIntoIterator<P>
fn into_named_parameters(self) -> Self::NamedParameterIntoIterator<P>
Consumes this Parameterized value and returns an iterator over all parameters contained in it, paired with
their corresponding ParameterPaths. The returned iterator traverses the parameters in the same order as
Self::parameters, Self::parameters_mut, Self::into_parameters, Self::named_parameters,
and Self::named_parameters_mut.
Sourcefn from_parameters_with_remainder<I: Iterator<Item = P>>(
structure: Self::ParameterStructure,
parameters: &mut I,
) -> Result<Self, Error>
fn from_parameters_with_remainder<I: Iterator<Item = P>>( structure: Self::ParameterStructure, parameters: &mut I, ) -> Result<Self, Error>
Reconstructs a value of this Parameterized type having the provided structure and consuming values
from the provided parameters to populate its parameters. This function may not consume all the provided
parameters, but if there are not enough parameters in the provided iterator, it will return a
Error::MissingParameters error.
Provided Methods§
Sourcefn parameter_paths<'p>(&'p self) -> impl 'p + Iterator<Item = ParameterPath>where
P: 'p,
fn parameter_paths<'p>(&'p self) -> impl 'p + Iterator<Item = ParameterPath>where
P: 'p,
Returns an iterator over the ParameterPaths to all nested parameters in this Parameterized value.
The returned iterator traverses the paths in the same order as Self::parameters, Self::parameters_mut,
Self::into_parameters, Self::named_parameters, Self::named_parameters_mut, and
Self::into_named_parameters.
Sourcefn from_parameters<I: IntoIterator<Item = P>>(
structure: Self::ParameterStructure,
parameters: I,
) -> Result<Self, Error>
fn from_parameters<I: IntoIterator<Item = P>>( structure: Self::ParameterStructure, parameters: I, ) -> Result<Self, Error>
Reconstructs a value of this Parameterized type having the provided structure and consuming values
from the provided parameters to populate its parameters. This function expects to fully consume the provided
iterator. If it does not contain enough values, then it will return a Error::MissingParameters error, while
if it contains too many values, it will return an Error::UnusedParameters. If you do not want to fully
consume the provided iterator, then you must use Self::from_parameters_with_remainder instead.
Sourcefn from_named_parameters<I: IntoIterator<Item = (ParameterPath, P)>>(
structure: Self::ParameterStructure,
parameters: I,
) -> Result<Self, Error>
fn from_named_parameters<I: IntoIterator<Item = (ParameterPath, P)>>( structure: Self::ParameterStructure, parameters: I, ) -> Result<Self, Error>
Reconstructs a value of this Parameterized type having the provided structure and consuming named values
from the provided parameters to populate its parameters. Unlike Self::from_broadcasted_named_parameters,
this function is strict in that keys in parameters must match exactly leaf ParameterPaths in structure,
and path prefix matching is not being used. If there are missing parameters preventing reconstruction from
being feasible, then this function will return a Error::MissingParameters error. Furthermore, if extra
paths remain after reconstruction, then it will return an Error::UnusedParameters error. For fully worked
examples, refer to the examples provided in the top-level documentation of the Parameterized trait.
Sourcefn from_broadcasted_named_parameters<I: IntoIterator<Item = (ParameterPath, P)>>(
structure: Self::ParameterStructure,
parameters: I,
) -> Result<Self, Error>where
P: Clone,
fn from_broadcasted_named_parameters<I: IntoIterator<Item = (ParameterPath, P)>>(
structure: Self::ParameterStructure,
parameters: I,
) -> Result<Self, Error>where
P: Clone,
Reconstructs a value of this Parameterized type having the provided structure and consuming named values
from the provided parameters to populate its parameters, where keys in parameters are interpreted as path
prefixes. Unlike Self::from_named_parameters, this function does not require exact leaf paths, and each
leaf path in structure receives the value from the most specific matching path prefix (i.e., the longest
shared path prefix). If any leaf path is not covered by a provided prefix, then this function will return
a Error::MissingParameters error. Furthermore, if there are any remaining ParameterPaths with no match
in structure, then it will return an Error::UnusedParameters error. Note that since one prefix value may
need to populate multiple leaves, this function requires P: Clone. For fully worked examples, refer to the
examples provided in the top-level documentation of the Parameterized trait.
Sourcefn map_parameters<T: Parameter, F: FnMut(P) -> T>(
self,
map_fn: F,
) -> Result<Self::To<T>, Error>where
Self::Family: ParameterizedFamily<T>,
fn map_parameters<T: Parameter, F: FnMut(P) -> T>(
self,
map_fn: F,
) -> Result<Self::To<T>, Error>where
Self::Family: ParameterizedFamily<T>,
Maps each nested Parameter of type P in this value using the provided map_fn to a Parameter of type
T, while preserving the Parameterized structure of this type. Nested parameters are visited in the same
order as Self::parameters, Self::parameters_mut, Self::into_parameters, Self::named_parameters,
Self::named_parameters_mut, and Self::into_named_parameters.
Sourcefn map_named_parameters<T: Parameter, F: FnMut(&ParameterPath, P) -> T>(
self,
map_fn: F,
) -> Result<Self::To<T>, Error>where
Self::Family: ParameterizedFamily<T>,
fn map_named_parameters<T: Parameter, F: FnMut(&ParameterPath, P) -> T>(
self,
map_fn: F,
) -> Result<Self::To<T>, Error>where
Self::Family: ParameterizedFamily<T>,
Maps each nested Parameter of type P in this value using the provided map_fn, which receives the
ParameterPath for each Parameter along with its value, and returns a new Parameter value of type
T, while preserving the Parameterized structure of this type. Nested parameters are visited in the
same order as Self::parameters, Self::parameters_mut, Self::into_parameters,
Self::named_parameters, Self::named_parameters_mut, and Self::into_named_parameters.
Sourcefn filter_parameters<F: FnMut(&ParameterPath, &P) -> bool>(
self,
predicate: F,
) -> Result<Self::To<Option<P>>, Error>
fn filter_parameters<F: FnMut(&ParameterPath, &P) -> bool>( self, predicate: F, ) -> Result<Self::To<Option<P>>, Error>
Filters all nested Parameters of type P in this value according to the provided predicate, producing a
structure-preserving Parameterized value with Option<P> leaves. Specifically, this value is a
Parameterized<P> and this function returns a Parameterized<Option<P>> where each parameter of this value
for which predicate returns true is kept as Some, while all other parameters are replaced by None.
This function is inspired by
Equinox’s filter function.
§Example
let value = vec![(1_i32, 2_i32), (3_i32, 4_i32)];
// Keep only the second tuple element across all top-level entries.
let filtered = value.filter_parameters(|path, _| path.to_string().ends_with(".1"))?;
assert_eq!(filtered, vec![(None, Some(2)), (None, Some(4))]);
Sourcefn partition_parameters<F: FnMut(&ParameterPath, &P) -> bool>(
self,
predicate: F,
) -> Result<(Self::To<Option<P>>, Self::To<Option<P>>), Error>
fn partition_parameters<F: FnMut(&ParameterPath, &P) -> bool>( self, predicate: F, ) -> Result<(Self::To<Option<P>>, Self::To<Option<P>>), Error>
Partitions all nested Parameters of type P in this value into two structure-preserving Parameterized
values, according to the provided predicate. Specifically, this value is a Parameterized<P> and this
function returns a pair of Parameterized<Option<P>> values. The first one contains Some for each parameter
for which the provided predicate returns true, and None elsewhere, and the opposite holds for the second
returned value. This function is equivalent to using Self::filter_parameters twice on the same value, but it
avoids traversing the structure twice.
This function is inspired by
Equinox’s partition function.
§Example
let value = vec![(1_i32, 2_i32), (3_i32, 4_i32)];
// Keep only parameters under the second top-level element in `partition_0`.
let (partition_0, partition_1) = value.partition_parameters(|path, _| path.to_string().starts_with("$[1]"))?;
assert_eq!(partition_0, vec![(None, None), (Some(3), Some(4))]);
assert_eq!(partition_1, vec![(Some(1), Some(2)), (None, None)]);
Sourcefn combine_parameters<I: IntoIterator<Item = Self::To<Option<P>>>>(
structure: Self::ParameterStructure,
values: I,
) -> Result<Self, Error>
fn combine_parameters<I: IntoIterator<Item = Self::To<Option<P>>>>( structure: Self::ParameterStructure, values: I, ) -> Result<Self, Error>
Combines multiple structure-aligned Parameterized<Option<P>> values into a single Parameterized<P> value,
using left-to-right precedence at each parameter location. That is, for each leaf ParameterPath in
structure, this function selects the first Some value from values and uses it for the corresponding
location in the resulting Parameterized value that the function returns. If multiple non-None values are
present for the same leaf, then they must all be equal, and otherwise this function returns an
Error::AmbiguousParameterCombination error. If no Some value is found for some leaf
ParameterPath, then this function will return a Error::MissingParameters error. Furthermore, if any of
the provided values contains additional Parameters, beyond those that correspond to ones in structure,
then this function will return an Error::UnusedParameters error.
This function is typically used to reconstruct values from the results of calling Self::filter_parameters
and Self::partition_parameters. It is inspired by
Equinox’s combine function.
§Example
let value = vec![(1_i32, 2_i32), (3_i32, 4_i32)];
let structure = value.parameter_structure();
// Split by top-level element and then reconstruct the original value.
let (partition_0, partition_1) = value.partition_parameters(|path, _| path.to_string().starts_with("$[0]"))?;
let combined = Vec::<(i32, i32)>::combine_parameters(
structure,
vec![partition_0, partition_1],
)?;
assert_eq!(combined, vec![(1, 2), (3, 4)]);
Sourcefn replace_parameters(
self,
replacement: Self::To<Option<P>>,
) -> Result<Self, Error>
fn replace_parameters( self, replacement: Self::To<Option<P>>, ) -> Result<Self, Error>
Replaces nested Parameters of type P in this value using a structure-aligned Parameterized<Option<P>>
replacement value. For each parameter, Some in replacement overrides the current value from self,
while None keeps the current value unchanged. If replacement is missing parameters for the expected
structure, this function will return a Error::MissingParameters error. Furthermore, if replacement
contains extra parameters, this function will return an Error::UnusedParameters error.
§Example
let value = vec![(1_i32, 2_i32), (3_i32, 4_i32)];
// Replace only the first field of the second tuple.
let replaced = value.replace_parameters(vec![(None, None), (Some(99), None)])?;
assert_eq!(replaced, vec![(1, 2), (99, 4)]);
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.