# JSON_STATE
A lightweight, flexible Rust module for managing application state persistence across memory and filesystem.
## Description
The JSON_STATE provides a simple and efficient way to store, retrieve, and manage application states. It enables seamless persistence of JSON-based state data both in memory and on the filesystem, making it ideal for applications that need to maintain state between sessions or require robust state handling.
## Features
- **Dual Persistence**: States are stored both in memory for fast access and on disk for persistence
- **JSON-based Payload**: Store any data that can be serialized to JSON
- **Unique State IDs**: Each state has a unique identifier for reliable retrieval
- **Memory & Filesystem Operations**: Save, load, and delete states from both memory and filesystem
- **Error Handling**: Robust error handling for filesystem operations
- **Directory-based Storage**: States are organized in a configurable directory
- **Safe File Loading**: Validates files based on UUID format and content integrity
- **Directory Management**: Utilities for clearing state directories and ensuring clean environments
## Installation
Add the following to your `Cargo.toml`:
```toml
[dependencies]
state = "0.1.0"
serde_json = "1.0"
uuid = "1.0"
serde = { version = "1.0", features = ["derive"] }
```
## Usage
Here's a simple example demonstrating how to use the State Management module:
```rust
use serde_json::{Value, json};
use state::{State, StateManager};
fn main() -> std::io::Result<()> {
// Create a StateManager with the directory path
let mut manager = StateManager::new("states".to_string());
// Create a new state with some payload
let payload = json!({ "name": "John", "age": 30 });
let state = State::new(payload);
let state_id = state.get_id().clone();
// Save the state to memory and file system
manager.save(state.clone())?;
println!("Saved state with ID: {}", state_id);
// Load the manager from the directory to verify saved state
let loaded_manager = StateManager::load_from_dir("states")?;
println!("Loaded states: {:?}", loaded_manager.states.keys());
// Load the specific state using the public load method
match manager.load(&state_id) {
Ok(Some(loaded_state)) => {
println!("Loaded state: {:?}", loaded_state);
}
Ok(None) => {
println!("State with ID {} not found.", state_id);
}
Err(e) => {
println!("Error loading state: {}", e);
}
}
// Delete the state from memory and file system
manager.delete(&state_id)?;
println!("Deleted state with ID: {}", state_id);
// Try loading the deleted state to verify deletion
match manager.load(&state_id) {
Ok(Some(loaded_state)) => {
println!("State still exists: {:?}", loaded_state);
}
Ok(None) => {
println!("State with ID {} has been deleted.", state_id);
}
Err(e) => {
println!("Error loading state: {}", e);
}
}
// Clear all states from a directory
StateManager::clear_dir("states")?;
println!("Cleared all states from directory");
Ok(())
}
```
## API Reference
### State
A structure representing a single state item with a unique ID and JSON payload.
```rust
// Create a new state with a JSON payload
let state = State::new(json!({ "key": "value" }));
// Get the state's unique ID
let id = state.get_id();
// Get the state's payload
let payload = state.get_payload();
```
### StateManager
Manages multiple states, providing operations for saving, loading, and deleting states.
```rust
// Create a new StateManager with a storage directory
let mut manager = StateManager::new("states".to_string());
// Load an existing StateManager from a directory
let manager = StateManager::load_from_dir("states")?;
// Save a state (to memory and filesystem)
manager.save(state)?;
// Load a state by ID
let loaded_state = manager.load(&state_id)?;
// Delete a state by ID
manager.delete(&state_id)?;
// Clear all states from a directory
StateManager::clear_dir("states")?;
```
## Error Handling
The module uses Rust's standard `std::io::Result` for error handling, making it straightforward to integrate with existing error handling approaches.
## Best Practices
- Use meaningful JSON payloads that reflect your application's state
- Handle filesystem errors appropriately
- Create a new StateManager instance for each logical group of states
- Use separate directories for different components to prevent state collisions
- Clear state directories when needed to ensure a clean environment
- Consider implementing serialization for your custom types to store them in states
## Testing
The library includes comprehensive tests that demonstrate proper usage and validate functionality:
```rust
// Run the tests
cargo test
```
Test isolation is achieved by using unique directories for each test case, preventing cross-test interference.
## License
This project is licensed under the MIT License - see the LICENSE file for details.