1use core::fmt;
2use linked_data::{
3 rdf_types::{
4 dataset::PatternMatchingDataset,
5 interpretation::{ReverseIriInterpretation, ReverseLiteralInterpretation},
6 vocabulary::{IriVocabularyMut, LiteralVocabulary},
7 Interpretation, LiteralType, LiteralTypeRef, Vocabulary, RDF_LANG_STRING,
8 },
9 Context, FromLinkedDataError, LinkedDataDeserializeSubject, LinkedDataPredicateObjects,
10 LinkedDataSubject, RdfLiteral,
11};
12use serde::{Deserialize, Serialize};
13use std::{borrow::Borrow, ops::Deref, str::FromStr};
14
15pub use multibase::{Base, Error};
16
17use crate::MULTIBASE;
18
19#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
20#[serde(transparent)]
21#[repr(transparent)]
22pub struct Multibase(str);
23
24impl Multibase {
25 pub fn new(value: &str) -> &Self {
26 unsafe { std::mem::transmute(value) }
27 }
28
29 pub fn as_str(&self) -> &str {
30 &self.0
31 }
32
33 pub fn decode(&self) -> Result<(Base, Vec<u8>), Error> {
34 multibase::decode(self)
35 }
36}
37
38impl AsRef<str> for Multibase {
39 fn as_ref(&self) -> &str {
40 &self.0
41 }
42}
43
44impl fmt::Display for Multibase {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 self.0.fmt(f)
47 }
48}
49
50impl<V: Vocabulary, I: Interpretation> linked_data::LinkedDataResource<I, V> for Multibase
51where
52 V: IriVocabularyMut,
53{
54 fn interpretation(
55 &self,
56 vocabulary: &mut V,
57 _interpretation: &mut I,
58 ) -> linked_data::ResourceInterpretation<I, V> {
59 use linked_data::{rdf_types::Term, CowRdfTerm, ResourceInterpretation};
60 ResourceInterpretation::Uninterpreted(Some(CowRdfTerm::Owned(Term::Literal(
61 RdfLiteral::Any(
62 self.0.to_owned(),
63 LiteralType::Any(vocabulary.insert(MULTIBASE)),
64 ),
65 ))))
66 }
67}
68
69impl<V: Vocabulary, I: Interpretation> LinkedDataPredicateObjects<I, V> for Multibase
70where
71 V: IriVocabularyMut,
72{
73 fn visit_objects<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
74 where
75 S: linked_data::PredicateObjectsVisitor<I, V>,
76 {
77 visitor.object(self)?;
78 visitor.end()
79 }
80}
81
82impl<V: Vocabulary, I: Interpretation> LinkedDataSubject<I, V> for Multibase {
83 fn visit_subject<S>(&self, visitor: S) -> Result<S::Ok, S::Error>
84 where
85 S: linked_data::SubjectVisitor<I, V>,
86 {
87 visitor.end()
88 }
89}
90
91#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
92#[serde(transparent)]
93#[repr(transparent)]
94pub struct MultibaseBuf(String);
95
96impl MultibaseBuf {
97 pub fn new(value: String) -> Self {
98 Self(value)
99 }
100
101 pub fn encode(base: Base, input: impl AsRef<[u8]>) -> Self {
102 Self(multibase::encode(base, input))
103 }
104
105 pub fn as_multibase(&self) -> &Multibase {
106 Multibase::new(self.0.as_str())
107 }
108}
109
110impl Borrow<str> for MultibaseBuf {
111 fn borrow(&self) -> &str {
112 self.as_str()
113 }
114}
115
116impl Borrow<Multibase> for MultibaseBuf {
117 fn borrow(&self) -> &Multibase {
118 self.as_multibase()
119 }
120}
121
122impl FromStr for MultibaseBuf {
123 type Err = std::convert::Infallible;
124
125 fn from_str(s: &str) -> Result<Self, Self::Err> {
126 Ok(Self(s.to_owned())) }
128}
129
130impl AsRef<str> for MultibaseBuf {
131 fn as_ref(&self) -> &str {
132 self.as_str()
133 }
134}
135
136impl Deref for MultibaseBuf {
137 type Target = Multibase;
138
139 fn deref(&self) -> &Self::Target {
140 self.as_multibase()
141 }
142}
143
144impl fmt::Display for MultibaseBuf {
145 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
146 self.0.fmt(f)
147 }
148}
149
150impl<V: Vocabulary, I: Interpretation> linked_data::LinkedDataResource<I, V> for MultibaseBuf
151where
152 V: IriVocabularyMut,
153{
154 fn interpretation(
155 &self,
156 vocabulary: &mut V,
157 _interpretation: &mut I,
158 ) -> linked_data::ResourceInterpretation<I, V> {
159 use linked_data::{rdf_types::Term, CowRdfTerm, ResourceInterpretation};
160 ResourceInterpretation::Uninterpreted(Some(CowRdfTerm::Owned(Term::Literal(
161 RdfLiteral::Any(
162 self.0.to_owned(),
163 LiteralType::Any(vocabulary.insert(MULTIBASE)),
164 ),
165 ))))
166 }
167}
168
169impl<V: Vocabulary, I: Interpretation> LinkedDataPredicateObjects<I, V> for MultibaseBuf
170where
171 V: IriVocabularyMut,
172{
173 fn visit_objects<S>(&self, mut visitor: S) -> Result<S::Ok, S::Error>
174 where
175 S: linked_data::PredicateObjectsVisitor<I, V>,
176 {
177 visitor.object(self)?;
178 visitor.end()
179 }
180}
181
182impl<V: Vocabulary, I: Interpretation> LinkedDataSubject<I, V> for MultibaseBuf {
183 fn visit_subject<S>(&self, visitor: S) -> Result<S::Ok, S::Error>
184 where
185 S: linked_data::SubjectVisitor<I, V>,
186 {
187 visitor.end()
188 }
189}
190
191impl<V: Vocabulary, I> LinkedDataDeserializeSubject<I, V> for MultibaseBuf
192where
193 V: LiteralVocabulary,
194 I: ReverseIriInterpretation<Iri = V::Iri> + ReverseLiteralInterpretation<Literal = V::Literal>,
195{
196 fn deserialize_subject_in<D>(
197 vocabulary: &V,
198 interpretation: &I,
199 _dataset: &D,
200 _graph: Option<&I::Resource>,
201 resource: &<I as Interpretation>::Resource,
202 context: Context<I>,
203 ) -> Result<Self, linked_data::FromLinkedDataError>
204 where
205 D: PatternMatchingDataset<Resource = I::Resource>,
206 {
207 let mut literal_ty = None;
208 for l in interpretation.literals_of(resource) {
209 let l = vocabulary.literal(l).unwrap();
210 match l.type_ {
211 LiteralTypeRef::Any(ty_iri) => {
212 let ty_iri = vocabulary.iri(ty_iri).unwrap();
213 if ty_iri == MULTIBASE {
214 return match l.value.parse() {
215 Ok(value) => Ok(value),
216 Err(_) => Err(FromLinkedDataError::InvalidLiteral(
217 context.into_iris(vocabulary, interpretation),
218 )),
219 };
220 }
221
222 literal_ty = Some(ty_iri)
223 }
224 LiteralTypeRef::LangString(_) => literal_ty = Some(RDF_LANG_STRING),
225 }
226 }
227
228 match literal_ty {
229 Some(ty) => Err(FromLinkedDataError::LiteralTypeMismatch {
230 context: context.into_iris(vocabulary, interpretation),
231 expected: Some(MULTIBASE.to_owned()),
232 found: ty.to_owned(),
233 }),
234 None => Err(FromLinkedDataError::ExpectedLiteral(
235 context.into_iris(vocabulary, interpretation),
236 )),
237 }
238 }
239}