reactive_graph_dynamic_graph_impl/field/entity/inbound/
outbound_entities_field.rs

1use 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}