#[derive(Recallable)]
{
// Attributes available to this derive:
#[recallable]
}
Expand description
Derive macro that generates a companion memento struct and the Recallable trait impl.
The memento struct mirrors the original but replaces #[recallable]-annotated fields
with their <FieldType as Recallable>::Memento type and omits #[recallable(skip)] fields.
The generated companion type has the same visibility as the input struct.
Its fields are always emitted without visibility modifiers, so they remain private to the
containing module. This is intentional: mementos are meant to be created and consumed alongside
the companion struct, primarily via Recall::recall and TryRecall::try_recall, with only
occasional same-file testing or debugging use.
For container-like field types, this is whatever memento shape that field type chose; the macro
does not special-case merge semantics.
When the impl_from feature is enabled, #[derive(Recallable)] also generates
From<Struct> for the memento type, which requires
<FieldType as Recallable>::Memento: From<FieldType> for each #[recallable] field.
Lifetime parameters are supported only when the generated memento can stay owned:
non-skipped fields may not borrow one of the struct’s lifetimes. Skipped borrowed
fields and lifetime-only markers such as PhantomData<&'a T> are allowed.
This example requires the serde feature.
use recallable::{Recall, Recallable};
#[derive(Clone, Debug, serde::Serialize, Recallable, Recall)]
struct Outer {
label: String,
#[recallable]
inner: Inner,
}
#[derive(Clone, Debug, serde::Serialize, Recallable, Recall)]
struct Inner {
count: u32,
}
// The memento type is accessible via the associated type
let memento: <Outer as Recallable>::Memento =
serde_json::from_str(r#"{"label":"updated","inner":{"count":99}}"#).unwrap();
let mut outer = Outer { label: "original".into(), inner: Inner { count: 0 } };
outer.recall(memento);
assert_eq!(outer.label, "updated");
assert_eq!(outer.inner.count, 99);Derive macro that generates the companion memento type and Recallable impl.
The generated memento type:
- mirrors the original struct shape (named/tuple/unit),
- includes fields unless marked with
#[recallable(skip)], - uses the same visibility as the input struct,
- keeps all generated fields private by omitting field-level visibility modifiers,
- also derives
serde::Deserializewhen theserdefeature is enabled for the macro crate.
For #[recallable] fields, the generated memento field type is exactly
<FieldType as Recallable>::Memento. The macro does not prescribe one canonical container
semantics; it uses whatever memento shape the field type defines.
The companion struct itself is generated as an internal implementation detail. The supported
way to name it is <Struct as Recallable>::Memento. It is intended to be produced and consumed
alongside the source struct, primarily through Recall::recall/TryRecall::try_recall, not as
a field-inspection surface with widened visibility.
The Recallable impl sets type Memento to that generated type and adds any required generic
bounds.
The generated memento struct always derives Clone, Debug, and PartialEq.
When the serde feature is enabled, it also derives serde::Deserialize.
All non-skipped field types must implement these derived traits.
To suppress the default Clone, Debug, and PartialEq derives (and their
corresponding trait bounds), annotate the struct with
#[recallable(skip_memento_default_derives)]. When serde is enabled, Deserialize is
still derived on the memento even with this attribute.
When the impl_from feature is enabled for the macro crate, a
From<Struct> implementation is also generated for the memento type. For #[recallable]
fields, that additionally requires <FieldType as Recallable>::Memento: From<FieldType>.