json_ld_core/deserialization/object/
value.rs

1use 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}