reactive_graph_dynamic_graph_impl/field/
property_instance.rs

1use async_graphql::Error;
2use async_graphql::dynamic::ResolverContext;
3use reactive_graph_dynamic_graph_api::PropertyDataTypeError;
4use serde_json::Value;
5use serde_json::json;
6
7use reactive_graph_graph::DataType;
8use reactive_graph_graph::PropertyInstances;
9use reactive_graph_graph::PropertyTypes;
10
11/// Returns a list of property instances from the field arguments.
12///
13/// Returns an error if a property doesn't exist in the entity type or relation type.
14///
15/// First, initializes the properties with the default values of the property types of
16/// an entity type or relation type. Next, overwrites the properties with the value
17/// provided by the field arguments.
18pub fn create_properties_from_field_arguments(ctx: &ResolverContext, property_types: &PropertyTypes) -> Result<PropertyInstances, Error> {
19    let properties = PropertyInstances::new_from_property_types_with_defaults(property_types);
20    for property in property_types.iter() {
21        let field_arg_value = ctx.args.try_get(property.key())?;
22        match &property.data_type {
23            DataType::Null => {
24                return Err(PropertyDataTypeError::NullIsNotAValidDataType(property.key().clone()).into());
25            }
26            DataType::Bool => {
27                properties.insert(property.key().clone(), Value::Bool(field_arg_value.boolean()?));
28            }
29            DataType::Number => {
30                if let Ok(value) = field_arg_value.i64() {
31                    properties.insert(property.key().clone(), json!(value));
32                } else if let Ok(value) = field_arg_value.u64() {
33                    properties.insert(property.key().clone(), json!(value));
34                } else if let Ok(value) = field_arg_value.f64() {
35                    properties.insert(property.key().clone(), json!(value));
36                } else {
37                    return Err(PropertyDataTypeError::ValueIsNotOfTheExpectedDataType(property.name.clone(), property.data_type, DataType::Number).into());
38                }
39            }
40            DataType::String => {
41                properties.insert(property.key().clone(), Value::String(field_arg_value.string()?.to_string()));
42            }
43            DataType::Array => {
44                let _ = field_arg_value.list()?;
45                let value = field_arg_value.deserialize::<Value>()?;
46                if !value.is_array() {
47                    return Err(PropertyDataTypeError::ValueIsNotOfTheExpectedDataType(property.name.clone(), property.data_type, DataType::Array).into());
48                }
49                properties.insert(property.key().clone(), value);
50            }
51            DataType::Object => {
52                let value = field_arg_value.deserialize::<Value>()?;
53                if !value.is_object() {
54                    return Err(PropertyDataTypeError::ValueIsNotOfTheExpectedDataType(property.name.clone(), property.data_type, DataType::Object).into());
55                }
56                properties.insert(property.key().clone(), value);
57            }
58            DataType::Any => {
59                if let Ok(value) = field_arg_value.deserialize() {
60                    properties.insert(property.key().clone(), value);
61                }
62            }
63        }
64    }
65    Ok(properties)
66}