shex_ast/ast/
object_value.rs

1use iri_s::{IriS, IriSError};
2use prefixmap::{Deref, DerefError, IriRef};
3use rust_decimal::Decimal;
4use serde::de::Unexpected;
5use serde::ser::SerializeMap;
6use serde::{
7    de::{self, MapAccess, Visitor},
8    Deserialize, Serialize, Serializer,
9};
10use srdf::lang::Lang;
11use srdf::literal::Literal;
12use srdf::numeric_literal::NumericLiteral;
13use std::fmt;
14use std::{result, str::FromStr};
15
16use super::{BOOLEAN_STR, DECIMAL_STR, DOUBLE_STR, INTEGER_STR};
17
18#[derive(Debug, PartialEq, Clone)]
19pub enum ObjectValue {
20    IriRef(IriRef),
21    Literal(Literal),
22}
23
24impl ObjectValue {
25    pub fn integer(n: isize) -> ObjectValue {
26        ObjectValue::Literal(Literal::integer(n))
27    }
28
29    pub fn double(n: f64) -> ObjectValue {
30        ObjectValue::Literal(Literal::double(n))
31    }
32
33    pub fn decimal(n: Decimal) -> ObjectValue {
34        ObjectValue::Literal(Literal::decimal(n))
35    }
36
37    pub fn bool(b: bool) -> ObjectValue {
38        ObjectValue::Literal(Literal::boolean(b))
39    }
40
41    pub fn literal(lit: Literal) -> ObjectValue {
42        ObjectValue::Literal(lit)
43    }
44
45    pub fn datatype_literal(lexical_form: &str, datatype: &IriRef) -> ObjectValue {
46        ObjectValue::Literal(Literal::lit_datatype(lexical_form, datatype))
47    }
48
49    pub fn lexical_form(&self) -> String {
50        match self {
51            ObjectValue::IriRef(iri) => iri.to_string(),
52            ObjectValue::Literal(lit) => lit.lexical_form(),
53        }
54    }
55
56    pub fn iri(iri: IriS) -> Self {
57        ObjectValue::IriRef(IriRef::iri(iri))
58    }
59
60    pub fn iri_ref(iri: IriRef) -> Self {
61        ObjectValue::IriRef(iri)
62    }
63
64    pub fn prefixed(alias: &str, local: &str) -> Self {
65        ObjectValue::IriRef(IriRef::prefixed(alias, local))
66    }
67
68    pub fn str(str: &str) -> Self {
69        ObjectValue::Literal(Literal::str(str))
70    }
71}
72
73impl Deref for ObjectValue {
74    fn deref(
75        &self,
76        base: &Option<iri_s::IriS>,
77        prefixmap: &Option<prefixmap::PrefixMap>,
78    ) -> Result<Self, DerefError> {
79        match self {
80            ObjectValue::IriRef(iri_ref) => {
81                let new_iri_ref = iri_ref.deref(base, prefixmap)?;
82                Ok(ObjectValue::IriRef(new_iri_ref))
83            }
84            ObjectValue::Literal(lit) => {
85                let new_lit = lit.deref(base, prefixmap)?;
86                Ok(ObjectValue::Literal(new_lit))
87            }
88        }
89    }
90}
91
92impl FromStr for ObjectValue {
93    type Err = IriSError;
94
95    fn from_str(s: &str) -> Result<Self, Self::Err> {
96        let iri_ref = IriRef::try_from(s)?;
97        Ok(ObjectValue::IriRef(iri_ref))
98    }
99}
100
101impl Serialize for ObjectValue {
102    fn serialize<S>(&self, serializer: S) -> result::Result<S::Ok, S::Error>
103    where
104        S: Serializer,
105    {
106        match self {
107            ObjectValue::Literal(Literal::BooleanLiteral(value)) => {
108                let mut map = serializer.serialize_map(Some(2))?;
109                map.serialize_entry("type", BOOLEAN_STR)?;
110                let value_str = if *value { "true" } else { "false" };
111                map.serialize_entry("value", value_str)?;
112                map.end()
113            }
114            ObjectValue::Literal(Literal::NumericLiteral(num)) => {
115                let mut map = serializer.serialize_map(Some(2))?;
116                map.serialize_entry("type", get_type_str(num))?;
117                map.serialize_entry("value", &num.to_string())?;
118                map.end()
119            }
120            ObjectValue::IriRef(iri) => serializer.serialize_str(iri.to_string().as_str()),
121            ObjectValue::Literal(Literal::StringLiteral { lexical_form, lang }) => {
122                let mut map = serializer.serialize_map(Some(3))?;
123                if let Some(lan) = lang {
124                    map.serialize_entry("language", &Some(lan))?;
125                }
126                map.serialize_entry("value", lexical_form)?;
127                map.end()
128            }
129            ObjectValue::Literal(Literal::DatatypeLiteral {
130                lexical_form,
131                datatype,
132            }) => {
133                let mut map = serializer.serialize_map(Some(2))?;
134                map.serialize_entry("type", datatype)?;
135                map.serialize_entry("value", lexical_form)?;
136                map.end()
137            }
138        }
139    }
140}
141
142fn get_type_str(n: &NumericLiteral) -> &str {
143    match n {
144        NumericLiteral::Integer(_) => INTEGER_STR,
145        NumericLiteral::Double(_) => DOUBLE_STR,
146        NumericLiteral::Decimal(_) => DECIMAL_STR,
147    }
148}
149
150#[derive(Debug, PartialEq)]
151enum ObjectValueType {
152    Boolean,
153    Integer,
154    Decimal,
155    Double,
156    Other(IriRef),
157}
158
159impl ObjectValueType {
160    fn parse(s: &str) -> Result<ObjectValueType, IriSError> {
161        match s {
162            BOOLEAN_STR => Ok(ObjectValueType::Boolean),
163            DECIMAL_STR => Ok(ObjectValueType::Decimal),
164            DOUBLE_STR => Ok(ObjectValueType::Double),
165            INTEGER_STR => Ok(ObjectValueType::Integer),
166            other => {
167                let iri = FromStr::from_str(other)?;
168                Ok(ObjectValueType::Other(iri))
169            }
170        }
171    }
172}
173
174impl<'de> Deserialize<'de> for ObjectValue {
175    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
176    where
177        D: serde::Deserializer<'de>,
178    {
179        enum Field {
180            Type,
181            Value,
182            Language,
183            LanguageTag,
184        }
185
186        impl<'de> Deserialize<'de> for Field {
187            fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
188            where
189                D: serde::Deserializer<'de>,
190            {
191                struct FieldVisitor;
192
193                impl Visitor<'_> for FieldVisitor {
194                    type Value = Field;
195
196                    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
197                        formatter.write_str("`value` for object value")
198                    }
199
200                    fn visit_str<E>(self, value: &str) -> Result<Field, E>
201                    where
202                        E: de::Error,
203                    {
204                        match value {
205                            "type" => Ok(Field::Type),
206                            "value" => Ok(Field::Value),
207                            "language" => Ok(Field::Language),
208                            "languageTag" => Ok(Field::LanguageTag),
209                            _ => Err(de::Error::unknown_field(value, FIELDS)),
210                        }
211                    }
212                }
213
214                deserializer.deserialize_identifier(FieldVisitor)
215            }
216        }
217
218        struct ObjectValueVisitor;
219
220        impl<'de> Visitor<'de> for ObjectValueVisitor {
221            type Value = ObjectValue;
222
223            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
224                formatter.write_str("object value")
225            }
226
227            fn visit_map<V>(self, mut map: V) -> Result<ObjectValue, V::Error>
228            where
229                V: MapAccess<'de>,
230            {
231                let mut value: Option<String> = None;
232                let mut type_: Option<ObjectValueType> = None;
233                let mut language: Option<String> = None;
234                let mut language_tag: Option<String> = None;
235
236                while let Some(key) = map.next_key()? {
237                    match key {
238                        Field::Type => {
239                            if type_.is_some() {
240                                return Err(de::Error::duplicate_field("type"));
241                            }
242                            let value: String = map.next_value()?;
243
244                            let parsed_type_ =
245                                ObjectValueType::parse(value.as_str()).map_err(|e| {
246                                    de::Error::custom(format!(
247                                    "Error parsing ValueSetValue type, found: {value}. Error: {e}"
248                                ))
249                                })?;
250                            type_ = Some(parsed_type_);
251                        }
252                        Field::Value => {
253                            if value.is_some() {
254                                return Err(de::Error::duplicate_field("value"));
255                            }
256                            value = Some(map.next_value()?);
257                        }
258                        Field::Language => {
259                            if language.is_some() {
260                                return Err(de::Error::duplicate_field("language"));
261                            }
262                            language = Some(map.next_value()?);
263                        }
264                        Field::LanguageTag => {
265                            if language_tag.is_some() {
266                                return Err(de::Error::duplicate_field("languageTag"));
267                            }
268                            language_tag = Some(map.next_value()?);
269                        }
270                    }
271                }
272                match type_ {
273                    Some(ObjectValueType::Boolean) => match value {
274                        Some(s) => match s.as_str() {
275                            "false" => Ok(ObjectValue::bool(false)),
276                            "true" => Ok(ObjectValue::bool(true)),
277                            _ => Err(de::Error::invalid_value(Unexpected::Str(&s), &self)),
278                        },
279                        None => Err(de::Error::missing_field("value")),
280                    },
281                    Some(ObjectValueType::Decimal) => match value {
282                        Some(s) => {
283                            let n = Decimal::from_str(&s).map_err(|e| {
284                                de::Error::custom(format!(
285                                    "Can't parse value {s} as decimal: Error {e}"
286                                ))
287                            })?;
288                            Ok(ObjectValue::decimal(n))
289                        }
290                        None => Err(de::Error::missing_field("value")),
291                    },
292                    Some(ObjectValueType::Double) => match value {
293                        Some(s) => {
294                            let n = f64::from_str(&s).map_err(|e| {
295                                de::Error::custom(format!(
296                                    "Can't parse value {s} as double: Error {e}"
297                                ))
298                            })?;
299                            Ok(ObjectValue::double(n))
300                        }
301                        None => Err(de::Error::missing_field("value")),
302                    },
303                    Some(ObjectValueType::Integer) => match value {
304                        Some(s) => {
305                            let n = isize::from_str(&s).map_err(|e| {
306                                de::Error::custom(format!(
307                                    "Can't parse value {s} as integer: Error {e}"
308                                ))
309                            })?;
310                            Ok(ObjectValue::integer(n))
311                        }
312                        None => Err(de::Error::missing_field("value")),
313                    },
314                    Some(ObjectValueType::Other(iri)) => match value {
315                        Some(v) => match language_tag {
316                            Some(lang) => Ok(ObjectValue::Literal(Literal::StringLiteral {
317                                lexical_form: v,
318                                lang: Some(Lang::new_unchecked(&lang)),
319                            })),
320                            None => Ok(ObjectValue::datatype_literal(&v, &iri)),
321                        },
322                        None => Err(de::Error::missing_field("value")),
323                    },
324                    None => match value {
325                        Some(lexical_form) => match language {
326                            Some(language) => Ok(ObjectValue::Literal(Literal::StringLiteral {
327                                lexical_form,
328                                lang: Some(Lang::new_unchecked(&language)),
329                            })),
330                            None => Ok(ObjectValue::Literal(Literal::StringLiteral {
331                                lexical_form,
332                                lang: None,
333                            })),
334                        },
335                        None => Err(de::Error::missing_field("value")),
336                    },
337                }
338            }
339
340            fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
341            where
342                E: de::Error,
343            {
344                let iri_ref = IriRef::from_str(s).map_err(|e| {
345                    de::Error::custom(format!("Cannot convert string `{s}` to Iri: {e}"))
346                })?;
347                Ok(ObjectValue::IriRef(iri_ref))
348            }
349        }
350
351        const FIELDS: &[&str] = &["value", "type", "languageTag"];
352        deserializer.deserialize_any(ObjectValueVisitor)
353    }
354}