mockforge_world_state/
model.rs

1//! World State Model - Core data structures for representing unified state
2//!
3//! This module defines the core data structures that represent the unified
4//! world state of MockForge, including nodes, edges, layers, and snapshots.
5
6use chrono::{DateTime, Utc};
7use serde::{Deserialize, Serialize};
8use serde_json::Value;
9use std::collections::HashMap;
10
11/// Complete world state snapshot at a point in time
12///
13/// This represents the entire state of the MockForge world at a specific
14/// moment, including all personas, entities, relationships, and system state.
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct WorldStateSnapshot {
17    /// Unique identifier for this snapshot
18    pub id: String,
19    /// Timestamp when this snapshot was created
20    pub timestamp: DateTime<Utc>,
21    /// All state nodes in this snapshot
22    pub nodes: Vec<StateNode>,
23    /// All state edges (relationships) in this snapshot
24    pub edges: Vec<StateEdge>,
25    /// State layers and their visibility
26    pub layers: HashMap<StateLayer, bool>,
27    /// Additional metadata about this snapshot
28    #[serde(default)]
29    pub metadata: HashMap<String, Value>,
30}
31
32impl WorldStateSnapshot {
33    /// Create a new empty snapshot
34    pub fn new() -> Self {
35        Self {
36            id: uuid::Uuid::new_v4().to_string(),
37            timestamp: Utc::now(),
38            nodes: Vec::new(),
39            edges: Vec::new(),
40            layers: HashMap::new(),
41            metadata: HashMap::new(),
42        }
43    }
44
45    /// Get all nodes in a specific layer
46    pub fn nodes_in_layer(&self, layer: &StateLayer) -> Vec<&StateNode> {
47        self.nodes.iter().filter(|node| node.layer == *layer).collect()
48    }
49
50    /// Get all edges connected to a node
51    pub fn edges_for_node(&self, node_id: &str) -> Vec<&StateEdge> {
52        self.edges
53            .iter()
54            .filter(|edge| edge.from == node_id || edge.to == node_id)
55            .collect()
56    }
57
58    /// Get a node by ID
59    pub fn get_node(&self, node_id: &str) -> Option<&StateNode> {
60        self.nodes.iter().find(|node| node.id == node_id)
61    }
62}
63
64impl Default for WorldStateSnapshot {
65    fn default() -> Self {
66        Self::new()
67    }
68}
69
70/// A node in the world state graph
71///
72/// Represents any stateful entity in MockForge, such as a persona, entity,
73/// session, or system component.
74#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
75pub struct StateNode {
76    /// Unique identifier for this node
77    pub id: String,
78    /// Human-readable label
79    pub label: String,
80    /// Type of node (persona, entity, session, etc.)
81    pub node_type: NodeType,
82    /// Layer this node belongs to
83    pub layer: StateLayer,
84    /// Current state value (if applicable)
85    pub state: Option<String>,
86    /// Additional properties/metadata
87    #[serde(default)]
88    pub properties: HashMap<String, Value>,
89    /// Timestamp when this node was created
90    pub created_at: DateTime<Utc>,
91    /// Timestamp when this node was last updated
92    pub updated_at: DateTime<Utc>,
93}
94
95impl StateNode {
96    /// Create a new state node
97    pub fn new(id: String, label: String, node_type: NodeType, layer: StateLayer) -> Self {
98        let now = Utc::now();
99        Self {
100            id,
101            label,
102            node_type,
103            layer,
104            state: None,
105            properties: HashMap::new(),
106            created_at: now,
107            updated_at: now,
108        }
109    }
110
111    /// Set a property on this node
112    pub fn set_property(&mut self, key: String, value: Value) {
113        self.properties.insert(key, value);
114        self.updated_at = Utc::now();
115    }
116
117    /// Get a property from this node
118    pub fn get_property(&self, key: &str) -> Option<&Value> {
119        self.properties.get(key)
120    }
121
122    /// Set the current state of this node
123    pub fn set_state(&mut self, state: String) {
124        self.state = Some(state);
125        self.updated_at = Utc::now();
126    }
127}
128
129/// Type of node in the world state
130#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
131#[serde(rename_all = "snake_case")]
132pub enum NodeType {
133    /// A persona profile
134    Persona,
135    /// An entity (user, order, payment, etc.)
136    Entity,
137    /// A session or connection
138    Session,
139    /// A protocol handler
140    Protocol,
141    /// A behavior rule or tree
142    Behavior,
143    /// A schema definition
144    Schema,
145    /// Recorded data or fixture
146    Recorded,
147    /// AI modifier or configuration
148    AiModifier,
149    /// System component
150    System,
151}
152
153/// An edge (relationship) between two nodes
154///
155/// Represents relationships between state entities, such as persona
156/// relationships, entity ownership, or protocol connections.
157#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
158pub struct StateEdge {
159    /// Source node ID
160    pub from: String,
161    /// Target node ID
162    pub to: String,
163    /// Type of relationship
164    pub relationship_type: String,
165    /// Additional edge properties
166    #[serde(default)]
167    pub properties: HashMap<String, Value>,
168    /// Timestamp when this edge was created
169    pub created_at: DateTime<Utc>,
170}
171
172impl StateEdge {
173    /// Create a new state edge
174    pub fn new(from: String, to: String, relationship_type: String) -> Self {
175        Self {
176            from,
177            to,
178            relationship_type,
179            properties: HashMap::new(),
180            created_at: Utc::now(),
181        }
182    }
183
184    /// Set a property on this edge
185    pub fn set_property(&mut self, key: String, value: Value) {
186        self.properties.insert(key, value);
187    }
188}
189
190/// State layer grouping related state
191///
192/// Layers organize state into logical groups for visualization and filtering.
193#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord)]
194#[serde(rename_all = "snake_case")]
195pub enum StateLayer {
196    /// Personas and persona relationships
197    Personas,
198    /// Lifecycle states and transitions
199    Lifecycle,
200    /// Reality levels and continuum
201    Reality,
202    /// Time and temporal state
203    Time,
204    /// Multi-protocol state
205    Protocols,
206    /// Behavior trees and rules
207    Behavior,
208    /// Generative schemas
209    Schemas,
210    /// Recorded data and fixtures
211    Recorded,
212    /// AI modifiers and configurations
213    AiModifiers,
214    /// System-level state
215    System,
216}
217
218impl StateLayer {
219    /// Get all available layers
220    pub fn all() -> Vec<Self> {
221        vec![
222            Self::Personas,
223            Self::Lifecycle,
224            Self::Reality,
225            Self::Time,
226            Self::Protocols,
227            Self::Behavior,
228            Self::Schemas,
229            Self::Recorded,
230            Self::AiModifiers,
231            Self::System,
232        ]
233    }
234
235    /// Get human-readable name for this layer
236    pub fn name(&self) -> &'static str {
237        match self {
238            Self::Personas => "Personas",
239            Self::Lifecycle => "Lifecycle",
240            Self::Reality => "Reality",
241            Self::Time => "Time",
242            Self::Protocols => "Protocols",
243            Self::Behavior => "Behavior",
244            Self::Schemas => "Schemas",
245            Self::Recorded => "Recorded",
246            Self::AiModifiers => "AI Modifiers",
247            Self::System => "System",
248        }
249    }
250}