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#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
20#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
21pub struct Literal<I = IriBuf> {
22 pub value: String,
24
25 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#[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 pub value: &'a str,
219
220 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}