shape_runtime/stdlib/
toml_module.rs1use crate::module_exports::{ModuleExports, ModuleParam};
25use crate::typed_module_exports::{
26 ConcreteReturn, ConcreteType, TypedReturn, register_typed_function,
27};
28use shape_value::KindedSlot;
29use std::sync::Arc;
30
31fn slot_as_string(slot: &KindedSlot) -> Option<Arc<String>> {
35 let bits = slot.slot().raw();
36 if bits == 0 {
37 return None;
38 }
39 unsafe {
44 let arc = Arc::<String>::from_raw(bits as *const String);
45 let cloned = arc.clone();
46 std::mem::forget(arc);
47 Some(cloned)
48 }
49}
50
51pub fn create_toml_module() -> ModuleExports {
53 let mut module = ModuleExports::new("std::core::toml");
54 module.description = "TOML parsing and serialization".to_string();
55
56 register_typed_function(
58 &mut module,
59 "parse",
60 "Parse a TOML string into Shape values",
61 vec![ModuleParam {
62 name: "text".to_string(),
63 type_name: "string".to_string(),
64 required: true,
65 description: "TOML string to parse".to_string(),
66 ..Default::default()
67 }],
68 ConcreteType::Result(Box::new(ConcreteType::HashMap)),
69 |_args, _ctx| {
70 Ok(TypedReturn::Err(ConcreteReturn::String(
71 "toml.parse() pending N6 (any-output marshal) — see ADR-006 §2.7.4".to_string(),
72 )))
73 },
74 );
75
76 register_typed_function(
78 &mut module,
79 "stringify",
80 "Serialize Shape values to a TOML string",
81 vec![ModuleParam {
82 name: "value".to_string(),
83 type_name: "any".to_string(),
84 required: true,
85 description: "Value to serialize (must be a HashMap or TypedObject)".to_string(),
86 ..Default::default()
87 }],
88 ConcreteType::Result(Box::new(ConcreteType::String)),
89 |_args, _ctx| {
90 Ok(TypedReturn::Err(ConcreteReturn::String(
91 "toml.stringify() pending N4 (any-input marshal) — see ADR-006 §2.7.4"
92 .to_string(),
93 )))
94 },
95 );
96
97 register_typed_function(
99 &mut module,
100 "is_valid",
101 "Check if a string is valid TOML",
102 vec![ModuleParam {
103 name: "text".to_string(),
104 type_name: "string".to_string(),
105 required: true,
106 description: "String to validate as TOML".to_string(),
107 ..Default::default()
108 }],
109 ConcreteType::Bool,
110 |args, _ctx| {
111 let slot = args
112 .first()
113 .ok_or_else(|| "toml.is_valid() requires a string argument".to_string())?;
114 let text = slot_as_string(slot)
115 .ok_or_else(|| "toml.is_valid() requires a string argument".to_string())?;
116 let valid = toml::from_str::<toml::Value>(text.as_str()).is_ok();
117 Ok(TypedReturn::Concrete(ConcreteReturn::Bool(valid)))
118 },
119 );
120
121 module
122}
123
124#[cfg(test)]
125mod tests {
126 use super::*;
127
128 #[test]
129 fn test_toml_module_creation() {
130 let module = create_toml_module();
131 assert_eq!(module.name, "std::core::toml");
132 assert!(module.has_export("parse"));
133 assert!(module.has_export("stringify"));
134 assert!(module.has_export("is_valid"));
135 }
136
137 #[test]
138 fn test_toml_typed_registry_populated() {
139 let module = create_toml_module();
140 let typed = module.typed_exports();
141 assert!(typed.get("parse").is_some());
142 assert!(typed.get("stringify").is_some());
143 assert!(typed.get("is_valid").is_some());
144 }
145
146 }