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
use crate::parser::types::Name;
use crate::{
    InputValueError, InputValueResult, InputValueType, OutputValueType, Scalar, ScalarType, Value,
};
use std::collections::BTreeMap;

/// A scalar that can represent any JSON Object value.
#[Scalar(internal, name = "JSONObject")]
impl<T> ScalarType for BTreeMap<String, T>
where
    T: OutputValueType + InputValueType + Send + Sync,
{
    fn parse(value: Value) -> InputValueResult<Self> {
        match value {
            Value::Object(map) => {
                let mut result = BTreeMap::new();
                for (name, value) in map {
                    result.insert(name.to_string(), T::parse(Some(value))?);
                }
                Ok(result)
            }
            _ => Err(InputValueError::ExpectedType(value)),
        }
    }

    fn to_value(&self) -> Value {
        let mut map = BTreeMap::new();
        for (name, value) in self {
            if let Ok(name) = Name::new(name.clone()) {
                map.insert(name, value.to_value());
            }
        }
        Value::Object(map)
    }
}