use eventfold::{Event, EventLog, View};
use serde::{Deserialize, Serialize};
use serde_json::json;
#[derive(Default, Clone, Debug, Serialize, Deserialize)]
struct TodoV1 {
items: Vec<ItemV1>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
struct ItemV1 {
text: String,
}
fn reducer_v1(mut state: TodoV1, event: &Event) -> TodoV1 {
if event.event_type == "todo_added" {
state.items.push(ItemV1 {
text: event.data["text"].as_str().unwrap_or("").to_string(),
});
}
state
}
#[derive(Default, Clone, Debug, Serialize, Deserialize)]
struct TodoV2 {
items: Vec<ItemV2>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
struct ItemV2 {
text: String,
priority: String,
}
fn reducer_v2(mut state: TodoV2, event: &Event) -> TodoV2 {
if event.event_type == "todo_added" {
state.items.push(ItemV2 {
text: event.data["text"].as_str().unwrap_or("").to_string(),
priority: event.data["priority"]
.as_str()
.unwrap_or("normal")
.to_string(),
});
}
state
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let dir = tempfile::tempdir()?;
{
let mut log = EventLog::open(dir.path())?;
log.append(
&Event::new("todo_added", json!({"text": "buy milk"}))
.with_meta(json!({"source": "cli"})),
)?;
log.append(
&Event::new("todo_added", json!({"text": "fix bug"}))
.with_meta(json!({"source": "cli", "priority": "high"})),
)?;
let mut view = View::new("todos", reducer_v1, &dir.path().join("views"));
view.refresh(&log.reader())?;
println!("Before rebuild (v1): {:?}", view.state());
}
{
let log = EventLog::open(dir.path())?;
let mut view = View::new("todos", reducer_v2, &dir.path().join("views"));
view.rebuild(&log.reader())?;
println!("After rebuild (v2): {:?}", view.state());
}
Ok(())
}