1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use ::json::{object::Object, JsonValue};
use super::*;
#[lovm2_function]
fn decode(json: String) -> Lovm2Result<Value> {
::json::parse(&json)
.or_else(err_from_string)
.and_then(|val| from_json_value(&val))
}
#[lovm2_function]
fn encode(val: Value) -> Lovm2Result<String> {
let val = to_json_value(val)?;
Ok(::json::stringify(val))
}
fn from_json_value(val: &JsonValue) -> Lovm2Result<Value> {
use std::convert::TryInto;
let val = match val {
JsonValue::Null => Value::Nil,
JsonValue::Short(s) => Value::from(s.as_str().to_string()),
JsonValue::String(s) => Value::from(s.to_string()),
JsonValue::Number(n) => {
let iparse: Result<i64, ::json::number::NumberOutOfScope> = (*n).try_into();
if let Ok(n) = iparse {
Value::from(n)
} else {
let n: f64 = (*n).into();
Value::from(n)
}
}
JsonValue::Boolean(b) => Value::from(*b),
JsonValue::Object(obj) => {
let mut dict = box_value(Value::dict());
for (key, val) in obj.iter() {
let key = Value::from(key);
let val = from_json_value(val)?;
dict.set(&key, val)?;
}
dict
}
JsonValue::Array(ls) => {
let mut list = vec![];
for val in ls.iter() {
let val = from_json_value(val)?;
list.push(val);
}
box_value(Value::List(list))
}
};
Ok(val)
}
fn to_json_value(val: Value) -> Lovm2Result<JsonValue> {
let json = match val {
Value::Nil => JsonValue::Null,
Value::Bool(b) => JsonValue::Boolean(b),
Value::Int(n) => JsonValue::Number(n.into()),
Value::Float(n) => JsonValue::Number(n.into()),
Value::Str(s) => JsonValue::String(s),
Value::Dict(d) => {
let mut obj = Object::new();
for (key, val) in d.into_iter() {
let key = key.as_str_inner()?;
let val = to_json_value(val)?;
obj.insert(&key, val);
}
obj.into()
}
Value::List(ls) => {
let mut json_ls = vec![];
for val in ls.into_iter() {
json_ls.push(to_json_value(val)?);
}
json_ls.into()
}
Value::Ref(r) => to_json_value(r.unref_to_value()?.borrow().clone())?,
_ => return err_from_string(format!("{:?} not supported for json", val)),
};
Ok(json)
}