json_ld/algorithms/deserialization/object/
value.rs1use json_syntax::{JsonNumberBuf, JsonPrint, JsonValue};
2use linked_data::{LinkedDataSerializer, SerializeLinkedData, ser::SerializeLinkedDataWith};
3use rdf_syntax::Iri;
4use rdf_syntax::{Literal, RDF_JSON, Term};
5use xsd_types::{
6 XSD_BOOLEAN, XSD_DOUBLE, XSD_INTEGER, XSD_STRING, XsdBoolean, XsdDouble, XsdFromStr,
7};
8
9use crate::JsonLdLenient;
10use crate::{JsonLdValue, object::value::JsonLdLiteralType};
11
12use super::super::RdfSerializationOptions;
13
14impl SerializeLinkedDataWith<RdfSerializationOptions> for JsonLdValue {
15 fn serialize_rdf_with<S>(
16 &self,
17 _opts: RdfSerializationOptions,
18 mut serializer: S,
19 _: Option<&Term>,
20 ) -> Result<S::Ok, S::Error>
21 where
22 S: LinkedDataSerializer<Term>,
23 {
24 let literal = match self {
25 Self::Literal(lit) => {
26 if lit.is_json() {
27 Literal::new(
28 lit.value.canonicalized().compact_print().to_string(),
29 RDF_JSON,
30 )
31 } else {
32 let ty = match &lit.type_ {
33 Some(JsonLdLiteralType::Iri(iri)) => iri.as_iri(),
34 _ => match &lit.value {
35 JsonValue::Null => XSD_STRING,
36 JsonValue::Boolean(_) => XSD_BOOLEAN,
37 JsonValue::Number(n) => {
38 let n = n.trimmed();
39 if n.has_decimal_point() || n.has_exponent() {
40 XSD_DOUBLE
41 } else {
42 XSD_INTEGER
43 }
44 }
45 JsonValue::String(_) => XSD_STRING,
46 _ => XSD_STRING,
47 },
48 };
49
50 match &lit.value {
51 JsonValue::Null => Literal::new("null", ty),
52 JsonValue::Boolean(b) => Literal::new(XsdBoolean(*b).to_string(), ty),
53 JsonValue::Number(n) => Literal::new(canonical_number(n, ty), ty),
54 JsonValue::String(s) => Literal::new(s.as_str(), ty),
55 other => {
56 Literal::new(other.canonicalized().compact_print().to_string(), ty)
57 }
58 }
59 }
60 }
61 Self::LangString(s) => match s.language() {
62 Some(lang) => match lang {
63 JsonLdLenient::Valid(tag) => Literal::new(s.as_str(), tag),
64 JsonLdLenient::Invalid(_) => return serializer.end(),
65 },
66 None => Literal::new(s.as_str(), XSD_STRING),
67 },
68 };
69
70 serializer.serialize_resource(Some(Term::literal(literal)))?;
71 serializer.end()
72 }
73}
74
75impl SerializeLinkedData for JsonLdValue {
76 fn serialize_rdf<S>(&self, serializer: S, graph: Option<&Term>) -> Result<S::Ok, S::Error>
77 where
78 S: LinkedDataSerializer<Term>,
79 {
80 self.serialize_rdf_with(RdfSerializationOptions::default(), serializer, graph)
81 }
82}
83
84fn canonical_number(n: &JsonNumberBuf, ty: &Iri) -> String {
85 let n = n.trimmed();
86
87 if (ty == XSD_DOUBLE || n.has_decimal_point() || n.has_exponent())
88 && let Ok(d) = XsdDouble::xsd_from_str(n)
89 {
90 return d.to_string();
91 }
92
93 n.to_string()
94}