json_ld_syntax/context/
mod.rs1use iref::{Iri, IriRef, IriRefBuf};
2use smallvec::SmallVec;
3
4pub mod definition;
5mod print;
6pub mod term_definition;
7mod try_from_json;
8
9pub use definition::Definition;
10pub use term_definition::TermDefinition;
11pub use try_from_json::InvalidContext;
12
13#[derive(PartialEq, Eq, Clone, Debug)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18#[cfg_attr(feature = "serde", serde(untagged))]
19pub enum Context {
20 One(ContextEntry),
21 Many(Vec<ContextEntry>),
22}
23
24impl Default for Context {
25 fn default() -> Self {
26 Self::Many(Vec::new())
27 }
28}
29
30impl Context {
31 pub fn one(context: ContextEntry) -> Self {
33 Self::One(context)
34 }
35
36 pub fn null() -> Self {
38 Self::one(ContextEntry::Null)
39 }
40
41 pub fn iri_ref(iri_ref: IriRefBuf) -> Self {
43 Self::one(ContextEntry::IriRef(iri_ref))
44 }
45
46 pub fn definition(def: Definition) -> Self {
48 Self::one(ContextEntry::Definition(def))
49 }
50}
51
52impl Context {
53 pub fn len(&self) -> usize {
54 match self {
55 Self::One(_) => 1,
56 Self::Many(l) => l.len(),
57 }
58 }
59
60 pub fn is_empty(&self) -> bool {
61 match self {
62 Self::One(_) => false,
63 Self::Many(l) => l.is_empty(),
64 }
65 }
66
67 pub fn as_slice(&self) -> &[ContextEntry] {
68 match self {
69 Self::One(c) => std::slice::from_ref(c),
70 Self::Many(list) => list,
71 }
72 }
73
74 pub fn is_object(&self) -> bool {
75 match self {
76 Self::One(c) => c.is_object(),
77 _ => false,
78 }
79 }
80
81 pub fn is_array(&self) -> bool {
82 matches!(self, Self::Many(_))
83 }
84
85 pub fn traverse(&self) -> Traverse {
86 match self {
87 Self::One(c) => Traverse::new(FragmentRef::Context(c)),
88 Self::Many(m) => Traverse::new(FragmentRef::ContextArray(m)),
89 }
90 }
91
92 pub fn iter(&self) -> std::slice::Iter<ContextEntry> {
93 self.as_slice().iter()
94 }
95}
96
97pub enum IntoIter {
98 One(Option<ContextEntry>),
99 Many(std::vec::IntoIter<ContextEntry>),
100}
101
102impl Iterator for IntoIter {
103 type Item = ContextEntry;
104
105 fn next(&mut self) -> Option<Self::Item> {
106 match self {
107 Self::One(t) => t.take(),
108 Self::Many(t) => t.next(),
109 }
110 }
111}
112
113impl IntoIterator for Context {
114 type Item = ContextEntry;
115 type IntoIter = IntoIter;
116
117 fn into_iter(self) -> Self::IntoIter {
118 match self {
119 Self::One(t) => IntoIter::One(Some(t)),
120 Self::Many(t) => IntoIter::Many(t.into_iter()),
121 }
122 }
123}
124
125impl<'a> IntoIterator for &'a Context {
126 type IntoIter = std::slice::Iter<'a, ContextEntry>;
127 type Item = &'a ContextEntry;
128
129 fn into_iter(self) -> Self::IntoIter {
130 self.iter()
131 }
132}
133
134impl From<ContextEntry> for Context {
135 fn from(c: ContextEntry) -> Self {
136 Self::One(c)
137 }
138}
139
140impl From<IriRefBuf> for Context {
141 fn from(i: IriRefBuf) -> Self {
142 Self::One(ContextEntry::IriRef(i))
143 }
144}
145
146impl<'a> From<&'a IriRef> for Context {
147 fn from(i: &'a IriRef) -> Self {
148 Self::One(ContextEntry::IriRef(i.to_owned()))
149 }
150}
151
152impl From<iref::IriBuf> for Context {
153 fn from(i: iref::IriBuf) -> Self {
154 Self::One(ContextEntry::IriRef(i.into()))
155 }
156}
157
158impl<'a> From<&'a Iri> for Context {
159 fn from(i: &'a Iri) -> Self {
160 Self::One(ContextEntry::IriRef(i.to_owned().into()))
161 }
162}
163
164impl From<Definition> for Context {
165 fn from(c: Definition) -> Self {
166 Self::One(ContextEntry::Definition(c))
167 }
168}
169
170#[derive(PartialEq, Eq, Clone, Debug)]
172#[cfg_attr(
173 feature = "serde",
174 derive(serde::Serialize, serde::Deserialize),
175 serde(untagged)
176)]
177pub enum ContextEntry {
178 Null,
179 IriRef(IriRefBuf),
180 Definition(Definition),
181}
182
183impl ContextEntry {
184 fn sub_items(&self) -> ContextSubFragments {
185 match self {
186 Self::Definition(d) => ContextSubFragments::Definition(Box::new(d.iter())),
187 _ => ContextSubFragments::None,
188 }
189 }
190
191 pub fn is_object(&self) -> bool {
192 matches!(self, Self::Definition(_))
193 }
194}
195
196impl From<IriRefBuf> for ContextEntry {
197 fn from(i: IriRefBuf) -> Self {
198 ContextEntry::IriRef(i)
199 }
200}
201
202impl<'a> From<&'a IriRef> for ContextEntry {
203 fn from(i: &'a IriRef) -> Self {
204 ContextEntry::IriRef(i.to_owned())
205 }
206}
207
208impl From<iref::IriBuf> for ContextEntry {
209 fn from(i: iref::IriBuf) -> Self {
210 ContextEntry::IriRef(i.into())
211 }
212}
213
214impl<'a> From<&'a Iri> for ContextEntry {
215 fn from(i: &'a Iri) -> Self {
216 ContextEntry::IriRef(i.to_owned().into())
217 }
218}
219
220impl From<Definition> for ContextEntry {
221 fn from(c: Definition) -> Self {
222 ContextEntry::Definition(c)
223 }
224}
225
226pub enum FragmentRef<'a> {
228 ContextArray(&'a [ContextEntry]),
230
231 Context(&'a ContextEntry),
233
234 DefinitionFragment(definition::FragmentRef<'a>),
236}
237
238impl<'a> FragmentRef<'a> {
239 pub fn is_array(&self) -> bool {
240 match self {
241 Self::ContextArray(_) => true,
242 Self::DefinitionFragment(i) => i.is_array(),
243 _ => false,
244 }
245 }
246
247 pub fn is_object(&self) -> bool {
248 match self {
249 Self::Context(c) => c.is_object(),
250 Self::DefinitionFragment(i) => i.is_object(),
251 _ => false,
252 }
253 }
254
255 pub fn sub_items(&self) -> SubFragments<'a> {
256 match self {
257 Self::ContextArray(a) => SubFragments::ContextArray(a.iter()),
258 Self::Context(c) => SubFragments::Context(c.sub_items()),
259 Self::DefinitionFragment(d) => SubFragments::Definition(Box::new(d.sub_items())),
260 }
261 }
262}
263
264pub enum ContextSubFragments<'a> {
265 None,
266 Definition(Box<definition::Entries<'a>>),
267}
268
269impl<'a> Iterator for ContextSubFragments<'a> {
270 type Item = FragmentRef<'a>;
271
272 fn next(&mut self) -> Option<Self::Item> {
273 match self {
274 Self::None => None,
275 Self::Definition(e) => e
276 .next()
277 .map(|e| FragmentRef::DefinitionFragment(definition::FragmentRef::Entry(e))),
278 }
279 }
280}
281
282pub enum SubFragments<'a> {
283 ContextArray(std::slice::Iter<'a, ContextEntry>),
284 Context(ContextSubFragments<'a>),
285 Definition(Box<definition::SubItems<'a>>),
286}
287
288impl<'a> Iterator for SubFragments<'a> {
289 type Item = FragmentRef<'a>;
290
291 fn next(&mut self) -> Option<Self::Item> {
292 match self {
293 Self::ContextArray(a) => a.next().map(FragmentRef::Context),
294 Self::Context(i) => i.next(),
295 Self::Definition(i) => i.next().map(FragmentRef::DefinitionFragment),
296 }
297 }
298}
299
300pub struct Traverse<'a> {
301 stack: SmallVec<[FragmentRef<'a>; 8]>,
302}
303
304impl<'a> Traverse<'a> {
305 pub(crate) fn new(item: FragmentRef<'a>) -> Self {
306 let mut stack = SmallVec::new();
307 stack.push(item);
308 Self { stack }
309 }
310}
311
312impl<'a> Iterator for Traverse<'a> {
313 type Item = FragmentRef<'a>;
314
315 fn next(&mut self) -> Option<Self::Item> {
316 match self.stack.pop() {
317 Some(item) => {
318 self.stack.extend(item.sub_items());
319 Some(item)
320 }
321 None => None,
322 }
323 }
324}
325
326#[derive(PartialEq, Eq, Clone, Debug)]
331#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
332pub struct ContextDocument {
333 #[cfg_attr(feature = "serde", serde(rename = "@context"))]
334 pub context: Context,
335}