Skip to main content

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::{object::Literal, Value};
8
9impl<V: Vocabulary, I: Interpretation> LinkedDataResource<I, V> for Value<V::Iri> {
10	fn interpretation(
11		&self,
12		vocabulary: &mut V,
13		_interpretation: &mut I,
14	) -> ResourceInterpretation<I, V> {
15		let term = match self {
16			Self::Literal(l, ty) => match l {
17				Literal::Null => CowRdfTerm::Owned(Term::Literal(RdfLiteral::Xsd(
18					xsd_types::Value::String("null".to_string()),
19				))),
20				Literal::Boolean(b) => CowRdfTerm::Owned(Term::Literal(RdfLiteral::Xsd(
21					xsd_types::Value::Boolean((*b).into()),
22				))),
23				Literal::Number(n) => match ty {
24					Some(ty) => match typed_number_interpretation(vocabulary, ty, n) {
25						Some(value) => CowRdfTerm::Owned(Term::Literal(RdfLiteral::Xsd(value))),
26						None => CowRdfTerm::Borrowed(Term::Literal(RdfLiteralRef::Any(
27							n.as_str(),
28							LiteralTypeRef::Any(ty),
29						))),
30					},
31					None => {
32						let value = match n.as_i64() {
33							Some(i) => xsd_types::Value::Integer(i.into()),
34							None => xsd_types::Value::Double(n.as_f64_lossy().into()),
35						};
36
37						CowRdfTerm::Owned(Term::Literal(RdfLiteral::Xsd(value)))
38					}
39				},
40				Literal::String(s) => CowRdfTerm::Borrowed(Term::Literal(match ty {
41					Some(ty) => RdfLiteralRef::Any(s.as_str(), LiteralTypeRef::Any(ty)),
42					None => RdfLiteralRef::Xsd(xsd_types::ValueRef::String(s)),
43				})),
44			},
45			Self::LangString(s) => match s.language().and_then(|l| l.as_well_formed()) {
46				Some(tag) => CowRdfTerm::Owned(Term::Literal(RdfLiteral::Any(
47					s.as_str().to_owned(),
48					rdf_types::LiteralType::LangString(tag.to_owned()),
49				))),
50				None => CowRdfTerm::Borrowed(Term::Literal(RdfLiteralRef::Xsd(
51					xsd_types::ValueRef::String(s.as_str()),
52				))),
53			},
54			Self::Json(json) => CowRdfTerm::Borrowed(Term::Literal(RdfLiteralRef::Json(json))),
55		};
56
57		ResourceInterpretation::Uninterpreted(Some(term))
58	}
59}
60
61fn typed_number_interpretation<V: Vocabulary>(
62	vocabulary: &V,
63	ty: &V::Iri,
64	n: &json_syntax::Number,
65) -> Option<xsd_types::Value> {
66	let iri = vocabulary.iri(ty)?;
67	let xsd_ty = xsd_types::Datatype::from_iri(iri)?;
68	xsd_ty.parse(n).ok()
69}
70
71impl<T, V: Vocabulary, I: Interpretation> LinkedDataSubject<I, V> for Value<T> {
72	fn visit_subject<S>(&self, visitor: S) -> Result<S::Ok, S::Error>
73	where
74		S: linked_data::SubjectVisitor<I, V>,
75	{
76		visitor.end()
77	}
78}
79
80impl<T, V: Vocabulary, I: Interpretation> LinkedDataPredicateObjects<I, V> for Value<T> {
81	fn visit_objects<S>(&self, visitor: S) -> Result<S::Ok, S::Error>
82	where
83		S: linked_data::PredicateObjectsVisitor<I, V>,
84	{
85		visitor.end()
86	}
87}
88
89impl<V: Vocabulary, I: Interpretation> LinkedDataGraph<I, V> for Value<V::Iri> {
90	fn visit_graph<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
91	where
92		S: linked_data::GraphVisitor<I, V>,
93	{
94		visitor.subject(self)?;
95		visitor.end()
96	}
97}
98
99impl<V: Vocabulary, I: Interpretation> LinkedData<I, V> for Value<V::Iri> {
100	fn visit<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
101	where
102		S: linked_data::Visitor<I, V>,
103	{
104		visitor.default_graph(self)?;
105		visitor.end()
106	}
107}