shex_ast/ast/
shape_expr.rs

1use 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 shape_exprs = ses
103        .into_iter()
104        .map(|shape_expression| Box::new(shape_expression.into()))
105        .collect(); */
106        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 shape_exprs = ses
115        .into_iter()
116        .map(|shape_expression| Box::new(shape_expression.into()))
117        .collect(); */
118        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}