reactive_graph_dynamic_graph_impl/field/entity/inbound/
outbound_entities_field.rs1use crate::object::types::DynamicGraphTypeDefinition;
2use async_graphql::dynamic::Field;
3use async_graphql::dynamic::FieldFuture;
4use async_graphql::dynamic::FieldValue;
5use async_graphql::dynamic::TypeRef;
6use reactive_graph_graph::ComponentTypeId;
7use reactive_graph_graph::EntityTypeId;
8use reactive_graph_graph::RelationTypeId;
9use reactive_graph_reactive_model_impl::ReactiveEntity;
10use reactive_graph_reactive_service_api::ReactiveRelationManager;
11use std::sync::Arc;
12
13pub fn inbound_entity_to_outbound_entities_field(
14 ty: &RelationTypeId,
15 outbound_ty: &EntityTypeId,
16 field_name: Option<String>,
17 field_description: Option<String>,
18) -> Option<Field> {
19 let dy_ty = DynamicGraphTypeDefinition::from(outbound_ty);
20 let field_name = field_name.unwrap_or(dy_ty.outbound_type_name());
21 create_inbound_entity_to_outbound_field(ty, &dy_ty.to_string(), &field_name, field_description)
22}
23
24pub fn inbound_entity_to_outbound_entities_union_field(
25 ty: &RelationTypeId,
26 type_name: &str,
27 field_name: Option<String>,
28 field_description: Option<String>,
29) -> Option<Field> {
30 let field_name = field_name.unwrap_or("outbound".to_string());
31 if field_name.is_empty() {
32 return None;
33 }
34 let relation_ty_inner = ty.clone();
35 let mut field = Field::new(field_name, TypeRef::named_nn_list_nn(type_name), move |ctx| {
36 let ty = relation_ty_inner.clone();
37 FieldFuture::new(async move {
38 let relation_instance_manager = ctx.data::<Arc<dyn ReactiveRelationManager + Send + Sync>>()?;
39 let entity_instance = ctx.parent_value.try_downcast_ref::<ReactiveEntity>()?;
40 Ok(Some(FieldValue::list(
41 relation_instance_manager
42 .get_by_inbound_entity(entity_instance.id)
43 .iter()
44 .filter(|relation_instance| relation_instance.relation_type_id() == ty)
45 .map(|relation_instance| {
46 let outbound = relation_instance.outbound.clone();
47 let dy_ty = DynamicGraphTypeDefinition::from(&outbound.ty);
48 FieldValue::owned_any(outbound).with_type(dy_ty.to_string())
49 }),
50 )))
51 })
52 });
53 if let Some(field_description) = field_description {
54 field = field.description(field_description);
55 }
56 Some(field)
57}
58
59pub fn inbound_entity_to_outbound_components_field(
60 ty: &RelationTypeId,
61 component_ty: &ComponentTypeId,
62 field_name: Option<String>,
63 field_description: Option<String>,
64) -> Option<Field> {
65 let dy_ty = DynamicGraphTypeDefinition::from(component_ty);
66 let field_name = field_name.unwrap_or(dy_ty.outbound_type_name());
67 create_inbound_entity_to_outbound_field(ty, &dy_ty.to_string(), &field_name, field_description)
68}
69
70pub fn create_inbound_entity_to_outbound_field(ty: &RelationTypeId, type_name: &str, field_name: &str, field_description: Option<String>) -> Option<Field> {
71 if field_name.is_empty() {
72 return None;
73 }
74 let relation_ty_inner = ty.clone();
75 let mut field = Field::new(field_name, TypeRef::named_nn_list_nn(type_name), move |ctx| {
76 let ty = relation_ty_inner.clone();
77 FieldFuture::new(async move {
78 let relation_instance_manager = ctx.data::<Arc<dyn ReactiveRelationManager + Send + Sync>>()?;
79 let entity_instance = ctx.parent_value.try_downcast_ref::<ReactiveEntity>()?;
80 Ok(Some(FieldValue::list(
81 relation_instance_manager
82 .get_by_inbound_entity(entity_instance.id)
83 .iter()
84 .filter(|relation_instance| relation_instance.relation_type_id() == ty)
85 .map(|relation_instance| FieldValue::owned_any(relation_instance.outbound.clone())),
86 )))
87 })
88 });
89 if let Some(field_description) = field_description {
90 field = field.description(field_description);
91 }
92 Some(field)
93}