reactive_graph_dynamic_graph_impl/field/entity/
creation.rs1use crate::field::create_properties_from_field_arguments;
2use crate::field::property::field_arguments::add_entity_type_properties_as_field_arguments;
3use crate::object::types::DynamicGraphTypeDefinition;
4use async_graphql::Error;
5use async_graphql::dynamic::Field;
6use async_graphql::dynamic::FieldFuture;
7use async_graphql::dynamic::FieldValue;
8use async_graphql::dynamic::InputValue;
9use async_graphql::dynamic::TypeRef;
10use reactive_graph_graph::EntityType;
11use reactive_graph_reactive_model_impl::ReactiveEntity;
12use reactive_graph_reactive_model_impl::ReactiveProperties;
13use reactive_graph_reactive_service_api::ReactiveEntityManager;
14use std::str::FromStr;
15use std::sync::Arc;
16use uuid::Uuid;
17
18pub fn entity_creation_field(entity_type: &EntityType) -> Option<Field> {
19 let ty = entity_type.ty.clone();
20 let entity_type_inner = entity_type.clone();
21 let dy_ty = DynamicGraphTypeDefinition::from(&ty);
22 let mut field = Field::new(dy_ty.mutation_field_name("create"), TypeRef::named_nn(dy_ty.to_string()), move |ctx| {
23 let ty = ty.clone();
24 let entity_type = entity_type_inner.clone();
25 FieldFuture::new(async move {
26 let entity_instance_manager = ctx.data::<Arc<dyn ReactiveEntityManager + Send + Sync>>()?;
27 let id = if let Some(id) = ctx.args.get("id") {
28 let id = Uuid::from_str(id.string()?)?;
29 if entity_instance_manager.has(id) {
30 return Err(Error::new(format!("Uuid {id} is already taken")));
31 }
32 id
33 } else {
34 Uuid::new_v4()
35 };
36 let properties = create_properties_from_field_arguments(&ctx, &entity_type.properties)?;
37 let properties = ReactiveProperties::new_with_id_from_properties(id, properties);
38 let reactive_entity = ReactiveEntity::builder().ty(&ty).id(id).properties(properties).build();
39 if let Ok(reactive_entity) = entity_instance_manager.register_reactive_instance(reactive_entity) {
40 return Ok(Some(FieldValue::owned_any(reactive_entity)));
41 }
42 Ok(None)
43 })
44 })
45 .argument(InputValue::new("id", TypeRef::named(TypeRef::ID)));
46 field = add_entity_type_properties_as_field_arguments(field, entity_type, false, false);
47 Some(field)
48}