1use crate::{RegisteredVariable, RegisteredVocabulary};
2use ahri_tre_protocol::refs::{EntityRef, RelationRef};
3use ahri_tre_protocol::refs::{TagRef, TagScope};
4use ahri_tre_protocol::{
5 PublicUuid, dictionary,
6 refs::{DomainRef, VariableRef, VocabularyRef, encode_scoped_integer_ref as protocol_int_ref},
7};
8use std::collections::BTreeMap;
9pub fn semantic_variable(
10 datastore_id: PublicUuid,
11 variable: RegisteredVariable,
12) -> ahri_tre_protocol::dictionary::VariableDetail {
13 let value_format = variable.variable.value_format.clone();
14 let note = variable.variable.note.clone();
15 let ontology_namespace = variable.variable.ontology_namespace.clone();
16 ahri_tre_protocol::dictionary::VariableDetail {
17 vocabulary_items_withheld: true,
18 summary: protocol_variable_summary(datastore_id, variable.clone()),
19 value_format,
20 note,
21 ontology_namespace,
22 vocabulary_items: Vec::new(),
25 domain_detail: None,
26 }
27}
28
29fn protocol_variable_summary(
30 datastore_id: PublicUuid,
31 variable: RegisteredVariable,
32) -> ahri_tre_protocol::dictionary::VariableSummary {
33 ahri_tre_protocol::dictionary::VariableSummary {
34 variable: VariableRef {
35 datastore_id,
36 kind: ahri_tre_protocol::refs::ObjectKind::Variable,
37 id: protocol_int_ref("variable", variable.variable.variable_id.0),
38 },
39 domain: DomainRef {
40 datastore_id,
41 kind: ahri_tre_protocol::refs::ObjectKind::Domain,
42 id: protocol_int_ref("domain", variable.variable.domain_id.0),
43 },
44 name: variable.variable.name.as_str().to_string(),
45 value_type: variable.value_type.value_type,
46 vocabulary: variable
47 .vocabulary
48 .map(|value| protocol_vocabulary_metadata_summary(datastore_id, value)),
49 key_role: Some(format!("{:?}", variable.variable.key_role).to_ascii_lowercase()),
50 description: variable.variable.description,
51 ontology_class: variable.variable.ontology_class,
52 tags: Vec::new(),
53 }
54}
55
56fn protocol_vocabulary_metadata_summary(
57 datastore_id: PublicUuid,
58 vocabulary: ahri_tre_types::VocabularyRecord,
59) -> ahri_tre_protocol::dictionary::VocabularySummary {
60 ahri_tre_protocol::dictionary::VocabularySummary {
61 vocabulary: VocabularyRef {
62 datastore_id,
63 kind: ahri_tre_protocol::refs::ObjectKind::Vocabulary,
64 id: protocol_int_ref("vocabulary", vocabulary.vocabulary_id.0),
65 },
66 domain: DomainRef {
67 datastore_id,
68 kind: ahri_tre_protocol::refs::ObjectKind::Domain,
69 id: protocol_int_ref("domain", vocabulary.domain_id.0),
70 },
71 name: vocabulary.name.as_str().to_string(),
72 item_count: None,
73 description: vocabulary.description,
74 tags: Vec::new(),
75 }
76}
77
78pub fn semantic_vocabulary(
79 datastore_id: PublicUuid,
80 vocabulary: RegisteredVocabulary,
81) -> dictionary::VocabularyDetail {
82 dictionary::VocabularyDetail {
83 items_withheld: true,
84 summary: protocol_vocabulary_metadata_summary(datastore_id, vocabulary.vocabulary),
85 items: Vec::new(),
86 }
87}
88
89pub fn semantic_entity(
90 datastore_id: PublicUuid,
91 entity: ahri_tre_types::EntityRecord,
92) -> ahri_tre_protocol::model::EntityDetail {
93 ahri_tre_protocol::model::EntityDetail {
94 summary: protocol_entity_summary(datastore_id, entity.clone()),
95 agent_instructions: entity.agent_instructions,
96 ontology_namespace: entity.ontology_namespace,
97 }
98}
99
100fn protocol_entity_summary(
101 datastore_id: PublicUuid,
102 entity: ahri_tre_types::EntityRecord,
103) -> ahri_tre_protocol::model::EntitySummary {
104 ahri_tre_protocol::model::EntitySummary {
105 entity: protocol_entity_ref(datastore_id, entity.entity_id.0),
106 domain: protocol_domain_ref(datastore_id, entity.domain_id.0),
107 name: entity.name.as_str().to_owned(),
108 description: entity.description,
109 ontology_class: entity.ontology_class,
110 tags: Vec::new(),
111 }
112}
113
114pub fn semantic_relation(
115 datastore_id: PublicUuid,
116 relation: ahri_tre_types::EntityRelationRecord,
117 endpoint_names: &BTreeMap<i64, String>,
118) -> ahri_tre_protocol::model::RelationDefinitionDetail {
119 ahri_tre_protocol::model::RelationDefinitionDetail {
120 summary: protocol_relation_summary(datastore_id, relation.clone(), endpoint_names),
121 agent_instructions: relation.agent_instructions,
122 ontology_namespace: relation.ontology_namespace,
123 }
124}
125
126fn protocol_relation_summary(
127 datastore_id: PublicUuid,
128 relation: ahri_tre_types::EntityRelationRecord,
129 endpoint_names: &BTreeMap<i64, String>,
130) -> ahri_tre_protocol::model::RelationDefinitionSummary {
131 ahri_tre_protocol::model::RelationDefinitionSummary {
132 relation: protocol_relation_ref(datastore_id, relation.entity_relation_id.0),
133 domain: protocol_domain_ref(datastore_id, relation.domain_id.0),
134 name: relation.name.as_str().to_owned(),
135 subject_entity: protocol_entity_ref(datastore_id, relation.subject_entity_id.0),
136 object_entity: protocol_entity_ref(datastore_id, relation.object_entity_id.0),
137 subject_entity_name: endpoint_names.get(&relation.subject_entity_id.0).cloned(),
138 object_entity_name: endpoint_names.get(&relation.object_entity_id.0).cloned(),
139 description: relation.description,
140 ontology_class: relation.ontology_class,
141 tags: Vec::new(),
142 }
143}
144
145fn protocol_entity_ref(datastore_id: PublicUuid, id: i64) -> EntityRef {
146 EntityRef {
147 datastore_id,
148 kind: ahri_tre_protocol::refs::ObjectKind::Entity,
149 id: protocol_int_ref("entity", id),
150 }
151}
152
153fn protocol_relation_ref(datastore_id: PublicUuid, id: i64) -> RelationRef {
154 RelationRef {
155 datastore_id,
156 kind: ahri_tre_protocol::refs::ObjectKind::Relation,
157 id: protocol_int_ref("relation", id),
158 }
159}
160
161fn protocol_domain_ref(datastore_id: PublicUuid, id: i64) -> DomainRef {
162 DomainRef {
163 datastore_id,
164 kind: ahri_tre_protocol::refs::ObjectKind::Domain,
165 id: protocol_int_ref("domain", id),
166 }
167}
168
169pub fn tag_summary(
170 datastore_id: PublicUuid,
171 tag: ahri_tre_types::TagRecord,
172) -> ahri_tre_protocol::refs::TagSummary {
173 ahri_tre_protocol::refs::TagSummary {
174 tag: TagRef {
175 datastore_id,
176 kind: ahri_tre_protocol::refs::ObjectKind::Tag,
177 id: protocol_int_ref("tag", tag.tag_id.0),
178 },
179 scope: TagScope::Global,
180 label: tag.name,
181 }
182}
183
184pub fn semantic_transformation(
185 datastore_id: PublicUuid,
186 value: crate::TransformationSummary,
187) -> ahri_tre_protocol::transformation::TransformationSummary {
188 use ahri_tre_protocol::{
189 refs::{ObjectKind, ObjectRef},
190 transformation::{TransformationDetail, TransformationSummary},
191 };
192 let version = |id| ObjectRef {
193 datastore_id,
194 kind: ObjectKind::AssetVersion,
195 id: PublicUuid::from_uuid(id),
196 };
197 TransformationSummary {
198 transformation: TransformationDetail {
199 transformation_id: ObjectRef {
200 datastore_id,
201 kind: ObjectKind::Transformation,
202 id: protocol_int_ref("transformation", value.transformation.transformation_id.0),
203 },
204 transformation_type: value.transformation.transformation_type,
205 description: value.transformation.description,
206 date_created: value.transformation.date_created,
207 created_by: value.transformation.created_by,
208 },
209 inputs: value
210 .inputs
211 .into_iter()
212 .map(|link| version(link.version_id.0))
213 .collect(),
214 outputs: value
215 .outputs
216 .into_iter()
217 .map(|link| version(link.version_id.0))
218 .collect(),
219 }
220}
221
222pub fn workflow_lineage(
224 datastore_id: PublicUuid,
225 value: ahri_tre_types::TransformationLineageRecord,
226) -> ahri_tre_protocol::transformation::TransformationSummary {
227 semantic_transformation(
228 datastore_id,
229 crate::TransformationSummary {
230 transformation: value.transformation,
231 inputs: value.inputs,
232 outputs: value.outputs,
233 },
234 )
235}
236
237#[cfg(test)]
238mod tests {
239 use super::*;
240 use ahri_tre_types::{
241 DomainId, NcName, VocabularyId, VocabularyItemId, VocabularyItemRecord, VocabularyRecord,
242 };
243
244 #[test]
245 fn catalogue_vocabulary_never_releases_unproved_values_or_counts() {
246 let datastore_id = PublicUuid::from_uuid(uuid::Uuid::from_u128(1));
247 let detail = semantic_vocabulary(
248 datastore_id,
249 RegisteredVocabulary {
250 vocabulary: VocabularyRecord {
251 vocabulary_id: VocabularyId(4),
252 domain_id: DomainId(2),
253 name: NcName::parse("status").unwrap(),
254 description: None,
255 },
256 items: vec![VocabularyItemRecord {
257 vocabulary_item_id: VocabularyItemId(5),
258 vocabulary_id: VocabularyId(4),
259 value: 1,
260 code: "content-must-not-leave".into(),
261 description: None,
262 }],
263 },
264 );
265 assert!(detail.items_withheld);
266 assert!(detail.items.is_empty());
267 assert_eq!(detail.summary.item_count, None);
268 assert_eq!(detail.summary.vocabulary.datastore_id, datastore_id);
269 let json = serde_json::to_string(&detail).unwrap();
270 assert!(!json.contains("content-must-not-leave"));
271 assert!(!json.contains("item_count"));
272 }
273}