jsonld_syntax/context/
mod.rs1use iri_rs::{Iri, IriRef, IriRefBuf};
2use smallvec::SmallVec;
3
4pub mod definition;
6mod print;
7pub mod term_definition;
9mod try_from_json;
10
11pub use definition::Definition;
12pub use term_definition::TermDefinition;
13pub use try_from_json::{InvalidContext, MAX_CONTEXT_DEPTH};
14
15#[derive(PartialEq, Eq, Clone, Debug)]
19#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
20#[cfg_attr(feature = "serde", serde(untagged))]
21#[allow(clippy::large_enum_variant)]
22pub enum Context {
23 One(ContextEntry),
25 Many(Vec<ContextEntry>),
27}
28
29impl Default for Context {
30 fn default() -> Self {
31 Self::Many(Vec::new())
32 }
33}
34
35impl Context {
36 #[must_use]
38 pub fn one(context: ContextEntry) -> Self {
39 Self::One(context)
40 }
41
42 #[must_use]
44 pub fn null() -> Self {
45 Self::one(ContextEntry::Null)
46 }
47
48 #[must_use]
50 pub fn iri_ref(iri_ref: IriRefBuf) -> Self {
51 Self::one(ContextEntry::IriRef(iri_ref))
52 }
53
54 #[must_use]
56 pub fn definition(def: Definition) -> Self {
57 Self::one(ContextEntry::Definition(def))
58 }
59}
60
61impl Context {
62 #[must_use]
65 pub fn len(&self) -> usize {
66 match self {
67 Self::One(_) => 1,
68 Self::Many(l) => l.len(),
69 }
70 }
71
72 #[must_use]
74 pub fn is_empty(&self) -> bool {
75 match self {
76 Self::One(_) => false,
77 Self::Many(l) => l.is_empty(),
78 }
79 }
80
81 #[must_use]
83 pub fn as_slice(&self) -> &[ContextEntry] {
84 match self {
85 Self::One(c) => std::slice::from_ref(c),
86 Self::Many(list) => list,
87 }
88 }
89
90 #[must_use]
93 pub fn is_object(&self) -> bool {
94 match self {
95 Self::One(c) => c.is_object(),
96 Self::Many(_) => false,
97 }
98 }
99
100 #[must_use]
102 pub fn is_array(&self) -> bool {
103 matches!(self, Self::Many(_))
104 }
105
106 #[must_use]
109 pub fn traverse(&self) -> Traverse<'_> {
110 match self {
111 Self::One(c) => Traverse::new(FragmentRef::Context(c)),
112 Self::Many(m) => Traverse::new(FragmentRef::ContextArray(m)),
113 }
114 }
115
116 pub fn iter(&self) -> std::slice::Iter<'_, ContextEntry> {
118 self.as_slice().iter()
119 }
120}
121
122pub enum IntoIter {
130 One(Option<Box<ContextEntry>>),
132 Many(std::vec::IntoIter<ContextEntry>),
134}
135
136impl Iterator for IntoIter {
137 type Item = ContextEntry;
138
139 fn next(&mut self) -> Option<Self::Item> {
140 match self {
141 Self::One(t) => t.take().map(|t| *t),
142 Self::Many(t) => t.next(),
143 }
144 }
145}
146
147impl IntoIterator for Context {
148 type Item = ContextEntry;
149 type IntoIter = IntoIter;
150
151 fn into_iter(self) -> Self::IntoIter {
152 match self {
153 Self::One(t) => IntoIter::One(Some(Box::new(t))),
154 Self::Many(t) => IntoIter::Many(t.into_iter()),
155 }
156 }
157}
158
159impl<'a> IntoIterator for &'a Context {
160 type IntoIter = std::slice::Iter<'a, ContextEntry>;
161 type Item = &'a ContextEntry;
162
163 fn into_iter(self) -> Self::IntoIter {
164 self.iter()
165 }
166}
167
168impl From<ContextEntry> for Context {
169 fn from(c: ContextEntry) -> Self {
170 Self::One(c)
171 }
172}
173
174impl From<IriRefBuf> for Context {
175 fn from(i: IriRefBuf) -> Self {
176 Self::One(ContextEntry::IriRef(i))
177 }
178}
179
180impl<'a> From<IriRef<&'a str>> for Context {
181 fn from(i: IriRef<&'a str>) -> Self {
182 Self::One(ContextEntry::IriRef(i.into()))
183 }
184}
185
186impl From<iri_rs::IriBuf> for Context {
187 fn from(i: iri_rs::IriBuf) -> Self {
188 Self::One(ContextEntry::IriRef(i.into()))
189 }
190}
191
192impl<'a> From<Iri<&'a str>> for Context {
193 fn from(i: Iri<&'a str>) -> Self {
194 Self::One(ContextEntry::IriRef(IriRefBuf::from(IriRef::<&str>::from(i))))
195 }
196}
197
198impl From<Definition> for Context {
199 fn from(c: Definition) -> Self {
200 Self::One(ContextEntry::Definition(c))
201 }
202}
203
204#[derive(PartialEq, Eq, Clone, Debug)]
206#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(untagged))]
207pub enum ContextEntry {
208 Null,
210 IriRef(IriRefBuf),
212 Definition(Definition),
214}
215
216impl ContextEntry {
217 fn sub_items(&self) -> ContextSubFragments<'_> {
218 match self {
219 Self::Definition(d) => ContextSubFragments::Definition(Box::new(d.iter())),
220 _ => ContextSubFragments::None,
221 }
222 }
223
224 #[must_use]
227 pub fn is_object(&self) -> bool {
228 matches!(self, Self::Definition(_))
229 }
230}
231
232impl From<IriRefBuf> for ContextEntry {
233 fn from(i: IriRefBuf) -> Self {
234 ContextEntry::IriRef(i)
235 }
236}
237
238impl<'a> From<IriRef<&'a str>> for ContextEntry {
239 fn from(i: IriRef<&'a str>) -> Self {
240 ContextEntry::IriRef(i.into())
241 }
242}
243
244impl From<iri_rs::IriBuf> for ContextEntry {
245 fn from(i: iri_rs::IriBuf) -> Self {
246 ContextEntry::IriRef(i.into())
247 }
248}
249
250impl<'a> From<Iri<&'a str>> for ContextEntry {
251 fn from(i: Iri<&'a str>) -> Self {
252 ContextEntry::IriRef(IriRefBuf::from(IriRef::<&str>::from(i)))
253 }
254}
255
256impl From<Definition> for ContextEntry {
257 fn from(c: Definition) -> Self {
258 ContextEntry::Definition(c)
259 }
260}
261
262pub enum FragmentRef<'a> {
264 ContextArray(&'a [ContextEntry]),
266
267 Context(&'a ContextEntry),
269
270 DefinitionFragment(definition::FragmentRef<'a>),
272}
273
274impl<'a> FragmentRef<'a> {
275 #[must_use]
277 pub fn is_array(&self) -> bool {
278 match self {
279 Self::ContextArray(_) => true,
280 Self::DefinitionFragment(i) => i.is_array(),
281 Self::Context(_) => false,
282 }
283 }
284
285 #[must_use]
287 pub fn is_object(&self) -> bool {
288 match self {
289 Self::Context(c) => c.is_object(),
290 Self::DefinitionFragment(i) => i.is_object(),
291 Self::ContextArray(_) => false,
292 }
293 }
294
295 #[must_use]
297 pub fn sub_items(&self) -> SubFragments<'a> {
298 match self {
299 Self::ContextArray(a) => SubFragments::ContextArray(a.iter()),
300 Self::Context(c) => SubFragments::Context(c.sub_items()),
301 Self::DefinitionFragment(d) => SubFragments::Definition(Box::new(d.sub_items())),
302 }
303 }
304}
305
306pub enum ContextSubFragments<'a> {
308 None,
310 Definition(Box<definition::Entries<'a>>),
312}
313
314impl<'a> Iterator for ContextSubFragments<'a> {
315 type Item = FragmentRef<'a>;
316
317 fn next(&mut self) -> Option<Self::Item> {
318 match self {
319 Self::None => None,
320 Self::Definition(e) => e.next().map(|e| FragmentRef::DefinitionFragment(definition::FragmentRef::Entry(e))),
321 }
322 }
323}
324
325pub enum SubFragments<'a> {
327 ContextArray(std::slice::Iter<'a, ContextEntry>),
329 Context(ContextSubFragments<'a>),
331 Definition(Box<definition::SubItems<'a>>),
333}
334
335impl<'a> Iterator for SubFragments<'a> {
336 type Item = FragmentRef<'a>;
337
338 fn next(&mut self) -> Option<Self::Item> {
339 match self {
340 Self::ContextArray(a) => a.next().map(FragmentRef::Context),
341 Self::Context(i) => i.next(),
342 Self::Definition(i) => i.next().map(FragmentRef::DefinitionFragment),
343 }
344 }
345}
346
347pub struct Traverse<'a> {
349 stack: SmallVec<[FragmentRef<'a>; 8]>,
350}
351
352impl<'a> Traverse<'a> {
353 pub(crate) fn new(item: FragmentRef<'a>) -> Self {
354 let mut stack = SmallVec::new();
355 stack.push(item);
356 Self { stack }
357 }
358}
359
360impl<'a> Iterator for Traverse<'a> {
361 type Item = FragmentRef<'a>;
362
363 fn next(&mut self) -> Option<Self::Item> {
364 match self.stack.pop() {
365 Some(item) => {
366 self.stack.extend(item.sub_items());
367 Some(item)
368 }
369 None => None,
370 }
371 }
372}
373
374#[derive(PartialEq, Eq, Clone, Debug)]
379#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
380pub struct ContextDocument {
381 #[cfg_attr(feature = "serde", serde(rename = "@context"))]
382 pub context: Context,
384}