typedb_driver/answer/concept_map.rs
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20use std::{
21 collections::{hash_map, HashMap},
22 ops::Index,
23};
24
25use crate::concept::Concept;
26
27/// Contains a mapping of variables to concepts.
28#[derive(Clone, Debug, PartialEq)]
29pub struct ConceptMap {
30 /// The `HashMap` where keys are query variables, and values are concepts.
31 pub map: HashMap<String, Concept>,
32 /// The `Explainables` object for this `ConceptMap`, that exposes which of the concepts
33 /// in this `ConceptMap` are explainable.
34 pub explainables: Explainables,
35}
36
37impl ConceptMap {
38 /// Retrieves a concept for a given variable name.
39 ///
40 /// # Arguments
41 ///
42 /// * `var_name` -- The string representation of a variable
43 ///
44 /// # Examples
45 ///
46 /// ```rust
47 /// concept_map.get(var_name)
48 /// ```
49 pub fn get(&self, var_name: &str) -> Option<&Concept> {
50 self.map.get(var_name)
51 }
52
53 /// Produces an iterator over all concepts in this `ConceptMap`.
54 ///
55 /// # Examples
56 ///
57 /// ```rust
58 /// concept_map.concepts()
59 /// ```
60 pub fn concepts(&self) -> impl Iterator<Item = &Concept> {
61 self.map.values()
62 }
63}
64
65impl From<ConceptMap> for HashMap<String, Concept> {
66 fn from(cm: ConceptMap) -> Self {
67 cm.map
68 }
69}
70
71impl Index<String> for ConceptMap {
72 type Output = Concept;
73
74 fn index(&self, index: String) -> &Self::Output {
75 &self.map[&index]
76 }
77}
78
79impl IntoIterator for ConceptMap {
80 type Item = (String, Concept);
81 type IntoIter = hash_map::IntoIter<String, Concept>;
82
83 fn into_iter(self) -> Self::IntoIter {
84 self.map.into_iter()
85 }
86}
87
88/// Contains explainable objects.
89#[derive(Clone, Debug, Default, PartialEq)]
90pub struct Explainables {
91 /// Explainable relations
92 pub relations: HashMap<String, Explainable>,
93 /// Explainable attributes
94 pub attributes: HashMap<String, Explainable>,
95 /// Explainable pairs of (owner, attribute)
96 pub ownerships: HashMap<(String, String), Explainable>,
97}
98
99impl Explainables {
100 /// Checks if this `Explainables` does not contain any `Explainable` object.
101 ///
102 /// # Examples
103 ///
104 /// ```rust
105 /// explainables.is_empty()
106 /// ```
107 pub fn is_empty(&self) -> bool {
108 self.relations.is_empty() && self.attributes.is_empty() && self.ownerships.is_empty()
109 }
110}
111
112/// Contains an explainable object.
113#[derive(Clone, Debug, PartialEq)]
114pub struct Explainable {
115 /// The subquery of the original query that is actually being explained.
116 pub conjunction: String,
117 /// The unique ID that identifies this `Explainable`.
118 pub id: i64,
119}
120
121impl Explainable {
122 pub(crate) fn new(conjunction: String, id: i64) -> Self {
123 Self { conjunction, id }
124 }
125}