json_ld_core/deserialization/object/
value.rs1use linked_data::{
2 xsd_types, CowRdfTerm, LinkedData, LinkedDataGraph, LinkedDataPredicateObjects,
3 LinkedDataResource, LinkedDataSubject, RdfLiteral, RdfLiteralRef, ResourceInterpretation,
4};
5use rdf_types::{Interpretation, LiteralTypeRef, Term, Vocabulary};
6
7use crate::{
8 object::Literal,
9 rdf::{XSD_DOUBLE, XSD_INTEGER},
10 Value,
11};
12
13impl<V: Vocabulary, I: Interpretation> LinkedDataResource<I, V> for Value<V::Iri> {
14 fn interpretation(
15 &self,
16 vocabulary: &mut V,
17 _interpretation: &mut I,
18 ) -> ResourceInterpretation<I, V> {
19 let term = match self {
20 Self::Literal(l, ty) => match l {
21 Literal::Null => CowRdfTerm::Owned(Term::Literal(RdfLiteral::Xsd(
22 xsd_types::Value::String("null".to_string()),
23 ))),
24 Literal::Boolean(b) => CowRdfTerm::Owned(Term::Literal(RdfLiteral::Xsd(
25 xsd_types::Value::Boolean((*b).into()),
26 ))),
27 Literal::Number(n) => {
28 #[derive(Clone, Copy, Default, PartialEq)]
29 enum NumericType {
30 Integer,
31 Double,
32 #[default]
33 Unknown,
34 }
35
36 impl NumericType {
37 pub fn matches(self, other: Self) -> bool {
38 self == other || self == Self::Unknown
39 }
40 }
41
42 let ty = ty
43 .as_ref()
44 .and_then(|t| vocabulary.iri(t))
45 .map(|iri| {
46 if iri == XSD_INTEGER {
47 NumericType::Integer
48 } else if iri == XSD_DOUBLE {
49 NumericType::Double
50 } else {
51 NumericType::Unknown
52 }
53 })
54 .unwrap_or_default();
55
56 let value = match n.as_i64() {
57 Some(i) if ty.matches(NumericType::Integer) => {
58 xsd_types::Value::Integer(i.into())
59 }
60 _ => xsd_types::Value::Double(n.as_f64_lossy().into()),
61 };
62
63 CowRdfTerm::Owned(Term::Literal(RdfLiteral::Xsd(value)))
64 }
65 Literal::String(s) => CowRdfTerm::Borrowed(Term::Literal(match ty {
66 Some(ty) => RdfLiteralRef::Any(s.as_str(), LiteralTypeRef::Any(ty)),
67 None => RdfLiteralRef::Xsd(xsd_types::ValueRef::String(s)),
68 })),
69 },
70 Self::LangString(s) => match s.language().and_then(|l| l.as_well_formed()) {
71 Some(tag) => CowRdfTerm::Owned(Term::Literal(RdfLiteral::Any(
72 s.as_str().to_owned(),
73 rdf_types::LiteralType::LangString(tag.to_owned()),
74 ))),
75 None => CowRdfTerm::Borrowed(Term::Literal(RdfLiteralRef::Xsd(
76 xsd_types::ValueRef::String(s.as_str()),
77 ))),
78 },
79 Self::Json(json) => CowRdfTerm::Borrowed(Term::Literal(RdfLiteralRef::Json(json))),
80 };
81
82 ResourceInterpretation::Uninterpreted(Some(term))
83 }
84}
85
86impl<T, V: Vocabulary, I: Interpretation> LinkedDataSubject<I, V> for Value<T> {
87 fn visit_subject<S>(&self, visitor: S) -> Result<S::Ok, S::Error>
88 where
89 S: linked_data::SubjectVisitor<I, V>,
90 {
91 visitor.end()
92 }
93}
94
95impl<T, V: Vocabulary, I: Interpretation> LinkedDataPredicateObjects<I, V> for Value<T> {
96 fn visit_objects<S>(&self, visitor: S) -> Result<S::Ok, S::Error>
97 where
98 S: linked_data::PredicateObjectsVisitor<I, V>,
99 {
100 visitor.end()
101 }
102}
103
104impl<V: Vocabulary, I: Interpretation> LinkedDataGraph<I, V> for Value<V::Iri> {
105 fn visit_graph<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
106 where
107 S: linked_data::GraphVisitor<I, V>,
108 {
109 visitor.subject(self)?;
110 visitor.end()
111 }
112}
113
114impl<V: Vocabulary, I: Interpretation> LinkedData<I, V> for Value<V::Iri> {
115 fn visit<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
116 where
117 S: linked_data::Visitor<I, V>,
118 {
119 visitor.default_graph(self)?;
120 visitor.end()
121 }
122}