oxide_generator_rs
oxide_generator_rs provides proc-macro attributes used to annotate Oxide state and reducer types.
The macros embed structured metadata as Rust doc strings so that code generation tools can discover:
- state names and field shapes
- action names and variant shapes
- reducer ↔ state/actions associations
This crate is intentionally usage-agnostic. For end-to-end Rust ↔ Flutter wiring, see the repository examples and the root README.
Add It To Your Crate
In your Cargo.toml:
[]
= "0.2.0"
= "0.2.0"
When working inside this repository, use combined version + path dependencies (Cargo prefers path locally, while published crates resolve by version):
= { = "0.2.0", = "../rust/oxide_core" }
= { = "0.2.0", = "../rust/oxide_generator_rs" }
Macros
#[state]
Use on a struct (single-state) or enum (multi-state).
The macro ensures these derives exist:
Debug, Clone, PartialEq, Eq
Serialization derives (Serialize, Deserialize) are only added when the state-persistence feature is enabled on oxide_generator_rs. When enabled, the macro also injects #[serde(crate = "oxide_core::serde")] so downstream crates do not need to depend on serde directly.
Example (struct state):
use state;
Optional: #[state(sliced = true)]
Enable sliced updates on a struct state to generate a slice enum and fieldwise slice inference.
use state;
// The macro generates:
// - a slice enum named `AppStateSlice` (one variant per top-level field)
// - an `oxide_core::SlicedState` impl that compares top-level fields with `PartialEq`
// - a helper `AppState::infer_slices_impl(before, after)` returning `Vec<AppStateSlice>`
Notes:
- Only supported on structs with named fields.
- Not supported on enums (use a struct with top-level fields if you need slicing).
Example (enum state):
use state;
#[actions]
Use on an enum representing a reducer’s action set.
The macro injects the same derives and serde crate attribute as #[state].
Example:
use actions;
#[reducer(...)]
Use on an impl oxide_core::Reducer for <Type> block.
Argument syntax
The macro uses a small, keyword-based mini-language inside the attribute. Each entry is either:
- a key-value pair:
key = <value> - a flag:
no_frb
Entries are comma-separated and can appear in any order:
Required arguments:
engine = <Ident>: generated engine wrapper typesnapshot = <Ident>: generated snapshot typeinitial = <expr>: initial state expression
Optional arguments:
reducer = <expr>: reducer construction expression (defaults toDefault::default())no_frb: disables emitting Flutter Rust Bridge glue for this reducer (useful for pure-Rust reducers)persist = "some.key"andpersist_min_interval_ms = 200: enables persistent engine wiring (requiresstate-persistencefeature)
Sliced updates are enabled automatically when your reducer returns [oxide_core::StateChange::Infer] or [oxide_core::StateChange::Slices].
When sliced updates are enabled, the macro expects the slice enum StateSlice type to be named <StateName>Slice (as generated by #[state(sliced = true)]) and available in scope.
Value kinds
engineandsnapshotmust be plain identifiers (not paths). The macro generates a new type with that name.initialis any Rust expression that evaluates toState.reduceris any Rust expression that evaluates to the reducer type (defaults toDefault::default()).persistmust be a string literal ("...").persist_min_interval_msmust be an integer literal (milliseconds).no_frbis a bare identifier flag.
The annotated impl must define:
type State = ...;type Action = ...;type SideEffect = ...;async fn init(&mut self, ctx: oxide_core::InitContext<Self::SideEffect>)fn reduce(&mut self, state: &mut Self::State, action: Self::Action) -> oxide_core::CoreResult<oxide_core::StateChange>fn effect(&mut self, state: &mut Self::State, effect: Self::SideEffect) -> oxide_core::CoreResult<oxide_core::StateChange>
Example:
use ;
Features
frb(default): enables FRB export generation for#[reducer(...)](can still be disabled per reducer viano_frb)state-persistence: enables serde derives injection for#[state]/#[actions]and enables persistence arguments for#[reducer(...)]full: enables all features
Metadata
The macros add doc strings containing oxide:meta:<json>. The JSON includes user doc comments and structural information needed for generators.
License
Dual-licensed under MIT OR Apache-2.0. See LICENSE.