shex_ast/ast/
shape_expr.rs1use iri_s::IriS;
2use prefixmap::{Deref, DerefError, IriRef, PrefixMap};
3use serde::{Deserialize, Serialize, Serializer};
4use std::str::FromStr;
5
6use super::serde_string_or_struct::SerializeStringOrStruct;
7use crate::ast::serde_string_or_struct::*;
8use crate::Annotation;
9use crate::{NodeConstraint, RefError, Shape, ShapeExprLabel};
10
11#[derive(Deserialize, Serialize, Debug, PartialEq, Clone)]
12#[serde(transparent)]
13pub struct ShapeExprWrapper {
14 #[serde(
15 serialize_with = "serialize_string_or_struct",
16 deserialize_with = "deserialize_string_or_struct"
17 )]
18 pub se: ShapeExpr,
19}
20
21impl Deref for ShapeExprWrapper {
22 fn deref(
23 &self,
24 base: &Option<IriS>,
25 prefixmap: &Option<PrefixMap>,
26 ) -> Result<Self, DerefError> {
27 let se = self.se.deref(base, prefixmap)?;
28 let sew = ShapeExprWrapper { se };
29 Ok(sew)
30 }
31}
32
33impl From<ShapeExpr> for ShapeExprWrapper {
34 fn from(shape_expr: ShapeExpr) -> Self {
35 Self { se: shape_expr }
36 }
37}
38
39#[derive(Deserialize, Serialize, Debug, PartialEq, Clone)]
40#[serde(tag = "type")]
41pub enum ShapeExpr {
42 ShapeOr {
43 #[serde(rename = "shapeExprs")]
44 shape_exprs: Vec<ShapeExprWrapper>,
45 },
46 ShapeAnd {
47 #[serde(rename = "shapeExprs")]
48 shape_exprs: Vec<ShapeExprWrapper>,
49 },
50 ShapeNot {
51 #[serde(rename = "shapeExpr")]
52 shape_expr: Box<ShapeExprWrapper>,
53 },
54
55 NodeConstraint(NodeConstraint),
56
57 Shape(Shape),
58
59 #[serde(rename = "ShapeExternal")]
60 External,
61
62 Ref(ShapeExprLabel),
63}
64
65impl FromStr for ShapeExpr {
66 type Err = RefError;
67
68 fn from_str(s: &str) -> Result<Self, Self::Err> {
69 let ref_ = ShapeExprLabel::from_str(s)?;
70 Ok(ShapeExpr::Ref(ref_))
71 }
72}
73
74impl SerializeStringOrStruct for ShapeExpr {
75 fn serialize_string_or_struct<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
76 where
77 S: Serializer,
78 {
79 match &self {
80 ShapeExpr::Ref(ref r) => r.serialize(serializer),
81 _ => self.serialize(serializer),
82 }
83 }
84}
85
86impl ShapeExpr {
87 pub fn empty_shape() -> ShapeExpr {
88 ShapeExpr::Shape(Shape::default())
89 }
90
91 pub fn external() -> ShapeExpr {
92 ShapeExpr::External
93 }
94
95 pub fn shape_not(se: ShapeExpr) -> ShapeExpr {
96 ShapeExpr::ShapeNot {
97 shape_expr: Box::new(ShapeExprWrapper { se }),
98 }
99 }
100
101 pub fn or(ses: Vec<ShapeExpr>) -> ShapeExpr {
102 let mut shape_exprs = Vec::new();
107 for se in ses {
108 shape_exprs.push(se.into())
109 }
110 ShapeExpr::ShapeOr { shape_exprs }
111 }
112
113 pub fn and(ses: Vec<ShapeExpr>) -> ShapeExpr {
114 let mut shape_exprs = Vec::new();
119 for se in ses {
120 shape_exprs.push(se.into())
121 }
122 ShapeExpr::ShapeAnd { shape_exprs }
123 }
124
125 pub fn node_constraint(nc: NodeConstraint) -> ShapeExpr {
126 ShapeExpr::NodeConstraint(nc)
127 }
128
129 pub fn iri_ref(iri_ref: IriRef) -> ShapeExpr {
130 ShapeExpr::Ref(ShapeExprLabel::iri_ref(iri_ref))
131 }
132
133 pub fn shape_ref(label: ShapeExprLabel) -> ShapeExpr {
134 ShapeExpr::Ref(label)
135 }
136
137 pub fn any() -> ShapeExpr {
138 ShapeExpr::default()
139 }
140
141 pub fn shape(shape: Shape) -> ShapeExpr {
142 ShapeExpr::Shape(shape)
143 }
144
145 pub fn add_annotation(&mut self, annotation: Annotation) {
146 match self {
147 Self::Shape(s) => s.add_annotation(annotation),
148 _ => todo!(),
149 };
150 }
151
152 pub fn has_annotations(&self) -> bool {
153 match self {
154 Self::Shape(s) => s.has_annotations(),
155 _ => todo!(),
156 }
157 }
158
159 pub fn annotations(&self) -> Option<impl Iterator<Item = &Annotation>> {
160 match self {
161 Self::Shape(s) => s.annotations(),
162 _ => todo!(),
163 }
164 }
165}
166
167impl Default for ShapeExpr {
168 fn default() -> Self {
169 ShapeExpr::Shape(Shape::default())
170 }
171}
172
173impl Deref for ShapeExpr {
174 fn deref(
175 &self,
176 base: &Option<IriS>,
177 prefixmap: &Option<PrefixMap>,
178 ) -> Result<Self, DerefError> {
179 match self {
180 ShapeExpr::External => Ok(ShapeExpr::External),
181 ShapeExpr::ShapeAnd { shape_exprs } => {
182 let shape_exprs = <ShapeExpr as Deref>::deref_vec(shape_exprs, base, prefixmap)?;
183 Ok(ShapeExpr::ShapeAnd {
184 shape_exprs: shape_exprs.clone(),
185 })
186 }
187 ShapeExpr::ShapeOr { shape_exprs } => {
188 let shape_exprs = <ShapeExpr as Deref>::deref_vec(shape_exprs, base, prefixmap)?;
189 Ok(ShapeExpr::ShapeOr {
190 shape_exprs: shape_exprs.clone(),
191 })
192 }
193 ShapeExpr::ShapeNot { shape_expr } => {
194 let shape_expr = Box::new(shape_expr.deref(base, prefixmap)?);
195 Ok(ShapeExpr::ShapeNot { shape_expr })
196 }
197 ShapeExpr::Shape(shape) => {
198 let shape = shape.deref(base, prefixmap)?;
199 Ok(ShapeExpr::Shape(shape))
200 }
201 ShapeExpr::Ref(ref_) => {
202 let ref_ = ref_.deref(base, prefixmap)?;
203 Ok(ShapeExpr::Ref(ref_))
204 }
205 ShapeExpr::NodeConstraint(nc) => {
206 let nc = nc.deref(base, prefixmap)?;
207 Ok(ShapeExpr::NodeConstraint(nc))
208 }
209 }
210 }
211}
212
213#[cfg(test)]
214mod tests {
215 use crate::{Pattern, StringFacet, XsFacet};
216
217 use super::*;
218
219 #[test]
220 fn test_serde_xsfacet_pattern() {
221 let facets: Vec<XsFacet> = vec![XsFacet::StringFacet(StringFacet::Pattern(Pattern::new(
222 "o*",
223 )))];
224 let nc = NodeConstraint::new().with_xsfacets(facets);
225 let se = ShapeExpr::NodeConstraint(nc);
226 let json_nc = serde_json::to_string(&se).unwrap();
227 assert_eq!(json_nc, "{\"type\":\"NodeConstraint\",\"pattern\":\"o*\"}");
228 }
229}