read_only/lib.rs
1//! Read-only field exposure macros.
2//!
3//! This crate intentionally combines two patterns:
4//!
5//! - [`cast`] is the classic cast-based readonly-field pattern, re-exported
6//! from the [`readonly`] crate.
7//! - [`embed`] is this crate's safe composition-based alternative that builds a
8//! dedicated `ReadOnly*` view struct and dereferences into it without unsafe
9//! code in the generated access path.
10//!
11//! Two attributes are provided:
12//!
13//! - `#[cast]` (re-exported from the [`readonly`] crate) — generates a
14//! `ReadOnly*` struct with the same fields and provides `Deref` via an unsafe
15//! pointer cast. Fields remain writable within the defining module but become
16//! read-only externally.
17//!
18//! - `#[embed]` — safe composition pattern. Fields annotated `#[readonly]` are
19//! moved into a `ReadOnly*` struct embedded inside the owning struct. A safe
20//! `Deref<Target=ReadOnly*>` impl is generated. Non-readonly fields stay on
21//! the owning struct and are accessed directly.
22//!
23//! # Choosing a Macro
24//!
25//! Use [`cast`] when you want the familiar `readonly` behavior and the smallest
26//! syntax change.
27//!
28//! Use [`embed`] when you want an explicit readonly view type and a safe
29//! composition-based implementation.
30//!
31//! # About `cast`
32//!
33//! [`cast`] is a re-export of [`readonly::make`]. This crate intentionally uses
34//! the upstream implementation and upstream item documentation for that macro.
35//! The crate-level docs and README provide the local framing for how `cast`
36//! fits beside [`embed`].
37//!
38//! # Examples
39//!
40//! See the runnable examples in:
41//!
42//! - `examples/basic.rs`
43//! - `examples/embed_deref.rs`
44
45#![doc(html_root_url = "https://docs.rs/read-only")]
46
47pub use read_only_derive::embed;
48pub use readonly::make as cast;