Skip to main content

rdfx/vocabulary/impl/indexed/
literal.rs

1use crate::vocabulary::{ExtractFromVocabulary, ExtractedFromVocabulary, LiteralVocabulary};
2use crate::{Literal, LiteralRef};
3
4/// Literal index.
5#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
6pub struct LiteralIndex(usize);
7
8impl From<usize> for LiteralIndex {
9    fn from(i: usize) -> Self {
10        Self(i)
11    }
12}
13
14impl From<LiteralIndex> for usize {
15    fn from(value: LiteralIndex) -> Self {
16        value.0
17    }
18}
19
20impl IndexedLiteral for LiteralIndex {
21    fn literal_index(&self) -> LiteralOrIndex<&'_ Literal> {
22        LiteralOrIndex::Index(self.0)
23    }
24
25    fn into_literal_index(self) -> LiteralOrIndex<Literal> {
26        LiteralOrIndex::Index(self.0)
27    }
28}
29
30impl<V> ExtractFromVocabulary<V> for LiteralIndex
31where
32    V: LiteralVocabulary<Literal = LiteralIndex>,
33{
34    type Extracted = Literal;
35
36    fn extract_from_vocabulary(self, vocabulary: &V) -> Self::Extracted {
37        vocabulary.owned_literal(self).unwrap()
38    }
39}
40
41impl<V> ExtractedFromVocabulary<V> for LiteralIndex
42where
43    V: LiteralVocabulary<Literal = LiteralIndex>,
44{
45    type Extracted = Literal;
46
47    fn extracted_from_vocabulary(&self, vocabulary: &V) -> Self::Extracted {
48        vocabulary.literal(self).unwrap().to_owned()
49    }
50}
51
52impl TryFrom<Literal> for LiteralIndex {
53    type Error = Literal;
54
55    fn try_from(value: Literal) -> Result<Self, Self::Error> {
56        Err(value)
57    }
58}
59
60impl<'a> TryFrom<LiteralRef<'a>> for LiteralIndex {
61    type Error = ();
62
63    fn try_from(_value: LiteralRef<'a>) -> Result<Self, Self::Error> {
64        Err(())
65    }
66}
67
68#[cfg(feature = "contextual")]
69impl<V: crate::vocabulary::LiteralVocabulary<Literal = Self>> contextual::DisplayWithContext<V>
70    for LiteralIndex
71{
72    fn fmt_with(&self, vocabulary: &V, f: &mut std::fmt::Formatter) -> std::fmt::Result {
73        std::fmt::Display::fmt(&vocabulary.literal(self).unwrap(), f)
74    }
75}
76
77#[cfg(feature = "contextual")]
78impl<V: crate::vocabulary::LiteralVocabulary<Literal = Self>> crate::RdfDisplayWithContext<V>
79    for LiteralIndex
80{
81    fn rdf_fmt_with(&self, vocabulary: &V, f: &mut std::fmt::Formatter) -> std::fmt::Result {
82        crate::RdfDisplay::rdf_fmt(&vocabulary.literal(self).unwrap(), f)
83    }
84}
85
86/// Literal or index.
87#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
88pub enum LiteralOrIndex<I> {
89    /// Index in the vocabulary.
90    Index(usize),
91
92    /// Non indexed literal.
93    Literal(I),
94}
95
96impl<I> From<usize> for LiteralOrIndex<I> {
97    fn from(i: usize) -> Self {
98        Self::Index(i)
99    }
100}
101
102impl<L: TryFrom<Literal>> TryFrom<Literal> for LiteralOrIndex<L> {
103    type Error = L::Error;
104
105    fn try_from(value: Literal) -> Result<Self, Self::Error> {
106        Ok(Self::Literal(L::try_from(value)?))
107    }
108}
109
110impl<'a, L: TryFrom<LiteralRef<'a>>> TryFrom<LiteralRef<'a>> for LiteralOrIndex<L> {
111    type Error = L::Error;
112
113    fn try_from(literal: LiteralRef<'a>) -> Result<Self, Self::Error> {
114        Ok(Self::Literal(L::try_from(literal)?))
115    }
116}
117
118/// Partly indexed literal value type.
119pub trait IndexedLiteral:
120    From<usize> + for<'a> TryFrom<LiteralRef<'a>> + TryFrom<Literal, Error = Literal>
121{
122    fn literal_index(&self) -> LiteralOrIndex<&Literal>;
123
124    fn into_literal_index(self) -> LiteralOrIndex<Literal>;
125}
126
127impl<L> IndexedLiteral for LiteralOrIndex<L>
128where
129    L: AsRef<Literal>
130        + Into<Literal>
131        + for<'a> TryFrom<LiteralRef<'a>>
132        + TryFrom<Literal, Error = Literal>,
133{
134    fn literal_index(&self) -> LiteralOrIndex<&Literal> {
135        match self {
136            Self::Literal(i) => LiteralOrIndex::Literal(i.as_ref()),
137            Self::Index(i) => LiteralOrIndex::Index(*i),
138        }
139    }
140
141    fn into_literal_index(self) -> LiteralOrIndex<Literal> {
142        match self {
143            Self::Literal(i) => LiteralOrIndex::Literal(i.into()),
144            Self::Index(i) => LiteralOrIndex::Index(i),
145        }
146    }
147}