# ref-view
`ref-view` provides `#[derive(RefView)]` for generating zero-copy reference
views over named structs and named-field enums.
```rust
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 accessors
- `ItemRef<'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:
```rust
#[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
## Examples
Run the examples with:
```shell
cargo run --example basic_struct
cargo run --example derive_and_impl_trait
cargo run --example enum_table_reference
```
### Struct Views
`examples/basic_struct.rs` shows a full `UserRef<'a>` and a
`UserPublicView<'a>` that omits sensitive fields:
```rust
#[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`.
### Derives And Trait Implementations
`examples/derive_and_impl_trait.rs` shows how to make generated ref views derive
the same common traits as the source type:
```rust
#[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:
```rust
#[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:
```rust
#[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 one `Display` implementation across `User`, `UserRef<'_>`,
and `PublicUserRef<'_>`
### Enum Views
`examples/enum_table_reference.rs` demonstrates a SQL-like formatter shared by
the source enum, its full ref view, and an omit view:
```rust
#[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.