Skip to main content

linked_data/impl/
xsd.rs

1use crate::{
2	DeserializeLinkedData, LinkedDataDeserializer, LinkedDataSerializer, SerializeLinkedData, de,
3};
4use rdf_syntax::{CowGroundTerm, CowLiteral, CowLiteralType, CowTerm};
5use std::borrow::Cow;
6use xsd_types::{XSD_STRING, XsdFromStr};
7
8impl<R: Clone + Ord> DeserializeLinkedData<R> for String {
9	fn deserialize_rdf<D>(mut deserializer: D, _: Option<&R>) -> Result<Self, D::Error>
10	where
11		D: LinkedDataDeserializer<R>,
12	{
13		let this = deserializer
14			.deserialize_resource(None)?
15			.ok_or_else(|| de::Error::missing_resource())?;
16
17		for term in deserializer.terms_of(&this)? {
18			if let CowTerm::Ground(CowGroundTerm::Literal(literal)) = term? {
19				if literal.r#type == XSD_STRING {
20					return Ok(literal.value.into_owned());
21				}
22			}
23		}
24
25		Err(de::Error::custom("no valid lexical representation"))
26	}
27}
28
29/// Implements [`SerializeLinkedData`] and [`DeserializeLinkedData`] for XSD
30/// value types, as a literal of the given datatype.
31///
32/// The types must implement [`XsdValue`](xsd_types::XsdValue), whose `Display`
33/// implementation writes the canonical lexical form, and [`XsdFromStr`].
34macro_rules! serde_xsd_datatype {
35	($($ty:ty: $datatype:ident),* $(,)?) => {
36		$(
37			impl<R: Clone + Ord> SerializeLinkedData<R> for $ty {
38				fn serialize_rdf<S>(
39					&self,
40					mut serializer: S,
41					_graph: Option<&R>,
42				) -> Result<S::Ok, S::Error>
43				where
44					S: LinkedDataSerializer<R>,
45				{
46					let this = serializer.interpret(Some(
47						CowLiteral::new(
48							Cow::Owned(self.to_string()),
49							CowLiteralType::Any(Cow::Borrowed(xsd_types::$datatype)),
50						)
51						.into(),
52					))?;
53					serializer.serialize_resource(Some(this))?;
54					serializer.end()
55				}
56			}
57
58			impl<R: Clone + Ord> DeserializeLinkedData<R> for $ty {
59				fn deserialize_rdf<D>(mut deserializer: D, _: Option<&R>) -> Result<Self, D::Error>
60				where
61					D: LinkedDataDeserializer<R>,
62				{
63					let this = deserializer
64						.deserialize_resource(None)?
65						.ok_or_else(|| de::Error::missing_resource())?;
66
67					for term in deserializer.terms_of(&this)? {
68						if let CowTerm::Ground(CowGroundTerm::Literal(literal)) = term? {
69							if literal.r#type == xsd_types::$datatype {
70								if let Ok(value) = <$ty as XsdFromStr>::xsd_from_str(&literal.value) {
71									return Ok(value);
72								}
73							}
74						}
75					}
76
77					Err(de::Error::custom("no valid lexical representation"))
78				}
79			}
80		)*
81	};
82}
83
84// `xsd_types::XsdString` (`String`) and `xsd_types::XsdAnyUriBuf` (`IriBuf`)
85// are not listed here: they are aliases of types implemented elsewhere.
86serde_xsd_datatype! {
87	// Boolean.
88	xsd_types::XsdBoolean: XSD_BOOLEAN,
89
90	// Numbers.
91	xsd_types::XsdFloat: XSD_FLOAT,
92	xsd_types::XsdDouble: XSD_DOUBLE,
93	xsd_types::XsdDecimal: XSD_DECIMAL,
94	xsd_types::XsdInteger: XSD_INTEGER,
95	xsd_types::XsdNonPositiveInteger: XSD_NON_POSITIVE_INTEGER,
96	xsd_types::XsdNegativeInteger: XSD_NEGATIVE_INTEGER,
97	xsd_types::XsdNonNegativeInteger: XSD_NON_NEGATIVE_INTEGER,
98	xsd_types::XsdPositiveInteger: XSD_POSITIVE_INTEGER,
99	xsd_types::XsdUnsignedByte: XSD_UNSIGNED_BYTE,
100	xsd_types::XsdUnsignedShort: XSD_UNSIGNED_SHORT,
101	xsd_types::XsdUnsignedInt: XSD_UNSIGNED_INT,
102	xsd_types::XsdUnsignedLong: XSD_UNSIGNED_LONG,
103	xsd_types::XsdByte: XSD_BYTE,
104	xsd_types::XsdShort: XSD_SHORT,
105	xsd_types::XsdInt: XSD_INT,
106	xsd_types::XsdLong: XSD_LONG,
107
108	// Strings.
109	xsd_types::XsdNormalizedString: XSD_NORMALIZED_STRING,
110	xsd_types::XsdTokenBuf: XSD_TOKEN,
111	xsd_types::XsdLanguageBuf: XSD_LANGUAGE,
112	xsd_types::XsdNameBuf: XSD_NAME,
113	xsd_types::XsdNCNameBuf: XSD_NC_NAME,
114	xsd_types::XsdIdBuf: XSD_ID,
115	xsd_types::XsdIdRefBuf: XSD_IDREF,
116	xsd_types::XsdNMTokenBuf: XSD_NMTOKEN,
117	xsd_types::XsdQNameBuf: XSD_Q_NAME,
118
119	// Durations, dates and times.
120	xsd_types::XsdDuration: XSD_DURATION,
121	xsd_types::XsdDayTimeDuration: XSD_DAY_TIME_DURATION,
122	xsd_types::XsdYearMonthDuration: XSD_YEAR_MONTH_DURATION,
123	xsd_types::XsdDateTime: XSD_DATE_TIME,
124	xsd_types::XsdDateTimeStamp: XSD_DATE_TIME_STAMP,
125	xsd_types::XsdTime: XSD_TIME,
126	xsd_types::XsdDate: XSD_DATE,
127	xsd_types::XsdGYearMonth: XSD_G_YEAR_MONTH,
128	xsd_types::XsdGYear: XSD_G_YEAR,
129	xsd_types::XsdGMonthDay: XSD_G_MONTH_DAY,
130	xsd_types::XsdGDay: XSD_G_DAY,
131	xsd_types::XsdGMonth: XSD_G_MONTH,
132
133	// Binary data.
134	xsd_types::XsdBase64BinaryBuf: XSD_BASE64_BINARY,
135	xsd_types::XsdHexBinaryBuf: XSD_HEX_BINARY,
136}
137
138impl<R: Clone + Ord> SerializeLinkedData<R> for bool {
139	fn serialize_rdf<S>(&self, serializer: S, graph: Option<&R>) -> Result<S::Ok, S::Error>
140	where
141		S: LinkedDataSerializer<R>,
142	{
143		xsd_types::XsdBoolean(*self).serialize_rdf(serializer, graph)
144	}
145}
146
147impl<R: Clone + Ord> DeserializeLinkedData<R> for bool {
148	fn deserialize_rdf<D>(deserializer: D, graph: Option<&R>) -> Result<Self, D::Error>
149	where
150		D: LinkedDataDeserializer<R>,
151	{
152		xsd_types::XsdBoolean::deserialize_rdf(deserializer, graph).map(Into::into)
153	}
154}