rdf_types/literal/
mod.rs

1use crate::vocabulary::{
2	EmbedIntoVocabulary, EmbeddedIntoVocabulary, ExtractFromVocabulary, ExtractedFromVocabulary,
3	IriVocabulary, IriVocabularyMut, LiteralVocabularyMut,
4};
5use crate::{IsXsdStringIri, RdfDisplay};
6use educe::Educe;
7use iref::IriBuf;
8use langtag::LangTag;
9use std::borrow::Borrow;
10use std::fmt;
11
12#[cfg(feature = "contextual")]
13use contextual::DisplayWithContext;
14
15mod r#type;
16pub use r#type::*;
17
18/// RDF Literal.
19#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
20#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
21pub struct Literal<I = IriBuf> {
22	/// Literal value.
23	pub value: String,
24
25	/// Literal type.
26	pub type_: LiteralType<I>,
27}
28
29impl<I> Literal<I> {
30	pub fn new(value: String, type_: LiteralType<I>) -> Self {
31		Self { value, type_ }
32	}
33
34	pub fn as_type(&self) -> &LiteralType<I> {
35		&self.type_
36	}
37
38	pub fn as_type_mut(&mut self) -> &mut LiteralType<I> {
39		&mut self.type_
40	}
41
42	pub fn into_type(self) -> LiteralType<I> {
43		self.type_
44	}
45
46	pub fn as_value(&self) -> &String {
47		&self.value
48	}
49
50	pub fn as_value_mut(&mut self) -> &mut String {
51		&mut self.value
52	}
53
54	pub fn into_value(self) -> String {
55		self.value
56	}
57
58	pub fn into_parts(self) -> (String, LiteralType<I>) {
59		(self.value, self.type_)
60	}
61
62	pub fn as_str(&self) -> &str {
63		self.value.as_ref()
64	}
65
66	pub fn as_bytes(&self) -> &[u8] {
67		self.value.as_ref()
68	}
69
70	pub fn is_lang_string(&self) -> bool {
71		self.type_.is_lang_string()
72	}
73
74	pub fn lang_tag(&self) -> Option<&LangTag> {
75		self.type_.lang_tag()
76	}
77
78	pub fn insert_type_into_vocabulary<V>(self, vocabulary: &mut V) -> Literal<I::Embedded>
79	where
80		I: EmbedIntoVocabulary<V>,
81	{
82		Literal {
83			value: self.value,
84			type_: self.type_.embed_into_vocabulary(vocabulary),
85		}
86	}
87
88	pub fn inserted_type_into_vocabulary<V>(&self, vocabulary: &mut V) -> Literal<I::Embedded>
89	where
90		I: EmbeddedIntoVocabulary<V>,
91	{
92		Literal {
93			value: self.value.clone(),
94			type_: self.type_.embedded_into_vocabulary(vocabulary),
95		}
96	}
97
98	pub fn as_ref(&self) -> LiteralRef<I> {
99		LiteralRef::new(&self.value, self.type_.as_ref())
100	}
101}
102
103impl<'a, I: PartialEq> PartialEq<LiteralRef<'a, I>> for Literal<I> {
104	fn eq(&self, other: &LiteralRef<'a, I>) -> bool {
105		self.type_ == other.type_ && self.value == other.value
106	}
107}
108
109impl<V: IriVocabularyMut + LiteralVocabularyMut> EmbedIntoVocabulary<V> for Literal {
110	type Embedded = V::Literal;
111
112	fn embed_into_vocabulary(self, vocabulary: &mut V) -> Self::Embedded {
113		let l = self.insert_type_into_vocabulary(vocabulary);
114		vocabulary.insert_owned_literal(l)
115	}
116}
117
118impl<V: IriVocabularyMut + LiteralVocabularyMut> EmbeddedIntoVocabulary<V> for Literal {
119	type Embedded = V::Literal;
120
121	fn embedded_into_vocabulary(&self, vocabulary: &mut V) -> Self::Embedded {
122		let l = self.inserted_type_into_vocabulary(vocabulary);
123		vocabulary.insert_owned_literal(l)
124	}
125}
126
127impl<V: IriVocabulary> ExtractFromVocabulary<V> for Literal<V::Iri> {
128	type Extracted = Literal;
129
130	fn extract_from_vocabulary(self, vocabulary: &V) -> Self::Extracted {
131		let (value, type_) = self.into_parts();
132		Literal::new(value, type_.extract_from_vocabulary(vocabulary))
133	}
134}
135
136impl<V: IriVocabulary> ExtractedFromVocabulary<V> for Literal<V::Iri> {
137	type Extracted = Literal;
138
139	fn extracted_from_vocabulary(&self, vocabulary: &V) -> Self::Extracted {
140		Literal::new(
141			self.value.clone(),
142			self.type_.extracted_from_vocabulary(vocabulary),
143		)
144	}
145}
146
147impl<I> Borrow<str> for Literal<I> {
148	fn borrow(&self) -> &str {
149		self.as_str()
150	}
151}
152
153impl<I> AsRef<str> for Literal<I> {
154	fn as_ref(&self) -> &str {
155		self.as_str()
156	}
157}
158
159impl fmt::Display for Literal {
160	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
161		self.value.rdf_fmt(f)?;
162		if self.type_.is_xsd_string() {
163			Ok(())
164		} else {
165			self.type_.rdf_fmt(f)
166		}
167	}
168}
169
170impl<I: RdfDisplay + IsXsdStringIri> RdfDisplay for Literal<I> {
171	fn rdf_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
172		self.value.rdf_fmt(f)?;
173		if self.type_.is_xsd_string() {
174			Ok(())
175		} else {
176			self.type_.rdf_fmt(f)
177		}
178	}
179}
180
181#[cfg(feature = "contextual")]
182impl<V: crate::vocabulary::IriVocabulary> DisplayWithContext<V> for Literal<V::Iri>
183where
184	V::Iri: crate::RdfDisplayWithContext<V>,
185{
186	fn fmt_with(&self, vocabulary: &V, f: &mut fmt::Formatter) -> fmt::Result {
187		use crate::RdfDisplayWithContext;
188		self.value.rdf_fmt(f)?;
189		if self.type_.is_xsd_string_with(vocabulary) {
190			Ok(())
191		} else {
192			self.type_.rdf_fmt_with(vocabulary, f)
193		}
194	}
195}
196
197#[cfg(feature = "contextual")]
198impl<V: crate::vocabulary::IriVocabulary> crate::RdfDisplayWithContext<V> for Literal<V::Iri>
199where
200	V::Iri: crate::RdfDisplayWithContext<V>,
201{
202	fn rdf_fmt_with(&self, vocabulary: &V, f: &mut fmt::Formatter) -> fmt::Result {
203		self.value.rdf_fmt(f)?;
204		if self.type_.is_xsd_string_with(vocabulary) {
205			Ok(())
206		} else {
207			self.type_.rdf_fmt_with(vocabulary, f)
208		}
209	}
210}
211
212/// RDF Literal reference.
213#[derive(Educe, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
214#[educe(Clone, Copy)]
215#[cfg_attr(feature = "serde", derive(serde::Serialize))]
216pub struct LiteralRef<'a, I = IriBuf> {
217	/// Literal value.
218	pub value: &'a str,
219
220	/// Literal type.
221	pub type_: LiteralTypeRef<'a, I>,
222}
223
224impl<'a, I> LiteralRef<'a, I> {
225	pub fn new(value: &'a str, type_: LiteralTypeRef<'a, I>) -> Self {
226		Self { value, type_ }
227	}
228
229	pub fn as_type(&self) -> LiteralTypeRef<'a, I> {
230		self.type_
231	}
232
233	pub fn as_type_mut(&mut self) -> &mut LiteralTypeRef<'a, I> {
234		&mut self.type_
235	}
236
237	pub fn into_type(self) -> LiteralTypeRef<'a, I> {
238		self.type_
239	}
240
241	pub fn as_value(&self) -> &'a str {
242		self.value
243	}
244
245	pub fn into_value(self) -> &'a str {
246		self.value
247	}
248
249	pub fn into_parts(self) -> (&'a str, LiteralTypeRef<'a, I>) {
250		(self.value, self.type_)
251	}
252
253	pub fn as_str(&self) -> &'a str {
254		self.value
255	}
256
257	pub fn as_bytes(&self) -> &'a [u8] {
258		self.value.as_ref()
259	}
260
261	pub fn is_lang_string(&self) -> bool {
262		self.type_.is_lang_string()
263	}
264
265	pub fn lang_tag(&self) -> Option<&'a LangTag> {
266		self.type_.lang_tag()
267	}
268
269	pub fn insert_type_into_vocabulary<V>(self, vocabulary: &mut V) -> Literal<I::Embedded>
270	where
271		I: EmbeddedIntoVocabulary<V>,
272	{
273		Literal {
274			value: self.value.to_owned(),
275			type_: self.type_.embed_into_vocabulary(vocabulary),
276		}
277	}
278
279	pub fn inserted_type_into_vocabulary<V>(&self, vocabulary: &mut V) -> Literal<I::Embedded>
280	where
281		I: EmbeddedIntoVocabulary<V>,
282	{
283		Literal {
284			value: self.value.to_owned(),
285			type_: self.type_.embedded_into_vocabulary(vocabulary),
286		}
287	}
288}
289
290impl<I: ToOwned> LiteralRef<'_, I> {
291	pub fn into_owned(self) -> Literal<I::Owned> {
292		Literal::new(self.value.to_owned(), self.type_.into_owned())
293	}
294}
295
296impl<'a, I> LiteralRef<'a, I> {
297	pub fn cast_into_owned<J>(self) -> Literal<J>
298	where
299		&'a I: Into<J>,
300	{
301		Literal::new(self.value.to_owned(), self.type_.cast_into_owned())
302	}
303}
304
305impl<I: PartialEq> PartialEq<Literal<I>> for LiteralRef<'_, I> {
306	fn eq(&self, other: &Literal<I>) -> bool {
307		self.type_ == other.type_ && self.value == other.value
308	}
309}
310
311impl<V: LiteralVocabularyMut> EmbedIntoVocabulary<V> for LiteralRef<'_, V::Iri>
312where
313	V::Iri: Clone,
314{
315	type Embedded = V::Literal;
316
317	fn embed_into_vocabulary(self, vocabulary: &mut V) -> Self::Embedded {
318		vocabulary.insert_literal(self)
319	}
320}
321
322impl<V: LiteralVocabularyMut> EmbeddedIntoVocabulary<V> for LiteralRef<'_, V::Iri>
323where
324	V::Iri: Clone,
325{
326	type Embedded = V::Literal;
327
328	fn embedded_into_vocabulary(&self, vocabulary: &mut V) -> Self::Embedded {
329		vocabulary.insert_literal(*self)
330	}
331}
332
333impl<V: IriVocabulary> ExtractFromVocabulary<V> for LiteralRef<'_, V::Iri> {
334	type Extracted = Literal;
335
336	fn extract_from_vocabulary(self, vocabulary: &V) -> Self::Extracted {
337		let (value, type_) = self.into_parts();
338		Literal::new(value.to_owned(), type_.extract_from_vocabulary(vocabulary))
339	}
340}
341
342impl<V: IriVocabulary> ExtractedFromVocabulary<V> for LiteralRef<'_, V::Iri> {
343	type Extracted = Literal;
344
345	fn extracted_from_vocabulary(&self, vocabulary: &V) -> Self::Extracted {
346		Literal::new(
347			self.value.to_owned(),
348			self.type_.extracted_from_vocabulary(vocabulary),
349		)
350	}
351}
352
353impl<I> Borrow<str> for LiteralRef<'_, I> {
354	fn borrow(&self) -> &str {
355		self.as_str()
356	}
357}
358
359impl<I> AsRef<str> for LiteralRef<'_, I> {
360	fn as_ref(&self) -> &str {
361		self.as_str()
362	}
363}
364
365impl fmt::Display for LiteralRef<'_> {
366	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
367		self.value.rdf_fmt(f)?;
368		if self.type_.is_xsd_string() {
369			Ok(())
370		} else {
371			self.type_.rdf_fmt(f)
372		}
373	}
374}
375
376impl<I: RdfDisplay + IsXsdStringIri> RdfDisplay for LiteralRef<'_, I> {
377	fn rdf_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
378		self.value.rdf_fmt(f)?;
379		if self.type_.is_xsd_string() {
380			Ok(())
381		} else {
382			self.type_.rdf_fmt(f)
383		}
384	}
385}
386
387#[cfg(feature = "contextual")]
388impl<'a, V: crate::vocabulary::IriVocabulary> DisplayWithContext<V> for LiteralRef<'a, V::Iri>
389where
390	V::Iri: crate::RdfDisplayWithContext<V>,
391{
392	fn fmt_with(&self, vocabulary: &V, f: &mut fmt::Formatter) -> fmt::Result {
393		use crate::RdfDisplayWithContext;
394		self.value.rdf_fmt(f)?;
395		if self.type_.is_xsd_string_with(vocabulary) {
396			Ok(())
397		} else {
398			self.type_.rdf_fmt_with(vocabulary, f)
399		}
400	}
401}
402
403#[cfg(feature = "contextual")]
404impl<'a, V: crate::vocabulary::IriVocabulary> crate::RdfDisplayWithContext<V>
405	for LiteralRef<'a, V::Iri>
406where
407	V::Iri: crate::RdfDisplayWithContext<V>,
408{
409	fn rdf_fmt_with(&self, vocabulary: &V, f: &mut fmt::Formatter) -> fmt::Result {
410		self.value.rdf_fmt(f)?;
411		if self.type_.is_xsd_string_with(vocabulary) {
412			Ok(())
413		} else {
414			self.type_.rdf_fmt_with(vocabulary, f)
415		}
416	}
417}