intuicio_frontend_simpleton/library/
json.rs

1use crate::{Array, Boolean, Integer, Map, Real, Reference, Text};
2use intuicio_core::registry::Registry;
3use intuicio_derive::intuicio_function;
4use serde_json::{Number, Value};
5
6fn to_value(value: &Reference) -> Value {
7    if let Some(value) = value.read::<Boolean>() {
8        Value::Bool(*value)
9    } else if let Some(value) = value.read::<Integer>() {
10        Value::Number((*value).into())
11    } else if let Some(value) = value.read::<Real>() {
12        Value::Number(Number::from_f64(*value).unwrap())
13    } else if let Some(value) = value.read::<Text>() {
14        Value::String(value.to_owned())
15    } else if let Some(value) = value.read::<Array>() {
16        Value::Array(value.iter().map(to_value).collect())
17    } else if let Some(value) = value.read::<Map>() {
18        Value::Object(
19            value
20                .iter()
21                .map(|(key, value)| (key.to_owned(), to_value(value)))
22                .collect(),
23        )
24    } else {
25        Value::Null
26    }
27}
28
29fn from_value(value: Value, registry: &Registry) -> Reference {
30    match value {
31        Value::Null => Reference::null(),
32        Value::Bool(value) => Reference::new_boolean(value, registry),
33        Value::Number(value) => {
34            if let Some(value) = value.as_f64() {
35                Reference::new_real(value, registry)
36            } else if let Some(value) = value.as_u64() {
37                Reference::new_integer(value as Integer, registry)
38            } else if let Some(value) = value.as_i64() {
39                Reference::new_integer(value, registry)
40            } else {
41                Reference::null()
42            }
43        }
44        Value::String(value) => Reference::new_text(value, registry),
45        Value::Array(value) => Reference::new_array(
46            value
47                .into_iter()
48                .map(|value| from_value(value, registry))
49                .collect(),
50            registry,
51        ),
52        Value::Object(value) => Reference::new_map(
53            value
54                .into_iter()
55                .map(|(key, value)| (key, from_value(value, registry)))
56                .collect(),
57            registry,
58        ),
59    }
60}
61
62#[intuicio_function(module_name = "json", use_registry)]
63pub fn serialize(registry: &Registry, value: Reference) -> Reference {
64    Reference::new_text(serde_json::to_string(&to_value(&value)).unwrap(), registry)
65}
66
67#[intuicio_function(module_name = "json", use_registry)]
68pub fn serialize_pretty(registry: &Registry, value: Reference) -> Reference {
69    Reference::new_text(
70        serde_json::to_string_pretty(&to_value(&value)).unwrap(),
71        registry,
72    )
73}
74
75#[intuicio_function(module_name = "json", use_registry)]
76pub fn deserialize(registry: &Registry, text: Reference) -> Reference {
77    from_value(
78        serde_json::from_str::<Value>(text.read::<Text>().unwrap().as_str()).unwrap(),
79        registry,
80    )
81}
82
83pub fn install(registry: &mut Registry) {
84    registry.add_function(serialize::define_function(registry));
85    registry.add_function(serialize_pretty::define_function(registry));
86    registry.add_function(deserialize::define_function(registry));
87}