bc_envelope/extension/edge/
edge_impl.rs1use known_values::{IS_A_RAW, SOURCE_RAW, TARGET_RAW};
2
3use crate::{Envelope, Error, Result, known_values};
4
5impl Envelope {
7 pub fn add_edge_envelope(&self, edge: Self) -> Self {
9 self.add_assertion(known_values::EDGE, edge)
10 }
11
12 pub fn edges(&self) -> Result<Vec<Self>> {
14 Ok(self.objects_for_predicate(known_values::EDGE))
15 }
16
17 pub fn validate_edge(&self) -> Result<()> {
24 let inner = if self.subject().is_wrapped() {
25 self.subject().try_unwrap()?
26 } else {
27 self.clone()
28 };
29
30 let mut seen_is_a = false;
31 let mut seen_source = false;
32 let mut seen_target = false;
33
34 for assertion in inner.assertions() {
35 let predicate = assertion
36 .try_predicate()?
37 .try_known_value()
38 .map_err(|_| Error::EdgeUnexpectedAssertion)?
39 .value();
40 match predicate {
41 IS_A_RAW => {
42 if seen_is_a {
43 return Err(Error::EdgeDuplicateIsA);
44 }
45 seen_is_a = true;
46 }
47 SOURCE_RAW => {
48 if seen_source {
49 return Err(Error::EdgeDuplicateSource);
50 }
51 seen_source = true;
52 }
53 TARGET_RAW => {
54 if seen_target {
55 return Err(Error::EdgeDuplicateTarget);
56 }
57 seen_target = true;
58 }
59 _ => return Err(Error::EdgeUnexpectedAssertion),
60 }
61 }
62
63 if !seen_is_a {
64 return Err(Error::EdgeMissingIsA);
65 }
66 if !seen_source {
67 return Err(Error::EdgeMissingSource);
68 }
69 if !seen_target {
70 return Err(Error::EdgeMissingTarget);
71 }
72
73 Ok(())
74 }
75
76 pub fn edge_is_a(&self) -> Result<Self> {
78 let inner = if self.subject().is_wrapped() {
79 self.subject().try_unwrap()?
80 } else {
81 self.clone()
82 };
83 inner.object_for_predicate(known_values::IS_A)
84 }
85
86 pub fn edge_source(&self) -> Result<Self> {
88 let inner = if self.subject().is_wrapped() {
89 self.subject().try_unwrap()?
90 } else {
91 self.clone()
92 };
93 inner.object_for_predicate(known_values::SOURCE)
94 }
95
96 pub fn edge_target(&self) -> Result<Self> {
98 let inner = if self.subject().is_wrapped() {
99 self.subject().try_unwrap()?
100 } else {
101 self.clone()
102 };
103 inner.object_for_predicate(known_values::TARGET)
104 }
105
106 pub fn edge_subject(&self) -> Result<Self> {
108 let inner = if self.subject().is_wrapped() {
109 self.subject().try_unwrap()?
110 } else {
111 self.clone()
112 };
113 Ok(inner.subject())
114 }
115
116 pub fn edges_matching(
121 &self,
122 is_a: Option<&Self>,
123 source: Option<&Self>,
124 target: Option<&Self>,
125 subject: Option<&Self>,
126 ) -> Result<Vec<Self>> {
127 let all_edges = self.edges()?;
128 let mut matching = Vec::new();
129
130 for edge in all_edges {
131 if let Some(is_a_filter) = is_a {
132 if let Ok(edge_is_a) = edge.edge_is_a() {
133 if !edge_is_a.is_equivalent_to(is_a_filter) {
134 continue;
135 }
136 } else {
137 continue;
138 }
139 }
140
141 if let Some(source_filter) = source {
142 if let Ok(edge_source) = edge.edge_source() {
143 if !edge_source.is_equivalent_to(source_filter) {
144 continue;
145 }
146 } else {
147 continue;
148 }
149 }
150
151 if let Some(target_filter) = target {
152 if let Ok(edge_target) = edge.edge_target() {
153 if !edge_target.is_equivalent_to(target_filter) {
154 continue;
155 }
156 } else {
157 continue;
158 }
159 }
160
161 if let Some(subject_filter) = subject {
162 if let Ok(edge_subject) = edge.edge_subject() {
163 if !edge_subject.is_equivalent_to(subject_filter) {
164 continue;
165 }
166 } else {
167 continue;
168 }
169 }
170
171 matching.push(edge);
172 }
173
174 Ok(matching)
175 }
176}