1use crate::{
2 container, context, CompactIri, CompactIriBuf, Container, ContainerKind, Direction, Keyword,
3 LenientLangTag, LenientLangTagBuf, Nullable,
4};
5use educe::Educe;
6use iref::{Iri, IriBuf};
7use rdf_types::{BlankId, BlankIdBuf};
8
9mod id;
10mod index;
11mod nest;
12mod type_;
13
14pub use id::*;
15pub use index::*;
16pub use nest::*;
17pub use type_::*;
18
19#[derive(PartialEq, Eq, Clone, Debug)]
21#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
22#[cfg_attr(feature = "serde", serde(untagged))]
23pub enum TermDefinition {
24 Simple(Simple),
25 Expanded(Box<Expanded>),
26}
27
28impl TermDefinition {
29 pub fn is_expanded(&self) -> bool {
30 matches!(self, Self::Expanded(_))
31 }
32
33 pub fn is_object(&self) -> bool {
34 self.is_expanded()
35 }
36
37 pub fn as_expanded(&self) -> ExpandedRef {
38 match self {
39 Self::Simple(term) => ExpandedRef {
40 id: Some(Nullable::Some(term.as_str().into())),
41 ..Default::default()
42 },
43 Self::Expanded(e) => e.as_expanded_ref(),
44 }
45 }
46}
47
48#[derive(PartialEq, Eq, Clone, Debug)]
49#[cfg_attr(
50 feature = "serde",
51 derive(serde::Serialize, serde::Deserialize),
52 serde(transparent)
53)]
54pub struct Simple(pub(crate) String);
55
56impl Simple {
57 pub fn as_iri(&self) -> Option<&Iri> {
58 Iri::new(&self.0).ok()
59 }
60
61 pub fn as_compact_iri(&self) -> Option<&CompactIri> {
62 CompactIri::new(&self.0).ok()
63 }
64
65 pub fn as_blank_id(&self) -> Option<&BlankId> {
66 BlankId::new(&self.0).ok()
67 }
68
69 pub fn as_str(&self) -> &str {
70 &self.0
71 }
72
73 pub fn into_string(self) -> String {
74 self.0
75 }
76}
77
78impl From<IriBuf> for Simple {
79 fn from(value: IriBuf) -> Self {
80 Self(value.into_string())
81 }
82}
83
84impl From<CompactIriBuf> for Simple {
85 fn from(value: CompactIriBuf) -> Self {
86 Self(value.into_string())
87 }
88}
89
90impl From<BlankIdBuf> for Simple {
91 fn from(value: BlankIdBuf) -> Self {
92 Self(value.to_string())
93 }
94}
95
96#[derive(PartialEq, Eq, Clone, Educe, Debug)]
98#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
99#[educe(Default)]
100pub struct Expanded {
101 #[cfg_attr(
102 feature = "serde",
103 serde(
104 rename = "@id",
105 default,
106 deserialize_with = "Nullable::optional",
107 skip_serializing_if = "Option::is_none"
108 )
109 )]
110 pub id: Option<Nullable<Id>>,
111
112 #[cfg_attr(
113 feature = "serde",
114 serde(
115 rename = "@type",
116 default,
117 deserialize_with = "Nullable::optional",
118 skip_serializing_if = "Option::is_none"
119 )
120 )]
121 pub type_: Option<Nullable<Type>>,
122
123 #[cfg_attr(
124 feature = "serde",
125 serde(rename = "@context", default, skip_serializing_if = "Option::is_none")
126 )]
127 pub context: Option<Box<context::Context>>,
128
129 #[cfg_attr(
130 feature = "serde",
131 serde(rename = "@reverse", default, skip_serializing_if = "Option::is_none")
132 )]
133 pub reverse: Option<context::definition::Key>,
134
135 #[cfg_attr(
136 feature = "serde",
137 serde(rename = "@index", default, skip_serializing_if = "Option::is_none")
138 )]
139 pub index: Option<Index>,
140
141 #[cfg_attr(
142 feature = "serde",
143 serde(
144 rename = "@language",
145 default,
146 deserialize_with = "Nullable::optional",
147 skip_serializing_if = "Option::is_none"
148 )
149 )]
150 pub language: Option<Nullable<LenientLangTagBuf>>,
151
152 #[cfg_attr(
153 feature = "serde",
154 serde(
155 rename = "@direction",
156 default,
157 deserialize_with = "Nullable::optional",
158 skip_serializing_if = "Option::is_none"
159 )
160 )]
161 pub direction: Option<Nullable<Direction>>,
162
163 #[cfg_attr(
164 feature = "serde",
165 serde(
166 rename = "@container",
167 default,
168 deserialize_with = "Nullable::optional",
169 skip_serializing_if = "Option::is_none"
170 )
171 )]
172 pub container: Option<Nullable<Container>>,
173
174 #[cfg_attr(
175 feature = "serde",
176 serde(rename = "@nest", default, skip_serializing_if = "Option::is_none")
177 )]
178 pub nest: Option<Nest>,
179
180 #[cfg_attr(
181 feature = "serde",
182 serde(rename = "@prefix", default, skip_serializing_if = "Option::is_none")
183 )]
184 pub prefix: Option<bool>,
185
186 #[cfg_attr(
187 feature = "serde",
188 serde(
189 rename = "@propagate",
190 default,
191 skip_serializing_if = "Option::is_none"
192 )
193 )]
194 pub propagate: Option<bool>,
195
196 #[cfg_attr(
197 feature = "serde",
198 serde(
199 rename = "@protected",
200 default,
201 skip_serializing_if = "Option::is_none"
202 )
203 )]
204 pub protected: Option<bool>,
205}
206
207impl Expanded {
208 pub fn new() -> Self {
209 Self::default()
210 }
211
212 pub fn is_null(&self) -> bool {
213 matches!(&self.id, None | Some(Nullable::Null))
214 && self.type_.is_none()
215 && self.context.is_none()
216 && self.reverse.is_none()
217 && self.index.is_none()
218 && self.language.is_none()
219 && self.direction.is_none()
220 && self.container.is_none()
221 && self.nest.is_none()
222 && self.prefix.is_none()
223 && self.propagate.is_none()
224 && self.protected.is_none()
225 }
226
227 pub fn is_simple_definition(&self) -> bool {
228 matches!(&self.id, Some(Nullable::Some(_)))
229 && self.type_.is_none()
230 && self.context.is_none()
231 && self.reverse.is_none()
232 && self.index.is_none()
233 && self.language.is_none()
234 && self.direction.is_none()
235 && self.container.is_none()
236 && self.nest.is_none()
237 && self.prefix.is_none()
238 && self.propagate.is_none()
239 && self.protected.is_none()
240 }
241
242 pub fn simplify(self) -> Nullable<TermDefinition> {
243 if self.is_null() {
244 Nullable::Null
245 } else if self.is_simple_definition() {
246 Nullable::Some(TermDefinition::Simple(Simple(
247 self.id.unwrap().unwrap().into_string(),
248 )))
249 } else {
250 Nullable::Some(TermDefinition::Expanded(Box::new(self)))
251 }
252 }
253
254 pub fn iter(&self) -> Entries {
255 Entries {
256 id: self.id.as_ref().map(Nullable::as_ref),
257 type_: self.type_.as_ref().map(Nullable::as_ref),
258 context: self.context.as_deref(),
259 reverse: self.reverse.as_ref(),
260 index: self.index.as_ref(),
261 language: self.language.as_ref().map(Nullable::as_ref),
262 direction: self.direction,
263 container: self.container.as_ref().map(Nullable::as_ref),
264 nest: self.nest.as_ref(),
265 prefix: self.prefix,
266 propagate: self.propagate,
267 protected: self.protected,
268 }
269 }
270
271 pub fn as_expanded_ref(&self) -> ExpandedRef {
272 ExpandedRef {
273 id: self
274 .id
275 .as_ref()
276 .map(|i| i.as_ref().map(|id| id.as_id_ref())),
277 type_: self.type_.as_ref().map(Nullable::as_ref),
278 context: self.context.as_deref(),
279 reverse: self.reverse.as_ref(),
280 index: self.index.as_ref(),
281 language: self
282 .language
283 .as_ref()
284 .map(|n| n.as_ref().map(LenientLangTagBuf::as_lenient_lang_tag_ref)),
285 direction: self.direction,
286 container: self.container.as_ref().map(Nullable::as_ref),
287 nest: self.nest.as_ref(),
288 prefix: self.prefix,
289 propagate: self.propagate,
290 protected: self.protected,
291 }
292 }
293}
294
295#[derive(Debug, Educe)]
297#[educe(Default)]
298pub struct ExpandedRef<'a> {
299 pub id: Option<Nullable<IdRef<'a>>>,
300 pub type_: Option<Nullable<&'a Type>>,
301 pub context: Option<&'a context::Context>,
302 pub reverse: Option<&'a context::definition::Key>,
303 pub index: Option<&'a Index>,
304 pub language: Option<Nullable<&'a LenientLangTag>>,
305 pub direction: Option<Nullable<Direction>>,
306 pub container: Option<Nullable<&'a Container>>,
307 pub nest: Option<&'a Nest>,
308 pub prefix: Option<bool>,
309 pub propagate: Option<bool>,
310 pub protected: Option<bool>,
311}
312
313impl<'a> From<Nullable<&'a TermDefinition>> for ExpandedRef<'a> {
314 fn from(value: Nullable<&'a TermDefinition>) -> Self {
315 match value {
316 Nullable::Some(d) => d.as_expanded(),
317 Nullable::Null => Self {
318 id: Some(Nullable::Null),
319 ..Default::default()
320 },
321 }
322 }
323}
324
325pub struct Entries<'a> {
327 id: Option<Nullable<&'a Id>>,
328 type_: Option<Nullable<&'a Type>>,
329 context: Option<&'a context::Context>,
330 reverse: Option<&'a context::definition::Key>,
331 index: Option<&'a Index>,
332 language: Option<Nullable<&'a LenientLangTagBuf>>,
333 direction: Option<Nullable<Direction>>,
334 container: Option<Nullable<&'a Container>>,
335 nest: Option<&'a Nest>,
336 prefix: Option<bool>,
337 propagate: Option<bool>,
338 protected: Option<bool>,
339}
340
341pub enum EntryRef<'a> {
342 Id(Nullable<&'a Id>),
343 Type(Nullable<&'a Type>),
344 Context(&'a context::Context),
345 Reverse(&'a context::definition::Key),
346 Index(&'a Index),
347 Language(Nullable<&'a LenientLangTagBuf>),
348 Direction(Nullable<Direction>),
349 Container(Nullable<&'a Container>),
350 Nest(&'a Nest),
351 Prefix(bool),
352 Propagate(bool),
353 Protected(bool),
354}
355
356impl<'a> EntryRef<'a> {
357 pub fn into_key(self) -> EntryKey {
358 match self {
359 Self::Id(_) => EntryKey::Id,
360 Self::Type(_) => EntryKey::Type,
361 Self::Context(_) => EntryKey::Context,
362 Self::Reverse(_) => EntryKey::Reverse,
363 Self::Index(_) => EntryKey::Index,
364 Self::Language(_) => EntryKey::Language,
365 Self::Direction(_) => EntryKey::Direction,
366 Self::Container(_) => EntryKey::Container,
367 Self::Nest(_) => EntryKey::Nest,
368 Self::Prefix(_) => EntryKey::Prefix,
369 Self::Propagate(_) => EntryKey::Propagate,
370 Self::Protected(_) => EntryKey::Protected,
371 }
372 }
373
374 pub fn key(&self) -> EntryKey {
375 match self {
376 Self::Id(_) => EntryKey::Id,
377 Self::Type(_) => EntryKey::Type,
378 Self::Context(_) => EntryKey::Context,
379 Self::Reverse(_) => EntryKey::Reverse,
380 Self::Index(_) => EntryKey::Index,
381 Self::Language(_) => EntryKey::Language,
382 Self::Direction(_) => EntryKey::Direction,
383 Self::Container(_) => EntryKey::Container,
384 Self::Nest(_) => EntryKey::Nest,
385 Self::Prefix(_) => EntryKey::Prefix,
386 Self::Propagate(_) => EntryKey::Propagate,
387 Self::Protected(_) => EntryKey::Protected,
388 }
389 }
390
391 pub fn into_value(self) -> EntryValueRef<'a> {
392 self.value()
393 }
394
395 pub fn value(&self) -> EntryValueRef<'a> {
396 match self {
397 Self::Id(e) => EntryValueRef::Id(*e),
398 Self::Type(e) => EntryValueRef::Type(*e),
399 Self::Context(e) => EntryValueRef::Context(e),
400 Self::Reverse(e) => EntryValueRef::Reverse(e),
401 Self::Index(e) => EntryValueRef::Index(e),
402 Self::Language(e) => EntryValueRef::Language(*e),
403 Self::Direction(e) => EntryValueRef::Direction(*e),
404 Self::Container(e) => EntryValueRef::Container(*e),
405 Self::Nest(e) => EntryValueRef::Nest(e),
406 Self::Prefix(e) => EntryValueRef::Prefix(*e),
407 Self::Propagate(e) => EntryValueRef::Propagate(*e),
408 Self::Protected(e) => EntryValueRef::Protected(*e),
409 }
410 }
411
412 pub fn into_key_value(self) -> (EntryKey, EntryValueRef<'a>) {
413 self.key_value()
414 }
415
416 pub fn key_value(&self) -> (EntryKey, EntryValueRef<'a>) {
417 match self {
418 Self::Id(e) => (EntryKey::Id, EntryValueRef::Id(*e)),
419 Self::Type(e) => (EntryKey::Type, EntryValueRef::Type(*e)),
420 Self::Context(e) => (EntryKey::Context, EntryValueRef::Context(e)),
421 Self::Reverse(e) => (EntryKey::Reverse, EntryValueRef::Reverse(e)),
422 Self::Index(e) => (EntryKey::Index, EntryValueRef::Index(e)),
423 Self::Language(e) => (EntryKey::Language, EntryValueRef::Language(*e)),
424 Self::Direction(e) => (EntryKey::Direction, EntryValueRef::Direction(*e)),
425 Self::Container(e) => (EntryKey::Container, EntryValueRef::Container(*e)),
426 Self::Nest(e) => (EntryKey::Nest, EntryValueRef::Nest(e)),
427 Self::Prefix(e) => (EntryKey::Prefix, EntryValueRef::Prefix(*e)),
428 Self::Propagate(e) => (EntryKey::Propagate, EntryValueRef::Propagate(*e)),
429 Self::Protected(e) => (EntryKey::Protected, EntryValueRef::Protected(*e)),
430 }
431 }
432}
433
434pub enum EntryKey {
435 Id,
436 Type,
437 Context,
438 Reverse,
439 Index,
440 Language,
441 Direction,
442 Container,
443 Nest,
444 Prefix,
445 Propagate,
446 Protected,
447}
448
449impl EntryKey {
450 pub fn keyword(&self) -> Keyword {
451 match self {
452 Self::Id => Keyword::Id,
453 Self::Type => Keyword::Type,
454 Self::Context => Keyword::Context,
455 Self::Reverse => Keyword::Reverse,
456 Self::Index => Keyword::Index,
457 Self::Language => Keyword::Language,
458 Self::Direction => Keyword::Direction,
459 Self::Container => Keyword::Container,
460 Self::Nest => Keyword::Nest,
461 Self::Prefix => Keyword::Prefix,
462 Self::Propagate => Keyword::Propagate,
463 Self::Protected => Keyword::Protected,
464 }
465 }
466
467 pub fn as_str(&self) -> &'static str {
468 self.keyword().into_str()
469 }
470}
471
472pub enum EntryValueRef<'a> {
473 Id(Nullable<&'a Id>),
474 Type(Nullable<&'a Type>),
475 Context(&'a context::Context),
476 Reverse(&'a context::definition::Key),
477 Index(&'a Index),
478 Language(Nullable<&'a LenientLangTagBuf>),
479 Direction(Nullable<Direction>),
480 Container(Nullable<&'a Container>),
481 Nest(&'a Nest),
482 Prefix(bool),
483 Propagate(bool),
484 Protected(bool),
485}
486
487impl<'a> EntryValueRef<'a> {
488 pub fn is_object(&self) -> bool {
489 match self {
490 Self::Context(c) => c.is_object(),
491 _ => false,
492 }
493 }
494
495 pub fn is_array(&self) -> bool {
496 match self {
497 Self::Container(Nullable::Some(c)) => c.is_array(),
498 _ => false,
499 }
500 }
501}
502
503impl<'a> Iterator for Entries<'a> {
504 type Item = EntryRef<'a>;
505
506 fn size_hint(&self) -> (usize, Option<usize>) {
507 let mut len = 0;
508
509 if self.id.is_some() {
510 len += 1
511 }
512
513 if self.type_.is_some() {
514 len += 1
515 }
516
517 if self.context.is_some() {
518 len += 1
519 }
520
521 if self.reverse.is_some() {
522 len += 1
523 }
524
525 if self.index.is_some() {
526 len += 1
527 }
528
529 if self.language.is_some() {
530 len += 1
531 }
532
533 if self.direction.is_some() {
534 len += 1
535 }
536
537 if self.container.is_some() {
538 len += 1
539 }
540
541 if self.nest.is_some() {
542 len += 1
543 }
544
545 if self.prefix.is_some() {
546 len += 1
547 }
548
549 if self.propagate.is_some() {
550 len += 1
551 }
552
553 if self.protected.is_some() {
554 len += 1
555 }
556
557 (len, Some(len))
558 }
559
560 fn next(&mut self) -> Option<Self::Item> {
561 match self.id.take() {
562 Some(value) => Some(EntryRef::Id(value)),
563 None => match self.type_.take() {
564 Some(value) => Some(EntryRef::Type(value)),
565 None => match self.context.take() {
566 Some(value) => Some(EntryRef::Context(value)),
567 None => match self.reverse.take() {
568 Some(value) => Some(EntryRef::Reverse(value)),
569 None => match self.index.take() {
570 Some(value) => Some(EntryRef::Index(value)),
571 None => match self.language.take() {
572 Some(value) => Some(EntryRef::Language(value)),
573 None => match self.direction.take() {
574 Some(value) => Some(EntryRef::Direction(value)),
575 None => match self.container.take() {
576 Some(value) => Some(EntryRef::Container(value)),
577 None => match self.nest.take() {
578 Some(value) => Some(EntryRef::Nest(value)),
579 None => match self.prefix.take() {
580 Some(value) => Some(EntryRef::Prefix(value)),
581 None => match self.propagate.take() {
582 Some(value) => Some(EntryRef::Propagate(value)),
583 None => self
584 .protected
585 .take()
586 .map(EntryRef::Protected),
587 },
588 },
589 },
590 },
591 },
592 },
593 },
594 },
595 },
596 },
597 }
598 }
599}
600
601impl<'a> ExactSizeIterator for Entries<'a> {}
602
603pub enum FragmentRef<'a> {
605 Entry(EntryRef<'a>),
607
608 Key(EntryKey),
610
611 Value(EntryValueRef<'a>),
613
614 ContainerFragment(&'a ContainerKind),
616}
617
618impl<'a> FragmentRef<'a> {
619 pub fn is_key(&self) -> bool {
620 matches!(self, Self::Key(_))
621 }
622
623 pub fn is_entry(&self) -> bool {
624 matches!(self, Self::Entry(_))
625 }
626
627 pub fn is_array(&self) -> bool {
628 match self {
629 Self::Value(v) => v.is_array(),
630 _ => false,
631 }
632 }
633
634 pub fn is_object(&self) -> bool {
635 match self {
636 Self::Value(v) => v.is_object(),
637 _ => false,
638 }
639 }
640
641 pub fn sub_fragments(&self) -> SubFragments<'a> {
642 match self {
643 Self::Value(EntryValueRef::Container(Nullable::Some(c))) => {
644 SubFragments::Container(c.sub_fragments())
645 }
646 _ => SubFragments::None,
647 }
648 }
649}
650
651pub enum SubFragments<'a> {
652 None,
653 Container(container::SubValues<'a>),
654}
655
656impl<'a> Iterator for SubFragments<'a> {
657 type Item = FragmentRef<'a>;
658
659 fn next(&mut self) -> Option<Self::Item> {
660 match self {
661 Self::None => None,
662 Self::Container(c) => c.next().map(FragmentRef::ContainerFragment),
663 }
664 }
665}