reactive_graph_graphql_schema/query/instances/
relation_instance.rs1use std::sync::Arc;
2
3use async_graphql::Context;
4use async_graphql::Object;
5use async_graphql::Result;
6use reactive_graph_behaviour_service_api::RelationBehaviourRegistry;
7use reactive_graph_behaviour_service_api::RelationComponentBehaviourRegistry;
8use reactive_graph_reactive_model_impl::ReactiveRelation;
9use reactive_graph_type_system_api::ComponentManager;
10use reactive_graph_type_system_api::RelationTypeManager;
11
12use crate::query::GraphQLComponent;
13use crate::query::GraphQLComponentBehaviour;
14use crate::query::GraphQLEntityInstance;
15use crate::query::GraphQLPropertyInstance;
16use crate::query::GraphQLRelationBehaviour;
17use crate::query::GraphQLRelationType;
18
19pub struct GraphQLRelationInstance {
20 relation_instance: ReactiveRelation,
21}
22
23#[Object(name = "RelationInstance")]
34impl GraphQLRelationInstance {
35 async fn outbound(&self) -> GraphQLEntityInstance {
40 self.relation_instance.outbound.clone().into()
41 }
42
43 #[graphql(name = "type")]
45 async fn relation_type(&self, context: &Context<'_>) -> Option<GraphQLRelationType> {
46 context
47 .data::<Arc<dyn RelationTypeManager + Send + Sync>>()
48 .ok()?
49 .get(&self.relation_instance.relation_type_id())
50 .map(|r| r.into())
51 }
52
53 async fn instance_id(&self) -> String {
55 self.relation_instance.ty.instance_id()
56 }
57
58 async fn inbound(&self) -> GraphQLEntityInstance {
63 self.relation_instance.inbound.clone().into()
64 }
65
66 async fn name(&self) -> String {
68 self.relation_instance.name.clone()
69 }
70
71 async fn description(&self) -> String {
73 self.relation_instance.description.clone()
74 }
75
76 async fn properties(
83 &self,
84 #[graphql(desc = "Filters by property name.")] name: Option<String>,
85 #[graphql(desc = "Filters by property names")] names: Option<Vec<String>>,
86 #[graphql(desc = "If true, the properties are sorted by name")] sort: Option<bool>,
87 ) -> Vec<GraphQLPropertyInstance> {
88 let mut properties: Vec<GraphQLPropertyInstance> = self
89 .relation_instance
90 .properties
91 .iter()
92 .filter(|property_instance| name.is_none() || name.clone().unwrap() == property_instance.key().as_str())
93 .filter(|property_instance| names.is_none() || names.clone().unwrap().contains(property_instance.key()))
94 .map(|property_instance| {
95 GraphQLPropertyInstance::new_relation_property(
96 self.relation_instance.relation_type_id(),
97 property_instance.key().clone(),
98 property_instance.get(),
99 )
100 })
101 .collect();
102 if sort.unwrap_or_default() {
103 properties.sort_by(|a, b| a.name.cmp(&b.name));
104 }
105 properties
106 }
107
108 async fn components(&self, context: &Context<'_>) -> Vec<GraphQLComponent> {
111 match context.data::<Arc<dyn ComponentManager + Send + Sync>>() {
112 Ok(component_manager) => self
113 .relation_instance
114 .components
115 .iter()
116 .map(|p| p.key().clone())
117 .filter_map(|component_name| {
118 component_manager.get(&component_name).map(|component| {
119 let component: GraphQLComponent = component.into();
120 component
121 })
122 })
123 .collect(),
124 Err(_) => Vec::new(),
125 }
126 }
127
128 async fn behaviours(&self, context: &Context<'_>) -> Result<Vec<GraphQLRelationBehaviour>> {
131 let relation_behaviour_registry = context.data::<Arc<dyn RelationBehaviourRegistry + Send + Sync>>()?;
132 Ok(self
133 .relation_instance
134 .behaviours
135 .iter()
136 .filter_map(move |p| {
137 let behaviour_ty = p.key();
138 relation_behaviour_registry
139 .get_by_behaviour_type(behaviour_ty)
140 .map(GraphQLRelationBehaviour::from)
141 })
142 .collect())
143 }
144
145 async fn component_behaviours(&self, context: &Context<'_>) -> Result<Vec<GraphQLComponentBehaviour>> {
148 let relation_component_behaviour_registry = context.data::<Arc<dyn RelationComponentBehaviourRegistry + Send + Sync>>()?;
149 Ok(self
150 .relation_instance
151 .behaviours
152 .iter()
153 .filter_map(move |p| {
154 let behaviour_ty = p.key();
155 relation_component_behaviour_registry
156 .get_by_behaviour_type(behaviour_ty)
157 .map(GraphQLComponentBehaviour::from)
158 })
159 .collect())
160 }
161}
162
163impl From<ReactiveRelation> for GraphQLRelationInstance {
164 fn from(relation_instance: ReactiveRelation) -> Self {
165 GraphQLRelationInstance { relation_instance }
166 }
167}