reactive_graph_dynamic_graph_impl/field/entity/outbound/
relation_field.rs

1use crate::extension::field_description::DynamicGraphFieldDescriptionExtension;
2use crate::extension::field_name::DynamicGraphFieldNameExtension;
3use crate::object::types::DynamicGraphTypeDefinition;
4use async_graphql::dynamic::Field;
5use async_graphql::dynamic::FieldFuture;
6use async_graphql::dynamic::FieldValue;
7use async_graphql::dynamic::TypeRef;
8use reactive_graph_graph::RelationType;
9use reactive_graph_reactive_model_impl::ReactiveEntity;
10use reactive_graph_reactive_service_api::ReactiveRelationManager;
11use std::sync::Arc;
12
13pub fn entity_outbound_relation_field(
14    outbound_relation_type: &RelationType,
15    field_names: &DynamicGraphFieldNameExtension,
16    field_descriptions: &DynamicGraphFieldDescriptionExtension,
17) -> Option<Field> {
18    let outbound_ty = outbound_relation_type.ty.clone();
19    let dy_ty = DynamicGraphTypeDefinition::from(&outbound_ty);
20
21    let field_name = field_names.from_outbound_entity_to_relation.clone().unwrap_or(dy_ty.outbound_type_name());
22    if field_name.is_empty() {
23        return None;
24    }
25    let field_description = field_descriptions
26        .from_outbound_entity_to_relation
27        .clone()
28        .unwrap_or(outbound_relation_type.description.clone());
29
30    let field = Field::new(field_name, TypeRef::named_nn_list_nn(dy_ty.to_string()), move |ctx| {
31        let outbound_ty = outbound_ty.clone();
32        FieldFuture::new(async move {
33            let entity_instance = ctx.parent_value.try_downcast_ref::<ReactiveEntity>()?;
34            let relation_instance_manager = ctx.data::<Arc<dyn ReactiveRelationManager + Send + Sync>>()?;
35            let relation_instances: Vec<FieldValue> = relation_instance_manager
36                .get_by_outbound_entity(entity_instance.id)
37                .iter()
38                .filter(|relation_instance| outbound_ty.clone() == relation_instance.relation_type_id())
39                .map(|relation_instance| FieldValue::owned_any(relation_instance.clone()))
40                .collect();
41            Ok(Some(FieldValue::list(relation_instances)))
42        })
43    })
44    .description(field_description);
45    Some(field)
46}