Macro sophia_iri::wrap
source · macro_rules! wrap { ($wid:ident<$tid:ident: $bound:path>: $new:item $($item:item)*) => { ... }; ($wid:ident borrowing $bid:ty: $new:item $($item:item)*) => { ... }; }
Expand description
This macro is used to create a read-only wrapper around a type T, usually for the purpose of guaranteeing that the wrapped value verifies some condition. This macro takes care of defining all the usual traits for the wrapper type.
In its most general form, it is used like this:
wrap! { MyWrapper<T: SomeTrait> :
// NB: the trait bound is required, as well as the trailing colon (':').
// You can include members in the impl of the wrapper type.
// At the very least, you must define a `new` constructor,
// that will check the appropriate condition on the wrapped value,
// and return a `Result`.
/// The `new` constructor should carry the documentation of the type;
/// since the generated documentation for the type will point to it.
pub fn new(inner: T) -> Result<Self, SomeError> {
if inner.check_some_property() {
Ok(Self(inner))
} else {
Err(SomeError {})
}
}
}
A more specific form is when the trait that T must satisfy
is std::borrow::Borrow<U>
, in which case more traits
can be implemented by the wrapper. This is achieved with
the following syntax:
wrap! { Foo borrowing str :
/// As before
pub fn new(inner: T) -> Result<Self, String> {
if inner.borrow().contains("foo") {
Ok(Self(inner))
} else {
Err(format!("{:?} is not a valid Foo", inner.borrow()))
}
}
}
Two examples are availble, illustrating the members and trait implementation generated by this macro.
NB: the documentation of the wrapper will point to the documentation of the new
method.