shex_ast/ast/
annotation.rs

1use std::{fmt, result};
2
3use iri_s::IriS;
4use prefixmap::IriRef;
5use prefixmap::{Deref, DerefError};
6use serde::ser::SerializeMap;
7use serde::{
8    de::{self, MapAccess, Visitor},
9    Deserialize, Serialize, Serializer,
10};
11use srdf::RDFS_LABEL_STR;
12
13use super::object_value::ObjectValue;
14
15#[derive(Debug, PartialEq, Clone)]
16pub struct Annotation {
17    predicate: IriRef,
18    object: ObjectValue,
19}
20
21impl Annotation {
22    pub fn new(predicate: IriRef, object: ObjectValue) -> Annotation {
23        Annotation { predicate, object }
24    }
25
26    pub fn rdfs_label(str: &str) -> Annotation {
27        Annotation {
28            predicate: IriRef::iri(IriS::new_unchecked(RDFS_LABEL_STR)),
29            object: ObjectValue::str(str),
30        }
31    }
32
33    pub fn rdfs_comment(str: &str) -> Annotation {
34        Annotation {
35            predicate: IriRef::prefixed("rdfs", "comment"),
36            object: ObjectValue::str(str),
37        }
38    }
39
40    pub fn predicate(&self) -> IriRef {
41        self.predicate.clone()
42    }
43
44    pub fn object(&self) -> ObjectValue {
45        self.object.clone()
46    }
47}
48
49impl Deref for Annotation {
50    fn deref(
51        &self,
52        base: &Option<iri_s::IriS>,
53        prefixmap: &Option<prefixmap::PrefixMap>,
54    ) -> Result<Self, DerefError> {
55        let new_pred = self.predicate.deref(base, prefixmap)?;
56        let new_obj = self.object.deref(base, prefixmap)?;
57        Ok(Annotation {
58            predicate: new_pred,
59            object: new_obj,
60        })
61    }
62}
63
64impl Serialize for Annotation {
65    fn serialize<S>(&self, serializer: S) -> result::Result<S::Ok, S::Error>
66    where
67        S: Serializer,
68    {
69        let mut map = serializer.serialize_map(Some(3))?;
70        map.serialize_entry("type", "Annotation")?;
71        map.serialize_entry("predicate", &self.predicate)?;
72        map.serialize_entry("object", &self.object)?;
73        map.end()
74    }
75}
76
77impl<'de> Deserialize<'de> for Annotation {
78    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
79    where
80        D: serde::Deserializer<'de>,
81    {
82        enum Field {
83            Type,
84            Predicate,
85            Object,
86        }
87
88        impl<'de> Deserialize<'de> for Field {
89            fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
90            where
91                D: serde::Deserializer<'de>,
92            {
93                struct FieldVisitor;
94
95                impl Visitor<'_> for FieldVisitor {
96                    type Value = Field;
97
98                    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
99                        formatter.write_str("`type` or `predicate` or `object` for annotation")
100                    }
101
102                    fn visit_str<E>(self, value: &str) -> Result<Field, E>
103                    where
104                        E: de::Error,
105                    {
106                        match value {
107                            "type" => Ok(Field::Type),
108                            "predicate" => Ok(Field::Predicate),
109                            "object" => Ok(Field::Object),
110                            _ => Err(de::Error::unknown_field(value, FIELDS)),
111                        }
112                    }
113                }
114
115                deserializer.deserialize_identifier(FieldVisitor)
116            }
117        }
118
119        struct AnnotationVisitor;
120
121        impl<'de> Visitor<'de> for AnnotationVisitor {
122            type Value = Annotation;
123
124            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
125                formatter.write_str("struct Annotation")
126            }
127
128            fn visit_map<V>(self, mut map: V) -> Result<Annotation, V::Error>
129            where
130                V: MapAccess<'de>,
131            {
132                let mut type_: Option<String> = None;
133                let mut predicate: Option<IriRef> = None;
134                let mut object: Option<ObjectValue> = None;
135                while let Some(key) = map.next_key()? {
136                    match key {
137                        Field::Predicate => {
138                            if predicate.is_some() {
139                                return Err(de::Error::duplicate_field("predicate"));
140                            }
141                            let iri: IriRef = map.next_value()?;
142                            predicate = Some(iri);
143                        }
144                        Field::Type => {
145                            if type_.is_some() {
146                                return Err(de::Error::duplicate_field("type"));
147                            }
148                            let value: String = map.next_value()?;
149                            if value != "Annotation" {
150                                return Err(de::Error::custom(format!(
151                                    "Expected type `Annotation`, found: {value}"
152                                )));
153                            }
154                            type_ = Some("Annotation".to_string());
155                        }
156                        Field::Object => {
157                            if object.is_some() {
158                                return Err(de::Error::duplicate_field("object"));
159                            }
160                            object = Some(map.next_value()?);
161                        }
162                    }
163                }
164                match (predicate, object) {
165                    (None, None) => {
166                        Err(de::Error::custom("Missing fields `predicate` and `object`"))
167                    }
168                    (Some(_), None) => Err(de::Error::custom("Missing field `object`")),
169                    (None, Some(_)) => Err(de::Error::custom("Missing field `predicate`")),
170                    (Some(predicate), Some(object)) => Ok(Annotation { predicate, object }),
171                }
172            }
173        }
174
175        const FIELDS: &[&str] = &["type", "predicate", "object"];
176        deserializer.deserialize_struct("Annotation", FIELDS, AnnotationVisitor)
177    }
178}