ref-view provides #[derive(RefView)] for generating zero-copy reference
views over named structs and named-field enums.
use ref_view::RefView;
#[derive(RefView)]
#[ref_view(name = ItemWithoutPayload, omit(payload))]
struct Item {
id: u64,
payload: Option<String>,
}By default the macro generates:
ItemView: a trait with field accessorsItemRef<'a>: a full reference view
Additional #[ref_view(name = ..., omit(...))] attributes generate views that
do not store omitted fields. Their accessors return None.
For enums, omit targets can be variant-qualified:
#[derive(RefView)]
#[ref_view(name = TableRefWithoutPivot, omit(Table.pivot, Subquery.pivot))]
enum TableRef {
Table { pivot: String },
Subquery { pivot: String },
}MVP limits:
- only non-generic types
- only named structs and named-field enum variants
Run the examples with:
cargo run --example basic_struct
cargo run --example derive_and_impl_trait
cargo run --example enum_table_referenceexamples/basic_struct.rs shows a full UserRef<'a> and a
UserPublicView<'a> that omits sensitive fields:
#[derive(RefView)]
#[ref_view(name = UserPublicView, omit(email, api_token))]
struct User {
id: u64,
name: String,
email: Option<String>,
api_token: String,
}Fields omitted by at least one view get Option<&T> accessors. The full view
returns Some(...); the omitted view returns None.
The same example also shows #[ref_view(trait_name = ConfigLike)], which makes
generated views implement ConfigLike instead of the default ConfigView.
examples/derive_and_impl_trait.rs shows how to make generated ref views derive
the same common traits as the source type:
#[derive(Debug, PartialEq, Eq, RefView)]
#[ref_view(derive(Debug, PartialEq, Eq))]
#[ref_view(name = PublicUserRef, omit(email, api_token))]
struct User {
id: u64,
name: String,
email: Option<String>,
api_token: String,
}Functions can be widened to accept the source type and generated views:
#[ref_view::impl_fn(UserView)]
fn compact_label(user: &User) -> String {
format!("{}#{} ({:?})", user.name(), user.id(), user.role())
}Normal impl blocks can be mirrored to generated ref views:
#[ref_view::impl_trait(UserView => UserRef<'_>, PublicUserRef<'_>)]
impl std::fmt::Display for User {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} [{}]", compact_label(self), optional_contact(self))
}
}The macro always derives Clone and Copy for generated views. Extra derives
are explicit via #[ref_view(derive(...))] instead of copied automatically from
the source type, because derives such as Default may not make sense for
borrowed views.
The example also demonstrates trait-oriented patterns:
- functions taking
&impl UserView - generic functions with
T: UserView - blanket impls for local traits over every
T: UserView - widened helper functions via
#[ref_view::impl_fn(...)] - mirrored trait impls for generated ref views via
#[ref_view::impl_trait(...)], such as sharing oneDisplayimplementation acrossUser,UserRef<'_>, andPublicUserRef<'_>
examples/enum_table_reference.rs demonstrates a SQL-like formatter shared by
the source enum, its full ref view, and an omit view:
#[derive(RefView)]
#[ref_view(name = TableReferenceWithoutPivot, omit(Table.pivot, Subquery.pivot))]
enum TableReference {
Table { pivot: String, /* ... */ },
Subquery { pivot: String, /* ... */ },
}The formatter calls pivot() normally. Full views return the pivot; the omit
view returns None, so the same formatter can render a table reference without
the pivot clause.