concinnity_world/spec/
json.rs1use super::{ArgValue, AssetSpec};
9use serde_json::{Map, Number, Value};
10
11pub fn arg_value_to_json(v: &ArgValue) -> Value {
13 match v {
14 ArgValue::Null => Value::Null,
15 ArgValue::Bool(b) => Value::Bool(*b),
16 ArgValue::Int(i) => Value::Number(Number::from(*i)),
17 ArgValue::Float(f) => Number::from_f64(*f)
18 .map(Value::Number)
19 .unwrap_or(Value::Null),
20 ArgValue::Str(s) => Value::String(s.clone()),
21 ArgValue::Array(items) => Value::Array(items.iter().map(arg_value_to_json).collect()),
22 ArgValue::Object(fields) => Value::Object(object_map(fields)),
23 }
24}
25
26pub fn spec_args(spec: &AssetSpec) -> Value {
29 Value::Object(object_map(&spec.fields))
30}
31
32pub fn spec_to_value(spec: &AssetSpec) -> Value {
35 let mut obj = Map::new();
36 obj.insert("name".to_string(), Value::String(spec.name.clone()));
37 obj.insert(
38 "type".to_string(),
39 Value::String(spec.asset_type.to_string()),
40 );
41 obj.insert("args".to_string(), spec_args(spec));
42 Value::Object(obj)
43}
44
45fn object_map(fields: &[(String, ArgValue)]) -> Map<String, Value> {
46 let mut obj = Map::new();
47 for (k, v) in fields {
48 obj.insert(k.clone(), arg_value_to_json(v));
49 }
50 obj
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[test]
58 fn arg_value_maps_each_shape() {
59 assert_eq!(arg_value_to_json(&ArgValue::Bool(true)), Value::Bool(true));
60 assert_eq!(arg_value_to_json(&ArgValue::Int(48)), serde_json::json!(48));
61 assert_eq!(
62 arg_value_to_json(&ArgValue::floats(&[1.0, 0.0, 0.0])),
63 serde_json::json!([1.0, 0.0, 0.0])
64 );
65 }
66
67 #[test]
68 fn spec_args_wraps_fields_in_order() {
69 let spec = AssetSpec::new("s", "Sprite")
70 .set("x", 10.0f32)
71 .set("y", 20.0f32);
72 let v = spec_args(&spec);
73 assert_eq!(v["x"], 10.0);
74 assert_eq!(v["y"], 20.0);
75 }
76
77 #[test]
78 fn spec_to_value_wraps_name_type_args() {
79 let spec = AssetSpec::new("lamp", "PointLight").set("intensity", 8.0f32);
80 let v = spec_to_value(&spec);
81 assert_eq!(v["name"], "lamp");
82 assert_eq!(v["type"], "PointLight");
83 assert_eq!(v["args"]["intensity"], 8.0);
84 }
85}