shape_runtime/simulation/
validation.rs1use crate::type_schema::{SchemaId, TypeSchemaRegistry};
7use shape_ast::error::{Result, ShapeError};
8use shape_value::ValueWord;
9
10pub fn validate_typed_state(
19 value: &ValueWord,
20 _registry: &TypeSchemaRegistry,
21) -> Result<Option<SchemaId>> {
22 if value.as_typed_object().is_some() {
23 Ok(None) } else if value.is_none() {
28 Ok(None)
30 } else {
31 Err(ShapeError::RuntimeError {
32 message: format!(
33 "Simulation state must be an Object (from type declaration) for optimal performance. \
34 Got: {}. Use 'type MyState {{ ... }}' to declare a typed state.",
35 value.type_name()
36 ),
37 location: None,
38 })
39 }
40}
41
42pub fn require_typed_state_with_schema(
56 value: &ValueWord,
57 type_name: &str,
58 registry: &TypeSchemaRegistry,
59) -> Result<SchemaId> {
60 if value.as_typed_object().is_none() {
62 return Err(ShapeError::RuntimeError {
63 message: format!(
64 "Simulation state must be a '{}' object. Got: {}",
65 type_name,
66 value.type_name()
67 ),
68 location: None,
69 });
70 }
71
72 match registry.get(type_name) {
74 Some(schema) => Ok(schema.id),
75 None => Err(ShapeError::RuntimeError {
76 message: format!(
77 "Type '{}' not found in schema registry. \
78 Declare it with 'type {} {{ ... }}' before using in simulation.",
79 type_name, type_name
80 ),
81 location: None,
82 }),
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89 #[test]
90 fn test_validate_typed_state() {
91 let registry = TypeSchemaRegistry::new();
92
93 let obj = crate::type_schema::typed_object_from_pairs(&[]);
95 assert!(validate_typed_state(&obj, ®istry).is_ok());
96
97 assert!(validate_typed_state(&ValueWord::none(), ®istry).is_ok());
99
100 let num = ValueWord::from_f64(42.0);
102 assert!(validate_typed_state(&num, ®istry).is_err());
103 }
104
105 #[test]
106 fn test_require_typed_state_with_schema() {
107 use crate::type_schema::TypeSchemaBuilder;
108
109 let mut registry = TypeSchemaRegistry::new();
110
111 let schema = TypeSchemaBuilder::new("TestState")
113 .f64_field("value")
114 .build();
115 registry.register(schema);
116
117 let obj = crate::type_schema::typed_object_from_pairs(&[]);
119 assert!(require_typed_state_with_schema(&obj, "TestState", ®istry).is_ok());
120
121 assert!(require_typed_state_with_schema(&obj, "UnknownType", ®istry).is_err());
123
124 let num = ValueWord::from_f64(42.0);
126 assert!(require_typed_state_with_schema(&num, "TestState", ®istry).is_err());
127 }
128}