1use crate::{CompactIri, CompactIriBuf, Container, ContainerKind, Direction, Keyword, LenientLangTag, LenientLangTagBuf, Nullable, container, context};
2use educe::Educe;
3use iri_rs::{Iri, IriBuf};
4use rdfx::{BlankId, BlankIdBuf};
5
6mod id;
7mod index;
8mod nest;
9mod type_;
10
11pub use id::*;
12pub use index::*;
13pub use nest::*;
14pub use type_::*;
15
16#[derive(PartialEq, Eq, Clone, Debug)]
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19#[cfg_attr(feature = "serde", serde(untagged))]
20pub enum TermDefinition {
21 Simple(Simple),
24 Expanded(Box<Expanded>),
26}
27
28impl TermDefinition {
29 #[must_use]
31 pub fn is_expanded(&self) -> bool {
32 matches!(self, Self::Expanded(_))
33 }
34
35 #[must_use]
38 pub fn is_object(&self) -> bool {
39 self.is_expanded()
40 }
41
42 #[must_use]
47 pub fn as_expanded(&self) -> ExpandedRef<'_> {
48 match self {
49 Self::Simple(term) => ExpandedRef {
50 id: Some(Nullable::Some(term.as_str().into())),
51 ..Default::default()
52 },
53 Self::Expanded(e) => e.as_expanded_ref(),
54 }
55 }
56}
57
58#[derive(PartialEq, Eq, Clone, Debug)]
59#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(transparent))]
60pub struct Simple(pub(crate) String);
66
67impl Simple {
68 #[must_use]
70 pub fn as_iri(&self) -> Option<Iri<&str>> {
71 Iri::parse(self.0.as_str()).ok()
72 }
73
74 #[must_use]
77 pub fn as_compact_iri(&self) -> Option<&CompactIri> {
78 CompactIri::new(&self.0).ok()
79 }
80
81 #[must_use]
84 pub fn as_blank_id(&self) -> Option<&BlankId> {
85 BlankId::new(&self.0).ok()
86 }
87
88 #[must_use]
90 pub fn as_str(&self) -> &str {
91 &self.0
92 }
93
94 #[must_use]
96 pub fn into_string(self) -> String {
97 self.0
98 }
99}
100
101impl From<IriBuf> for Simple {
102 fn from(value: IriBuf) -> Self {
103 Self(value.into_inner())
104 }
105}
106
107impl From<CompactIriBuf> for Simple {
108 fn from(value: CompactIriBuf) -> Self {
109 Self(value.into_string())
110 }
111}
112
113impl From<BlankIdBuf> for Simple {
114 fn from(value: BlankIdBuf) -> Self {
115 Self(value.to_string())
116 }
117}
118
119#[derive(PartialEq, Eq, Clone, Educe, Debug)]
121#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
122#[educe(Default)]
123pub struct Expanded {
124 #[cfg_attr(
125 feature = "serde",
126 serde(rename = "@id", default, deserialize_with = "Nullable::optional", skip_serializing_if = "Option::is_none")
127 )]
128 pub id: Option<Nullable<Id>>,
130
131 #[cfg_attr(
132 feature = "serde",
133 serde(rename = "@type", default, deserialize_with = "Nullable::optional", skip_serializing_if = "Option::is_none")
134 )]
135 pub type_: Option<Nullable<Type>>,
137
138 #[cfg_attr(feature = "serde", serde(rename = "@context", default, skip_serializing_if = "Option::is_none"))]
139 pub context: Option<Box<context::Context>>,
141
142 #[cfg_attr(feature = "serde", serde(rename = "@reverse", default, skip_serializing_if = "Option::is_none"))]
143 pub reverse: Option<context::definition::Key>,
145
146 #[cfg_attr(feature = "serde", serde(rename = "@index", default, skip_serializing_if = "Option::is_none"))]
147 pub index: Option<Index>,
150
151 #[cfg_attr(
152 feature = "serde",
153 serde(rename = "@language", default, deserialize_with = "Nullable::optional", skip_serializing_if = "Option::is_none")
154 )]
155 pub language: Option<Nullable<LenientLangTagBuf>>,
157
158 #[cfg_attr(
159 feature = "serde",
160 serde(rename = "@direction", default, deserialize_with = "Nullable::optional", skip_serializing_if = "Option::is_none")
161 )]
162 pub direction: Option<Nullable<Direction>>,
164
165 #[cfg_attr(
166 feature = "serde",
167 serde(rename = "@container", default, deserialize_with = "Nullable::optional", skip_serializing_if = "Option::is_none")
168 )]
169 pub container: Option<Nullable<Container>>,
172
173 #[cfg_attr(feature = "serde", serde(rename = "@nest", default, skip_serializing_if = "Option::is_none"))]
174 pub nest: Option<Nest>,
176
177 #[cfg_attr(feature = "serde", serde(rename = "@prefix", default, skip_serializing_if = "Option::is_none"))]
178 pub prefix: Option<bool>,
181
182 #[cfg_attr(feature = "serde", serde(rename = "@propagate", default, skip_serializing_if = "Option::is_none"))]
183 pub propagate: Option<bool>,
185
186 #[cfg_attr(feature = "serde", serde(rename = "@protected", default, skip_serializing_if = "Option::is_none"))]
187 pub protected: Option<bool>,
189}
190
191impl Expanded {
192 #[must_use]
194 pub fn new() -> Self {
195 Self::default()
196 }
197
198 #[must_use]
201 pub fn is_null(&self) -> bool {
202 matches!(&self.id, None | Some(Nullable::Null))
203 && self.type_.is_none()
204 && self.context.is_none()
205 && self.reverse.is_none()
206 && self.index.is_none()
207 && self.language.is_none()
208 && self.direction.is_none()
209 && self.container.is_none()
210 && self.nest.is_none()
211 && self.prefix.is_none()
212 && self.propagate.is_none()
213 && self.protected.is_none()
214 }
215
216 #[must_use]
219 pub fn is_simple_definition(&self) -> bool {
220 matches!(&self.id, Some(Nullable::Some(_)))
221 && self.type_.is_none()
222 && self.context.is_none()
223 && self.reverse.is_none()
224 && self.index.is_none()
225 && self.language.is_none()
226 && self.direction.is_none()
227 && self.container.is_none()
228 && self.nest.is_none()
229 && self.prefix.is_none()
230 && self.propagate.is_none()
231 && self.protected.is_none()
232 }
233
234 #[must_use]
238 pub fn simplify(self) -> Nullable<TermDefinition> {
239 if self.is_null() {
240 return Nullable::Null;
241 }
242 match self {
243 Self {
244 id: Some(Nullable::Some(id)),
245 type_: None,
246 context: None,
247 reverse: None,
248 index: None,
249 language: None,
250 direction: None,
251 container: None,
252 nest: None,
253 prefix: None,
254 propagate: None,
255 protected: None,
256 } => Nullable::Some(TermDefinition::Simple(Simple(id.into_string()))),
257 other => Nullable::Some(TermDefinition::Expanded(Box::new(other))),
258 }
259 }
260
261 pub fn iter(&self) -> Entries<'_> {
264 Entries {
265 id: self.id.as_ref().map(Nullable::as_ref),
266 type_: self.type_.as_ref().map(Nullable::as_ref),
267 context: self.context.as_deref(),
268 reverse: self.reverse.as_ref(),
269 index: self.index.as_ref(),
270 language: self.language.as_ref().map(Nullable::as_ref),
271 direction: self.direction,
272 container: self.container.as_ref().map(Nullable::as_ref),
273 nest: self.nest.as_ref(),
274 prefix: self.prefix,
275 propagate: self.propagate,
276 protected: self.protected,
277 }
278 }
279
280 pub fn as_expanded_ref(&self) -> ExpandedRef<'_> {
282 ExpandedRef {
283 id: self.id.as_ref().map(|i| i.as_ref().map(|id| id.as_id_ref())),
284 type_: self.type_.as_ref().map(Nullable::as_ref),
285 context: self.context.as_deref(),
286 reverse: self.reverse.as_ref(),
287 index: self.index.as_ref(),
288 language: self.language.as_ref().map(|n| n.as_ref().map(LenientLangTagBuf::as_lenient_lang_tag_ref)),
289 direction: self.direction,
290 container: self.container.as_ref().map(Nullable::as_ref),
291 nest: self.nest.as_ref(),
292 prefix: self.prefix,
293 propagate: self.propagate,
294 protected: self.protected,
295 }
296 }
297}
298
299#[derive(Debug, Educe)]
304#[educe(Default)]
305pub struct ExpandedRef<'a> {
306 pub id: Option<Nullable<IdRef<'a>>>,
308 pub type_: Option<Nullable<&'a Type>>,
310 pub context: Option<&'a context::Context>,
312 pub reverse: Option<&'a context::definition::Key>,
314 pub index: Option<&'a Index>,
317 pub language: Option<Nullable<&'a LenientLangTag>>,
319 pub direction: Option<Nullable<Direction>>,
321 pub container: Option<Nullable<&'a Container>>,
324 pub nest: Option<&'a Nest>,
326 pub prefix: Option<bool>,
329 pub propagate: Option<bool>,
332 pub protected: Option<bool>,
334}
335
336impl<'a> From<Nullable<&'a TermDefinition>> for ExpandedRef<'a> {
337 fn from(value: Nullable<&'a TermDefinition>) -> Self {
338 match value {
339 Nullable::Some(d) => d.as_expanded(),
340 Nullable::Null => Self {
341 id: Some(Nullable::Null),
342 ..Default::default()
343 },
344 }
345 }
346}
347
348pub struct Entries<'a> {
350 id: Option<Nullable<&'a Id>>,
351 type_: Option<Nullable<&'a Type>>,
352 context: Option<&'a context::Context>,
353 reverse: Option<&'a context::definition::Key>,
354 index: Option<&'a Index>,
355 language: Option<Nullable<&'a LenientLangTagBuf>>,
356 direction: Option<Nullable<Direction>>,
357 container: Option<Nullable<&'a Container>>,
358 nest: Option<&'a Nest>,
359 prefix: Option<bool>,
360 propagate: Option<bool>,
361 protected: Option<bool>,
362}
363
364pub enum EntryRef<'a> {
366 Id(Nullable<&'a Id>),
368 Type(Nullable<&'a Type>),
370 Context(&'a context::Context),
372 Reverse(&'a context::definition::Key),
374 Index(&'a Index),
377 Language(Nullable<&'a LenientLangTagBuf>),
379 Direction(Nullable<Direction>),
381 Container(Nullable<&'a Container>),
384 Nest(&'a Nest),
386 Prefix(bool),
389 Propagate(bool),
391 Protected(bool),
393}
394
395impl<'a> EntryRef<'a> {
396 #[must_use]
398 pub fn into_key(self) -> EntryKey {
399 match self {
400 Self::Id(_) => EntryKey::Id,
401 Self::Type(_) => EntryKey::Type,
402 Self::Context(_) => EntryKey::Context,
403 Self::Reverse(_) => EntryKey::Reverse,
404 Self::Index(_) => EntryKey::Index,
405 Self::Language(_) => EntryKey::Language,
406 Self::Direction(_) => EntryKey::Direction,
407 Self::Container(_) => EntryKey::Container,
408 Self::Nest(_) => EntryKey::Nest,
409 Self::Prefix(_) => EntryKey::Prefix,
410 Self::Propagate(_) => EntryKey::Propagate,
411 Self::Protected(_) => EntryKey::Protected,
412 }
413 }
414
415 #[must_use]
417 pub fn key(&self) -> EntryKey {
418 match self {
419 Self::Id(_) => EntryKey::Id,
420 Self::Type(_) => EntryKey::Type,
421 Self::Context(_) => EntryKey::Context,
422 Self::Reverse(_) => EntryKey::Reverse,
423 Self::Index(_) => EntryKey::Index,
424 Self::Language(_) => EntryKey::Language,
425 Self::Direction(_) => EntryKey::Direction,
426 Self::Container(_) => EntryKey::Container,
427 Self::Nest(_) => EntryKey::Nest,
428 Self::Prefix(_) => EntryKey::Prefix,
429 Self::Propagate(_) => EntryKey::Propagate,
430 Self::Protected(_) => EntryKey::Protected,
431 }
432 }
433
434 #[must_use]
436 pub fn into_value(self) -> EntryValueRef<'a> {
437 self.value()
438 }
439
440 #[must_use]
442 pub fn value(&self) -> EntryValueRef<'a> {
443 match self {
444 Self::Id(e) => EntryValueRef::Id(*e),
445 Self::Type(e) => EntryValueRef::Type(*e),
446 Self::Context(e) => EntryValueRef::Context(e),
447 Self::Reverse(e) => EntryValueRef::Reverse(e),
448 Self::Index(e) => EntryValueRef::Index(e),
449 Self::Language(e) => EntryValueRef::Language(*e),
450 Self::Direction(e) => EntryValueRef::Direction(*e),
451 Self::Container(e) => EntryValueRef::Container(*e),
452 Self::Nest(e) => EntryValueRef::Nest(e),
453 Self::Prefix(e) => EntryValueRef::Prefix(*e),
454 Self::Propagate(e) => EntryValueRef::Propagate(*e),
455 Self::Protected(e) => EntryValueRef::Protected(*e),
456 }
457 }
458
459 #[must_use]
461 pub fn into_key_value(self) -> (EntryKey, EntryValueRef<'a>) {
462 self.key_value()
463 }
464
465 #[must_use]
467 pub fn key_value(&self) -> (EntryKey, EntryValueRef<'a>) {
468 match self {
469 Self::Id(e) => (EntryKey::Id, EntryValueRef::Id(*e)),
470 Self::Type(e) => (EntryKey::Type, EntryValueRef::Type(*e)),
471 Self::Context(e) => (EntryKey::Context, EntryValueRef::Context(e)),
472 Self::Reverse(e) => (EntryKey::Reverse, EntryValueRef::Reverse(e)),
473 Self::Index(e) => (EntryKey::Index, EntryValueRef::Index(e)),
474 Self::Language(e) => (EntryKey::Language, EntryValueRef::Language(*e)),
475 Self::Direction(e) => (EntryKey::Direction, EntryValueRef::Direction(*e)),
476 Self::Container(e) => (EntryKey::Container, EntryValueRef::Container(*e)),
477 Self::Nest(e) => (EntryKey::Nest, EntryValueRef::Nest(e)),
478 Self::Prefix(e) => (EntryKey::Prefix, EntryValueRef::Prefix(*e)),
479 Self::Propagate(e) => (EntryKey::Propagate, EntryValueRef::Propagate(*e)),
480 Self::Protected(e) => (EntryKey::Protected, EntryValueRef::Protected(*e)),
481 }
482 }
483}
484
485pub enum EntryKey {
487 Id,
489 Type,
491 Context,
493 Reverse,
495 Index,
498 Language,
500 Direction,
502 Container,
505 Nest,
507 Prefix,
510 Propagate,
512 Protected,
514}
515
516impl EntryKey {
517 #[must_use]
519 pub fn keyword(&self) -> Keyword {
520 match self {
521 Self::Id => Keyword::Id,
522 Self::Type => Keyword::Type,
523 Self::Context => Keyword::Context,
524 Self::Reverse => Keyword::Reverse,
525 Self::Index => Keyword::Index,
526 Self::Language => Keyword::Language,
527 Self::Direction => Keyword::Direction,
528 Self::Container => Keyword::Container,
529 Self::Nest => Keyword::Nest,
530 Self::Prefix => Keyword::Prefix,
531 Self::Propagate => Keyword::Propagate,
532 Self::Protected => Keyword::Protected,
533 }
534 }
535
536 #[must_use]
538 pub fn as_str(&self) -> &'static str {
539 self.keyword().into_str()
540 }
541}
542
543pub enum EntryValueRef<'a> {
545 Id(Nullable<&'a Id>),
547 Type(Nullable<&'a Type>),
549 Context(&'a context::Context),
551 Reverse(&'a context::definition::Key),
553 Index(&'a Index),
556 Language(Nullable<&'a LenientLangTagBuf>),
558 Direction(Nullable<Direction>),
560 Container(Nullable<&'a Container>),
563 Nest(&'a Nest),
565 Prefix(bool),
568 Propagate(bool),
570 Protected(bool),
572}
573
574impl EntryValueRef<'_> {
575 #[must_use]
578 pub fn is_object(&self) -> bool {
579 match self {
580 Self::Context(c) => c.is_object(),
581 _ => false,
582 }
583 }
584
585 #[must_use]
588 pub fn is_array(&self) -> bool {
589 match self {
590 Self::Container(Nullable::Some(c)) => c.is_array(),
591 _ => false,
592 }
593 }
594}
595
596impl<'a> Iterator for Entries<'a> {
597 type Item = EntryRef<'a>;
598
599 fn size_hint(&self) -> (usize, Option<usize>) {
600 let mut len = 0;
601
602 if self.id.is_some() {
603 len += 1;
604 }
605
606 if self.type_.is_some() {
607 len += 1;
608 }
609
610 if self.context.is_some() {
611 len += 1;
612 }
613
614 if self.reverse.is_some() {
615 len += 1;
616 }
617
618 if self.index.is_some() {
619 len += 1;
620 }
621
622 if self.language.is_some() {
623 len += 1;
624 }
625
626 if self.direction.is_some() {
627 len += 1;
628 }
629
630 if self.container.is_some() {
631 len += 1;
632 }
633
634 if self.nest.is_some() {
635 len += 1;
636 }
637
638 if self.prefix.is_some() {
639 len += 1;
640 }
641
642 if self.propagate.is_some() {
643 len += 1;
644 }
645
646 if self.protected.is_some() {
647 len += 1;
648 }
649
650 (len, Some(len))
651 }
652
653 fn next(&mut self) -> Option<Self::Item> {
654 match self.id.take() {
655 Some(value) => Some(EntryRef::Id(value)),
656 None => match self.type_.take() {
657 Some(value) => Some(EntryRef::Type(value)),
658 None => match self.context.take() {
659 Some(value) => Some(EntryRef::Context(value)),
660 None => match self.reverse.take() {
661 Some(value) => Some(EntryRef::Reverse(value)),
662 None => match self.index.take() {
663 Some(value) => Some(EntryRef::Index(value)),
664 None => match self.language.take() {
665 Some(value) => Some(EntryRef::Language(value)),
666 None => match self.direction.take() {
667 Some(value) => Some(EntryRef::Direction(value)),
668 None => match self.container.take() {
669 Some(value) => Some(EntryRef::Container(value)),
670 None => match self.nest.take() {
671 Some(value) => Some(EntryRef::Nest(value)),
672 None => match self.prefix.take() {
673 Some(value) => Some(EntryRef::Prefix(value)),
674 None => match self.propagate.take() {
675 Some(value) => Some(EntryRef::Propagate(value)),
676 None => self.protected.take().map(EntryRef::Protected),
677 },
678 },
679 },
680 },
681 },
682 },
683 },
684 },
685 },
686 },
687 }
688 }
689}
690
691impl ExactSizeIterator for Entries<'_> {}
692
693pub enum FragmentRef<'a> {
695 Entry(EntryRef<'a>),
697
698 Key(EntryKey),
700
701 Value(EntryValueRef<'a>),
703
704 ContainerFragment(&'a ContainerKind),
706}
707
708impl<'a> FragmentRef<'a> {
709 #[must_use]
711 pub fn is_key(&self) -> bool {
712 matches!(self, Self::Key(_))
713 }
714
715 #[must_use]
717 pub fn is_entry(&self) -> bool {
718 matches!(self, Self::Entry(_))
719 }
720
721 #[must_use]
723 pub fn is_array(&self) -> bool {
724 match self {
725 Self::Value(v) => v.is_array(),
726 _ => false,
727 }
728 }
729
730 #[must_use]
732 pub fn is_object(&self) -> bool {
733 match self {
734 Self::Value(v) => v.is_object(),
735 _ => false,
736 }
737 }
738
739 #[must_use]
741 pub fn sub_fragments(&self) -> SubFragments<'a> {
742 match self {
743 Self::Value(EntryValueRef::Container(Nullable::Some(c))) => SubFragments::Container(c.sub_fragments()),
744 _ => SubFragments::None,
745 }
746 }
747}
748
749pub enum SubFragments<'a> {
751 None,
753 Container(container::SubValues<'a>),
755}
756
757impl<'a> Iterator for SubFragments<'a> {
758 type Item = FragmentRef<'a>;
759
760 fn next(&mut self) -> Option<Self::Item> {
761 match self {
762 Self::None => None,
763 Self::Container(c) => c.next().map(FragmentRef::ContainerFragment),
764 }
765 }
766}