shacl_ast/ast/
node_shape.rs1use crate::{
2 component::Component, message_map::MessageMap, severity::Severity, target::Target, SH_CLOSED,
3 SH_DEACTIVATED, SH_DESCRIPTION, SH_GROUP, SH_INFO_STR, SH_NAME, SH_NODE_SHAPE, SH_PROPERTY,
4 SH_SEVERITY, SH_VIOLATION_STR, SH_WARNING_STR,
5};
6use iri_s::iri;
7use srdf::{RDFNode, SRDFBuilder};
8use std::fmt::Display;
9
10#[derive(Debug, Clone)]
11pub struct NodeShape {
12 id: RDFNode,
13 components: Vec<Component>,
14 targets: Vec<Target>,
15 property_shapes: Vec<RDFNode>,
16 closed: bool,
17 deactivated: bool,
19 severity: Option<Severity>,
21 name: MessageMap,
22 description: MessageMap,
23 group: Option<RDFNode>,
24 }
26
27impl NodeShape {
28 pub fn new(id: RDFNode) -> Self {
29 NodeShape {
30 id,
31 components: Vec::new(),
32 targets: Vec::new(),
33 property_shapes: Vec::new(),
34 closed: false,
35 deactivated: false,
37 severity: None,
39 name: MessageMap::new(),
40 description: MessageMap::new(),
41 group: None,
42 }
44 }
45
46 pub fn with_targets(mut self, targets: Vec<Target>) -> Self {
47 self.targets = targets;
48 self
49 }
50
51 pub fn set_targets(&mut self, targets: Vec<Target>) {
52 self.targets = targets;
53 }
54
55 pub fn with_property_shapes(mut self, property_shapes: Vec<RDFNode>) -> Self {
56 self.property_shapes = property_shapes;
57 self
58 }
59
60 pub fn with_components(mut self, components: Vec<Component>) -> Self {
61 self.components = components;
62 self
63 }
64
65 pub fn with_closed(mut self, closed: bool) -> Self {
66 self.closed = closed;
67 self
68 }
69
70 pub fn id(&self) -> &RDFNode {
71 &self.id
72 }
73
74 pub fn is_closed(&self) -> &bool {
75 &self.closed
76 }
77
78 pub fn is_deactivated(&self) -> &bool {
79 &self.deactivated
80 }
81
82 pub fn severity(&self) -> Option<Severity> {
83 self.severity.to_owned()
84 }
85
86 pub fn components(&self) -> &Vec<Component> {
87 &self.components
88 }
89
90 pub fn targets(&self) -> &Vec<Target> {
91 &self.targets
92 }
93
94 pub fn property_shapes(&self) -> &Vec<RDFNode> {
95 &self.property_shapes
96 }
97
98 pub fn write<RDF>(&self, rdf: &mut RDF) -> Result<(), RDF::Err>
100 where
101 RDF: SRDFBuilder,
102 {
103 let id: RDF::Subject = self.id.clone().try_into().map_err(|_| unreachable!())?;
104 rdf.add_type(id.clone(), SH_NODE_SHAPE.clone())?;
105
106 self.name.iter().try_for_each(|(lang, value)| {
107 let literal: RDF::Literal = match lang {
108 Some(_) => todo!(),
109 None => value.clone().into(),
110 };
111 rdf.add_triple(id.clone(), SH_NAME.clone(), literal)
112 })?;
113
114 self.description.iter().try_for_each(|(lang, value)| {
115 let literal: RDF::Literal = match lang {
116 Some(_) => todo!(),
117 None => value.clone().into(),
118 };
119 rdf.add_triple(id.clone(), SH_DESCRIPTION.clone(), literal)
120 })?;
121
122 self.components
123 .iter()
124 .try_for_each(|component| component.write(&self.id, rdf))?;
125
126 self.targets
127 .iter()
128 .try_for_each(|target| target.write(&self.id, rdf))?;
129
130 self.property_shapes.iter().try_for_each(|property_shape| {
131 rdf.add_triple(id.clone(), SH_PROPERTY.clone(), property_shape.clone())
132 })?;
133
134 if self.deactivated {
135 let literal: RDF::Literal = "true".to_string().into();
136
137 rdf.add_triple(id.clone(), SH_DEACTIVATED.clone(), literal)?;
138 }
139
140 if let Some(group) = &self.group {
141 rdf.add_triple(id.clone(), SH_GROUP.clone(), group.clone())?;
142 }
143
144 if let Some(severity) = &self.severity {
145 let pred = match severity {
146 Severity::Violation => iri!(SH_VIOLATION_STR),
147 Severity::Info => iri!(SH_INFO_STR),
148 Severity::Warning => iri!(SH_WARNING_STR),
149 Severity::Generic(iri) => iri.get_iri().unwrap(),
150 };
151
152 rdf.add_triple(id.clone(), SH_SEVERITY.clone(), pred.clone())?;
153 }
154
155 if self.closed {
156 let literal: RDF::Literal = "true".to_string().into();
157
158 rdf.add_triple(id.clone(), SH_CLOSED.clone(), literal)?;
159 }
160
161 Ok(())
162 }
163}
164
165impl Display for NodeShape {
166 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
167 writeln!(f, "{{")?;
168 if self.closed {
169 writeln!(f, " closed: {}", self.closed)?
170 }
171 for target in self.targets.iter() {
172 writeln!(f, " {target}")?
173 }
174 for property in self.property_shapes.iter() {
175 writeln!(f, " Property {property}")?
176 }
177 for component in self.components.iter() {
178 writeln!(f, " {component}")?
179 }
180 write!(f, "}}")?;
181 Ok(())
182 }
183}