# Yewstand
**Zustand-inspired state management for Yew** - Simple, declarative global stores using Rust macros.
## Features
- **Global Store**: Single source of truth with automatic React-like re-renders
- **Shallow Selectors**: Subscribe only to specific fields for optimal performance
- **Mutation Macros**: Generate store-updating methods from simple functions
- **Zero-boilerplate hooks**: `use_app_store()` and `use_app_store_shallow()`
- **Async Support**: Mutations can be `async` functions
## Quick Start
```bash
cargo add yew --features="csr"
cargo add yewstand
```
```rust
use yewstand::{yewstand_store, yewstand_mutations};
// 1. Define your store
#[derive(Default, Clone, PartialEq)]
#[yewstand_store]
pub struct AppStore {
pub count: i32,
pub name: String,
}
// 2. Define mutations
#[yewstand_mutations]
impl AppStore {
pub fn set_count(state: AppStore, value: i32) -> AppStore {
AppStore { count: value, ..state }
}
pub async fn load_count(state: AppStore, id: String) -> AppStore {
let count = get_count_from_backend().await;
AppStore { count, ..state }
}
}
```
```rust
// 3. Use in components
#[function_component(App)]
fn app() -> Html {
let store = use_app_store(); // Full store subscription
let count = *use_app_store_shallow(|s| s.count); // Shallow selector
let onclick = {
Callback::from(|_| {
AppStore::set_count(42); // Updates global store automatically
})
};
html! {
<>
<p>{ format!("Count: {}", count) }</p>
<p>{ format!("Name: {}", store.name) }</p>
<button onclick={onclick}>{ "Set to 42" }</button>
</>
}
}
```
## API Reference
### Store Macro: `#[yewstand_store]`
Automatically generates:
- `use_app_store()` - Full store hook
- `use_app_store_shallow(|store| value)` - Shallow selector hook
- `update_store(|store| {...})` - Functional updater
- Global store infrastructure
**Requirements**: Store must implement `Default`, `Clone`, `PartialEq`
### Mutations Macro: `#[yewstand_mutations]`
Transform functions like this:
```rust
pub fn set_count(state: AppStore, value: i32) -> AppStore {
AppStore { count: value, ..state }
}
```
Into callable methods:
```rust
AppStore::set_count(42); // Updates global store automatically
```
**Pattern**: `(state: AppStore, args...) -> AppStore`
## Examples
See the [counter example](examples/counter/src/main.rs) for a complete working demo with:
- Full store subscription (`FullStore` component)
- Shallow selector (`CountOnly` component)
- Functional updates (`update_store`)
- Generated mutations (`AppStore::set_count`)
## License
[Unlicense](LICENSE)