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}