reactive_graph_dynamic_graph_impl/field/entity/
mutation.rs1use crate::field::property::field_arguments::add_entity_type_properties_as_field_arguments;
2use crate::field::property::filter::get_entity_instances_by_type_filter_by_properties;
3use crate::object::types::DynamicGraphTypeDefinition;
4use async_graphql::dynamic::Field;
5use async_graphql::dynamic::FieldFuture;
6use async_graphql::dynamic::FieldValue;
7use async_graphql::dynamic::InputValue;
8use async_graphql::dynamic::TypeRef;
9use reactive_graph_dynamic_graph_api::EntityInstanceIsNotOfType;
10use reactive_graph_dynamic_graph_api::EntityInstanceNotFound;
11use reactive_graph_graph::EntityType;
12use reactive_graph_reactive_service_api::ReactiveEntityManager;
13use std::str::FromStr;
14use std::sync::Arc;
15use uuid::Uuid;
16
17pub fn entity_mutation_field(entity_type: &EntityType) -> Option<Field> {
18 let ty = entity_type.ty.clone();
19 let entity_type_inner = entity_type.clone();
20 let dy_ty = DynamicGraphTypeDefinition::from(&entity_type.ty);
21 let mut field = Field::new(dy_ty.field_name(), TypeRef::named_nn(dy_ty.mutation_type_name()), move |ctx| {
22 let ty = ty.clone();
23 let entity_type = entity_type_inner.clone();
24 FieldFuture::new(async move {
25 let entity_instance_manager = ctx.data::<Arc<dyn ReactiveEntityManager + Send + Sync>>()?;
26 if let Ok(ids) = ctx.args.try_get("ids") {
28 let mut entity_instances = Vec::new();
29 for id in ids
30 .list()?
31 .iter()
32 .filter_map(|id| id.string().map(str::to_string).ok())
33 .filter_map(|id| Uuid::from_str(&id).ok())
34 {
35 if let Some(entity_instance) = entity_instance_manager.get(id) {
36 if entity_instance.ty != ty {
37 return Err(EntityInstanceIsNotOfType(id, ty.clone()).into());
38 }
39 entity_instances.push(entity_instance);
40 }
41 }
42 let field_value = FieldValue::owned_any(entity_instances);
43 return Ok(Some(field_value));
44 }
45 if let Ok(id) = ctx.args.try_get("id") {
47 let id = Uuid::from_str(id.string()?)?;
48 let entity_instance = entity_instance_manager.get(id).ok_or(EntityInstanceNotFound(id))?;
49 if entity_instance.ty != ty {
50 return Err(EntityInstanceIsNotOfType(id, ty.clone()).into());
51 }
52 let entity_instances = vec![entity_instance];
53 let field_value = FieldValue::owned_any(entity_instances);
54 return Ok(Some(field_value));
55 }
56 let instances = get_entity_instances_by_type_filter_by_properties(&ctx, &entity_type, entity_instance_manager);
58 let field_value = FieldValue::owned_any(instances);
59 Ok(Some(field_value))
60 })
61 })
62 .description(entity_type.description.clone())
63 .argument(InputValue::new("ids", TypeRef::named_nn_list(TypeRef::ID)))
64 .argument(InputValue::new("id", TypeRef::named(TypeRef::ID)))
65 .argument(InputValue::new("label", TypeRef::named(TypeRef::STRING)));
67 field = add_entity_type_properties_as_field_arguments(field, entity_type, true, true);
68 Some(field)
69}