1use crate::patch::{create_patch, Patch};
37use serde::{Deserialize, Serialize};
38use serde_json::Value as JsonValue;
39use std::fmt::Debug;
40
41pub trait AgentState:
70 'static + Debug + Clone + Send + Sync + for<'de> Deserialize<'de> + Serialize + Default
71{
72}
73
74pub trait FwdProps:
102 'static + Clone + Send + Sync + for<'de> Deserialize<'de> + Serialize + Default
103{
104}
105
106impl AgentState for JsonValue {}
109impl AgentState for () {}
110
111impl FwdProps for JsonValue {}
114impl FwdProps for () {}
115
116pub fn diff_states(old: &JsonValue, new: &JsonValue) -> Option<Patch> {
137 let patch = create_patch(old, new);
138 if patch.0.is_empty() {
139 None
140 } else {
141 Some(patch)
142 }
143}
144
145#[derive(Debug, Clone)]
171pub struct StateManager {
172 current: JsonValue,
173 version: u64,
174}
175
176impl StateManager {
177 pub fn new(initial: JsonValue) -> Self {
179 Self {
180 current: initial,
181 version: 0,
182 }
183 }
184
185 pub fn current(&self) -> &JsonValue {
187 &self.current
188 }
189
190 pub fn version(&self) -> u64 {
192 self.version
193 }
194
195 pub fn update(&mut self, new_state: JsonValue) -> Option<Patch> {
199 let patch = diff_states(&self.current, &new_state);
200 if patch.is_some() {
201 self.current = new_state;
202 self.version += 1;
203 }
204 patch
205 }
206
207 pub fn update_with<F>(&mut self, f: F) -> Option<Patch>
228 where
229 F: FnOnce(&mut JsonValue),
230 {
231 let old_state = self.current.clone();
232 f(&mut self.current);
233 let patch = diff_states(&old_state, &self.current);
234 if patch.is_some() {
235 self.version += 1;
236 }
237 patch
238 }
239
240 pub fn reset(&mut self, new_state: JsonValue) {
245 self.current = new_state;
246 self.version += 1;
247 }
248
249 pub fn snapshot(&self) -> JsonValue {
253 self.current.clone()
254 }
255}
256
257impl Default for StateManager {
258 fn default() -> Self {
259 Self::new(JsonValue::Object(serde_json::Map::new()))
260 }
261}
262
263#[derive(Debug, Clone)]
291pub struct TypedStateManager<S: AgentState> {
292 current: S,
293 version: u64,
294}
295
296impl<S: AgentState + PartialEq> TypedStateManager<S> {
297 pub fn new(initial: S) -> Self {
299 Self {
300 current: initial,
301 version: 0,
302 }
303 }
304
305 pub fn current(&self) -> &S {
307 &self.current
308 }
309
310 pub fn version(&self) -> u64 {
312 self.version
313 }
314
315 pub fn update(&mut self, new_state: S) -> Option<Patch> {
319 if self.current == new_state {
320 return None;
321 }
322
323 let old_json = serde_json::to_value(&self.current).ok()?;
324 let new_json = serde_json::to_value(&new_state).ok()?;
325 let patch = diff_states(&old_json, &new_json);
326
327 self.current = new_state;
328 self.version += 1;
329 patch
330 }
331
332 pub fn reset(&mut self, new_state: S) {
334 self.current = new_state;
335 self.version += 1;
336 }
337
338 pub fn snapshot(&self) -> JsonValue {
340 serde_json::to_value(&self.current).unwrap_or(JsonValue::Null)
341 }
342
343 pub fn as_json(&self) -> JsonValue {
345 serde_json::to_value(&self.current).unwrap_or(JsonValue::Null)
346 }
347}
348
349impl<S: AgentState + PartialEq> Default for TypedStateManager<S> {
350 fn default() -> Self {
351 Self::new(S::default())
352 }
353}
354
355#[cfg(test)]
356mod tests {
357 use super::*;
358
359 #[derive(Debug, Clone, Default, Serialize, Deserialize)]
360 struct TestState {
361 value: i32,
362 }
363
364 impl AgentState for TestState {}
365
366 #[derive(Clone, Default, Serialize, Deserialize)]
367 struct TestProps {
368 name: String,
369 }
370
371 impl FwdProps for TestProps {}
372
373 #[test]
374 fn test_json_value_implements_agent_state() {
375 fn requires_agent_state<T: AgentState>(_: T) {}
376 requires_agent_state(JsonValue::Null);
377 }
378
379 #[test]
380 fn test_unit_implements_agent_state() {
381 fn requires_agent_state<T: AgentState>(_: T) {}
382 requires_agent_state(());
383 }
384
385 #[test]
386 fn test_json_value_implements_fwd_props() {
387 fn requires_fwd_props<T: FwdProps>(_: T) {}
388 requires_fwd_props(JsonValue::Null);
389 }
390
391 #[test]
392 fn test_unit_implements_fwd_props() {
393 fn requires_fwd_props<T: FwdProps>(_: T) {}
394 requires_fwd_props(());
395 }
396
397 #[test]
398 fn test_custom_state_type() {
399 fn requires_agent_state<T: AgentState>(_: T) {}
400 requires_agent_state(TestState { value: 42 });
401 }
402
403 #[test]
404 fn test_custom_props_type() {
405 fn requires_fwd_props<T: FwdProps>(_: T) {}
406 requires_fwd_props(TestProps {
407 name: "test".to_string(),
408 });
409 }
410
411 #[test]
416 fn test_diff_states_with_changes() {
417 use serde_json::json;
418
419 let old = json!({"count": 0});
420 let new = json!({"count": 5});
421
422 let patch = diff_states(&old, &new);
423 assert!(patch.is_some());
424 }
425
426 #[test]
427 fn test_diff_states_no_changes() {
428 use serde_json::json;
429
430 let state = json!({"count": 0});
431
432 let patch = diff_states(&state, &state);
433 assert!(patch.is_none());
434 }
435
436 #[test]
437 fn test_state_manager_new() {
438 use serde_json::json;
439
440 let manager = StateManager::new(json!({"count": 0}));
441 assert_eq!(manager.current()["count"], 0);
442 assert_eq!(manager.version(), 0);
443 }
444
445 #[test]
446 fn test_state_manager_update_with_changes() {
447 use serde_json::json;
448
449 let mut manager = StateManager::new(json!({"count": 0}));
450
451 let delta = manager.update(json!({"count": 5}));
452 assert!(delta.is_some());
453 assert_eq!(manager.current()["count"], 5);
454 assert_eq!(manager.version(), 1);
455 }
456
457 #[test]
458 fn test_state_manager_update_no_changes() {
459 use serde_json::json;
460
461 let mut manager = StateManager::new(json!({"count": 0}));
462
463 let delta = manager.update(json!({"count": 0}));
464 assert!(delta.is_none());
465 assert_eq!(manager.version(), 0); }
467
468 #[test]
469 fn test_state_manager_update_with_closure() {
470 use serde_json::json;
471
472 let mut manager = StateManager::new(json!({"count": 0}));
473
474 let delta = manager.update_with(|state| {
475 state["count"] = json!(10);
476 });
477
478 assert!(delta.is_some());
479 assert_eq!(manager.current()["count"], 10);
480 assert_eq!(manager.version(), 1);
481 }
482
483 #[test]
484 fn test_state_manager_update_with_no_changes() {
485 use serde_json::json;
486
487 let mut manager = StateManager::new(json!({"count": 0}));
488
489 let delta = manager.update_with(|_state| {
490 });
492
493 assert!(delta.is_none());
494 assert_eq!(manager.version(), 0);
495 }
496
497 #[test]
498 fn test_state_manager_reset() {
499 use serde_json::json;
500
501 let mut manager = StateManager::new(json!({"count": 0}));
502 manager.reset(json!({"count": 100, "new_field": true}));
503
504 assert_eq!(manager.current()["count"], 100);
505 assert_eq!(manager.current()["new_field"], true);
506 assert_eq!(manager.version(), 1);
507 }
508
509 #[test]
510 fn test_state_manager_snapshot() {
511 use serde_json::json;
512
513 let manager = StateManager::new(json!({"count": 42}));
514 let snapshot = manager.snapshot();
515
516 assert_eq!(snapshot, json!({"count": 42}));
517 }
518
519 #[test]
520 fn test_state_manager_default() {
521 let manager = StateManager::default();
522 assert!(manager.current().is_object());
523 assert_eq!(manager.version(), 0);
524 }
525
526 #[test]
527 fn test_state_manager_multiple_updates() {
528 use serde_json::json;
529
530 let mut manager = StateManager::new(json!({"count": 0}));
531
532 manager.update(json!({"count": 1}));
533 manager.update(json!({"count": 2}));
534 manager.update(json!({"count": 3}));
535
536 assert_eq!(manager.current()["count"], 3);
537 assert_eq!(manager.version(), 3);
538 }
539
540 #[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
545 struct AppState {
546 count: u32,
547 name: String,
548 }
549
550 impl AgentState for AppState {}
551
552 #[test]
553 fn test_typed_state_manager_new() {
554 let manager = TypedStateManager::new(AppState {
555 count: 0,
556 name: "test".to_string(),
557 });
558
559 assert_eq!(manager.current().count, 0);
560 assert_eq!(manager.current().name, "test");
561 assert_eq!(manager.version(), 0);
562 }
563
564 #[test]
565 fn test_typed_state_manager_update() {
566 let mut manager = TypedStateManager::new(AppState {
567 count: 0,
568 name: "test".to_string(),
569 });
570
571 let delta = manager.update(AppState {
572 count: 5,
573 name: "test".to_string(),
574 });
575
576 assert!(delta.is_some());
577 assert_eq!(manager.current().count, 5);
578 assert_eq!(manager.version(), 1);
579 }
580
581 #[test]
582 fn test_typed_state_manager_update_no_changes() {
583 let mut manager = TypedStateManager::new(AppState {
584 count: 0,
585 name: "test".to_string(),
586 });
587
588 let delta = manager.update(AppState {
589 count: 0,
590 name: "test".to_string(),
591 });
592
593 assert!(delta.is_none());
594 assert_eq!(manager.version(), 0);
595 }
596
597 #[test]
598 fn test_typed_state_manager_reset() {
599 let mut manager = TypedStateManager::new(AppState {
600 count: 0,
601 name: "old".to_string(),
602 });
603
604 manager.reset(AppState {
605 count: 100,
606 name: "new".to_string(),
607 });
608
609 assert_eq!(manager.current().count, 100);
610 assert_eq!(manager.current().name, "new");
611 assert_eq!(manager.version(), 1);
612 }
613
614 #[test]
615 fn test_typed_state_manager_snapshot() {
616 let manager = TypedStateManager::new(AppState {
617 count: 42,
618 name: "test".to_string(),
619 });
620
621 let snapshot = manager.snapshot();
622 assert_eq!(snapshot["count"], 42);
623 assert_eq!(snapshot["name"], "test");
624 }
625
626 #[test]
627 fn test_typed_state_manager_as_json() {
628 let manager = TypedStateManager::new(AppState {
629 count: 10,
630 name: "hello".to_string(),
631 });
632
633 let json = manager.as_json();
634 assert_eq!(json["count"], 10);
635 assert_eq!(json["name"], "hello");
636 }
637
638 #[test]
639 fn test_typed_state_manager_default() {
640 let manager: TypedStateManager<AppState> = TypedStateManager::default();
641 assert_eq!(manager.current().count, 0);
642 assert_eq!(manager.current().name, "");
643 assert_eq!(manager.version(), 0);
644 }
645}