1use crate::{CompactIri, CompactIriBuf, Container, ContainerKind, Direction, Keyword, LenientLangTag, LenientLangTagBuf, Nullable, container, context};
2use iri_rs::{Iri, IriBuf};
3use rdfx::{BlankId, BlankIdBuf};
4
5mod id;
6mod index;
7mod nest;
8mod type_;
9
10pub use id::*;
11pub use index::*;
12pub use nest::*;
13pub use type_::*;
14
15#[derive(PartialEq, Eq, Clone, Debug)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18#[cfg_attr(feature = "serde", serde(untagged))]
19pub enum TermDefinition {
20 Simple(Simple),
23 Expanded(Box<Expanded>),
25}
26
27impl TermDefinition {
28 #[must_use]
30 pub fn is_expanded(&self) -> bool {
31 matches!(self, Self::Expanded(_))
32 }
33
34 #[must_use]
37 pub fn is_object(&self) -> bool {
38 self.is_expanded()
39 }
40
41 #[must_use]
46 pub fn as_expanded(&self) -> ExpandedRef<'_> {
47 match self {
48 Self::Simple(term) => ExpandedRef {
49 id: Some(Nullable::Some(term.as_str().into())),
50 ..Default::default()
51 },
52 Self::Expanded(e) => e.as_expanded_ref(),
53 }
54 }
55}
56
57#[derive(PartialEq, Eq, Clone, Debug)]
58#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(transparent))]
59pub struct Simple(pub(crate) String);
65
66impl Simple {
67 #[must_use]
69 pub fn as_iri(&self) -> Option<Iri<&str>> {
70 Iri::parse(self.0.as_str()).ok()
71 }
72
73 #[must_use]
76 pub fn as_compact_iri(&self) -> Option<&CompactIri> {
77 CompactIri::new(&self.0).ok()
78 }
79
80 #[must_use]
83 pub fn as_blank_id(&self) -> Option<&BlankId> {
84 BlankId::new(&self.0).ok()
85 }
86
87 #[must_use]
89 pub fn as_str(&self) -> &str {
90 &self.0
91 }
92
93 #[must_use]
95 pub fn into_string(self) -> String {
96 self.0
97 }
98}
99
100impl From<IriBuf> for Simple {
101 fn from(value: IriBuf) -> Self {
102 Self(value.into_inner())
103 }
104}
105
106impl From<CompactIriBuf> for Simple {
107 fn from(value: CompactIriBuf) -> Self {
108 Self(value.into_string())
109 }
110}
111
112impl From<BlankIdBuf> for Simple {
113 fn from(value: BlankIdBuf) -> Self {
114 Self(value.to_string())
115 }
116}
117
118#[derive(PartialEq, Eq, Clone, Default, Debug)]
120#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
121pub struct Expanded {
122 #[cfg_attr(
123 feature = "serde",
124 serde(rename = "@id", default, deserialize_with = "Nullable::optional", skip_serializing_if = "Option::is_none")
125 )]
126 pub id: Option<Nullable<Id>>,
128
129 #[cfg_attr(
130 feature = "serde",
131 serde(rename = "@type", default, deserialize_with = "Nullable::optional", skip_serializing_if = "Option::is_none")
132 )]
133 pub type_: Option<Nullable<Type>>,
135
136 #[cfg_attr(feature = "serde", serde(rename = "@context", default, skip_serializing_if = "Option::is_none"))]
137 pub context: Option<Box<context::Context>>,
139
140 #[cfg_attr(feature = "serde", serde(rename = "@reverse", default, skip_serializing_if = "Option::is_none"))]
141 pub reverse: Option<context::definition::Key>,
143
144 #[cfg_attr(feature = "serde", serde(rename = "@index", default, skip_serializing_if = "Option::is_none"))]
145 pub index: Option<Index>,
148
149 #[cfg_attr(
150 feature = "serde",
151 serde(rename = "@language", default, deserialize_with = "Nullable::optional", skip_serializing_if = "Option::is_none")
152 )]
153 pub language: Option<Nullable<LenientLangTagBuf>>,
155
156 #[cfg_attr(
157 feature = "serde",
158 serde(rename = "@direction", default, deserialize_with = "Nullable::optional", skip_serializing_if = "Option::is_none")
159 )]
160 pub direction: Option<Nullable<Direction>>,
162
163 #[cfg_attr(
164 feature = "serde",
165 serde(rename = "@container", default, deserialize_with = "Nullable::optional", skip_serializing_if = "Option::is_none")
166 )]
167 pub container: Option<Nullable<Container>>,
170
171 #[cfg_attr(feature = "serde", serde(rename = "@nest", default, skip_serializing_if = "Option::is_none"))]
172 pub nest: Option<Nest>,
174
175 #[cfg_attr(feature = "serde", serde(rename = "@prefix", default, skip_serializing_if = "Option::is_none"))]
176 pub prefix: Option<bool>,
179
180 #[cfg_attr(feature = "serde", serde(rename = "@propagate", default, skip_serializing_if = "Option::is_none"))]
181 pub propagate: Option<bool>,
183
184 #[cfg_attr(feature = "serde", serde(rename = "@protected", default, skip_serializing_if = "Option::is_none"))]
185 pub protected: Option<bool>,
187}
188
189impl Expanded {
190 #[must_use]
192 pub fn new() -> Self {
193 Self::default()
194 }
195
196 #[must_use]
199 pub fn is_null(&self) -> bool {
200 matches!(&self.id, None | Some(Nullable::Null))
201 && self.type_.is_none()
202 && self.context.is_none()
203 && self.reverse.is_none()
204 && self.index.is_none()
205 && self.language.is_none()
206 && self.direction.is_none()
207 && self.container.is_none()
208 && self.nest.is_none()
209 && self.prefix.is_none()
210 && self.propagate.is_none()
211 && self.protected.is_none()
212 }
213
214 #[must_use]
217 pub fn is_simple_definition(&self) -> bool {
218 matches!(&self.id, Some(Nullable::Some(_)))
219 && self.type_.is_none()
220 && self.context.is_none()
221 && self.reverse.is_none()
222 && self.index.is_none()
223 && self.language.is_none()
224 && self.direction.is_none()
225 && self.container.is_none()
226 && self.nest.is_none()
227 && self.prefix.is_none()
228 && self.propagate.is_none()
229 && self.protected.is_none()
230 }
231
232 #[must_use]
236 pub fn simplify(self) -> Nullable<TermDefinition> {
237 if self.is_null() {
238 return Nullable::Null;
239 }
240 match self {
241 Self {
242 id: Some(Nullable::Some(id)),
243 type_: None,
244 context: None,
245 reverse: None,
246 index: None,
247 language: None,
248 direction: None,
249 container: None,
250 nest: None,
251 prefix: None,
252 propagate: None,
253 protected: None,
254 } => Nullable::Some(TermDefinition::Simple(Simple(id.into_string()))),
255 other => Nullable::Some(TermDefinition::Expanded(Box::new(other))),
256 }
257 }
258
259 pub fn iter(&self) -> Entries<'_> {
262 Entries {
263 id: self.id.as_ref().map(Nullable::as_ref),
264 type_: self.type_.as_ref().map(Nullable::as_ref),
265 context: self.context.as_deref(),
266 reverse: self.reverse.as_ref(),
267 index: self.index.as_ref(),
268 language: self.language.as_ref().map(Nullable::as_ref),
269 direction: self.direction,
270 container: self.container.as_ref().map(Nullable::as_ref),
271 nest: self.nest.as_ref(),
272 prefix: self.prefix,
273 propagate: self.propagate,
274 protected: self.protected,
275 }
276 }
277
278 pub fn as_expanded_ref(&self) -> ExpandedRef<'_> {
280 ExpandedRef {
281 id: self.id.as_ref().map(|i| i.as_ref().map(|id| id.as_id_ref())),
282 type_: self.type_.as_ref().map(Nullable::as_ref),
283 context: self.context.as_deref(),
284 reverse: self.reverse.as_ref(),
285 index: self.index.as_ref(),
286 language: self.language.as_ref().map(|n| n.as_ref().map(LenientLangTagBuf::as_lenient_lang_tag_ref)),
287 direction: self.direction,
288 container: self.container.as_ref().map(Nullable::as_ref),
289 nest: self.nest.as_ref(),
290 prefix: self.prefix,
291 propagate: self.propagate,
292 protected: self.protected,
293 }
294 }
295}
296
297#[derive(Debug, Default)]
302pub struct ExpandedRef<'a> {
303 pub id: Option<Nullable<IdRef<'a>>>,
305 pub type_: Option<Nullable<&'a Type>>,
307 pub context: Option<&'a context::Context>,
309 pub reverse: Option<&'a context::definition::Key>,
311 pub index: Option<&'a Index>,
314 pub language: Option<Nullable<&'a LenientLangTag>>,
316 pub direction: Option<Nullable<Direction>>,
318 pub container: Option<Nullable<&'a Container>>,
321 pub nest: Option<&'a Nest>,
323 pub prefix: Option<bool>,
326 pub propagate: Option<bool>,
329 pub protected: Option<bool>,
331}
332
333impl<'a> From<Nullable<&'a TermDefinition>> for ExpandedRef<'a> {
334 fn from(value: Nullable<&'a TermDefinition>) -> Self {
335 match value {
336 Nullable::Some(d) => d.as_expanded(),
337 Nullable::Null => Self {
338 id: Some(Nullable::Null),
339 ..Default::default()
340 },
341 }
342 }
343}
344
345pub struct Entries<'a> {
347 id: Option<Nullable<&'a Id>>,
348 type_: Option<Nullable<&'a Type>>,
349 context: Option<&'a context::Context>,
350 reverse: Option<&'a context::definition::Key>,
351 index: Option<&'a Index>,
352 language: Option<Nullable<&'a LenientLangTagBuf>>,
353 direction: Option<Nullable<Direction>>,
354 container: Option<Nullable<&'a Container>>,
355 nest: Option<&'a Nest>,
356 prefix: Option<bool>,
357 propagate: Option<bool>,
358 protected: Option<bool>,
359}
360
361pub enum EntryRef<'a> {
363 Id(Nullable<&'a Id>),
365 Type(Nullable<&'a Type>),
367 Context(&'a context::Context),
369 Reverse(&'a context::definition::Key),
371 Index(&'a Index),
374 Language(Nullable<&'a LenientLangTagBuf>),
376 Direction(Nullable<Direction>),
378 Container(Nullable<&'a Container>),
381 Nest(&'a Nest),
383 Prefix(bool),
386 Propagate(bool),
388 Protected(bool),
390}
391
392impl<'a> EntryRef<'a> {
393 #[must_use]
395 pub fn into_key(self) -> EntryKey {
396 match self {
397 Self::Id(_) => EntryKey::Id,
398 Self::Type(_) => EntryKey::Type,
399 Self::Context(_) => EntryKey::Context,
400 Self::Reverse(_) => EntryKey::Reverse,
401 Self::Index(_) => EntryKey::Index,
402 Self::Language(_) => EntryKey::Language,
403 Self::Direction(_) => EntryKey::Direction,
404 Self::Container(_) => EntryKey::Container,
405 Self::Nest(_) => EntryKey::Nest,
406 Self::Prefix(_) => EntryKey::Prefix,
407 Self::Propagate(_) => EntryKey::Propagate,
408 Self::Protected(_) => EntryKey::Protected,
409 }
410 }
411
412 #[must_use]
414 pub fn key(&self) -> EntryKey {
415 match self {
416 Self::Id(_) => EntryKey::Id,
417 Self::Type(_) => EntryKey::Type,
418 Self::Context(_) => EntryKey::Context,
419 Self::Reverse(_) => EntryKey::Reverse,
420 Self::Index(_) => EntryKey::Index,
421 Self::Language(_) => EntryKey::Language,
422 Self::Direction(_) => EntryKey::Direction,
423 Self::Container(_) => EntryKey::Container,
424 Self::Nest(_) => EntryKey::Nest,
425 Self::Prefix(_) => EntryKey::Prefix,
426 Self::Propagate(_) => EntryKey::Propagate,
427 Self::Protected(_) => EntryKey::Protected,
428 }
429 }
430
431 #[must_use]
433 pub fn into_value(self) -> EntryValueRef<'a> {
434 self.value()
435 }
436
437 #[must_use]
439 pub fn value(&self) -> EntryValueRef<'a> {
440 match self {
441 Self::Id(e) => EntryValueRef::Id(*e),
442 Self::Type(e) => EntryValueRef::Type(*e),
443 Self::Context(e) => EntryValueRef::Context(e),
444 Self::Reverse(e) => EntryValueRef::Reverse(e),
445 Self::Index(e) => EntryValueRef::Index(e),
446 Self::Language(e) => EntryValueRef::Language(*e),
447 Self::Direction(e) => EntryValueRef::Direction(*e),
448 Self::Container(e) => EntryValueRef::Container(*e),
449 Self::Nest(e) => EntryValueRef::Nest(e),
450 Self::Prefix(e) => EntryValueRef::Prefix(*e),
451 Self::Propagate(e) => EntryValueRef::Propagate(*e),
452 Self::Protected(e) => EntryValueRef::Protected(*e),
453 }
454 }
455
456 #[must_use]
458 pub fn into_key_value(self) -> (EntryKey, EntryValueRef<'a>) {
459 self.key_value()
460 }
461
462 #[must_use]
464 pub fn key_value(&self) -> (EntryKey, EntryValueRef<'a>) {
465 match self {
466 Self::Id(e) => (EntryKey::Id, EntryValueRef::Id(*e)),
467 Self::Type(e) => (EntryKey::Type, EntryValueRef::Type(*e)),
468 Self::Context(e) => (EntryKey::Context, EntryValueRef::Context(e)),
469 Self::Reverse(e) => (EntryKey::Reverse, EntryValueRef::Reverse(e)),
470 Self::Index(e) => (EntryKey::Index, EntryValueRef::Index(e)),
471 Self::Language(e) => (EntryKey::Language, EntryValueRef::Language(*e)),
472 Self::Direction(e) => (EntryKey::Direction, EntryValueRef::Direction(*e)),
473 Self::Container(e) => (EntryKey::Container, EntryValueRef::Container(*e)),
474 Self::Nest(e) => (EntryKey::Nest, EntryValueRef::Nest(e)),
475 Self::Prefix(e) => (EntryKey::Prefix, EntryValueRef::Prefix(*e)),
476 Self::Propagate(e) => (EntryKey::Propagate, EntryValueRef::Propagate(*e)),
477 Self::Protected(e) => (EntryKey::Protected, EntryValueRef::Protected(*e)),
478 }
479 }
480}
481
482pub enum EntryKey {
484 Id,
486 Type,
488 Context,
490 Reverse,
492 Index,
495 Language,
497 Direction,
499 Container,
502 Nest,
504 Prefix,
507 Propagate,
509 Protected,
511}
512
513impl EntryKey {
514 #[must_use]
516 pub fn keyword(&self) -> Keyword {
517 match self {
518 Self::Id => Keyword::Id,
519 Self::Type => Keyword::Type,
520 Self::Context => Keyword::Context,
521 Self::Reverse => Keyword::Reverse,
522 Self::Index => Keyword::Index,
523 Self::Language => Keyword::Language,
524 Self::Direction => Keyword::Direction,
525 Self::Container => Keyword::Container,
526 Self::Nest => Keyword::Nest,
527 Self::Prefix => Keyword::Prefix,
528 Self::Propagate => Keyword::Propagate,
529 Self::Protected => Keyword::Protected,
530 }
531 }
532
533 #[must_use]
535 pub fn as_str(&self) -> &'static str {
536 self.keyword().into_str()
537 }
538}
539
540pub enum EntryValueRef<'a> {
542 Id(Nullable<&'a Id>),
544 Type(Nullable<&'a Type>),
546 Context(&'a context::Context),
548 Reverse(&'a context::definition::Key),
550 Index(&'a Index),
553 Language(Nullable<&'a LenientLangTagBuf>),
555 Direction(Nullable<Direction>),
557 Container(Nullable<&'a Container>),
560 Nest(&'a Nest),
562 Prefix(bool),
565 Propagate(bool),
567 Protected(bool),
569}
570
571impl EntryValueRef<'_> {
572 #[must_use]
575 pub fn is_object(&self) -> bool {
576 match self {
577 Self::Context(c) => c.is_object(),
578 _ => false,
579 }
580 }
581
582 #[must_use]
585 pub fn is_array(&self) -> bool {
586 match self {
587 Self::Container(Nullable::Some(c)) => c.is_array(),
588 _ => false,
589 }
590 }
591}
592
593impl<'a> Iterator for Entries<'a> {
594 type Item = EntryRef<'a>;
595
596 fn size_hint(&self) -> (usize, Option<usize>) {
597 let mut len = 0;
598
599 if self.id.is_some() {
600 len += 1;
601 }
602
603 if self.type_.is_some() {
604 len += 1;
605 }
606
607 if self.context.is_some() {
608 len += 1;
609 }
610
611 if self.reverse.is_some() {
612 len += 1;
613 }
614
615 if self.index.is_some() {
616 len += 1;
617 }
618
619 if self.language.is_some() {
620 len += 1;
621 }
622
623 if self.direction.is_some() {
624 len += 1;
625 }
626
627 if self.container.is_some() {
628 len += 1;
629 }
630
631 if self.nest.is_some() {
632 len += 1;
633 }
634
635 if self.prefix.is_some() {
636 len += 1;
637 }
638
639 if self.propagate.is_some() {
640 len += 1;
641 }
642
643 if self.protected.is_some() {
644 len += 1;
645 }
646
647 (len, Some(len))
648 }
649
650 fn next(&mut self) -> Option<Self::Item> {
651 match self.id.take() {
652 Some(value) => Some(EntryRef::Id(value)),
653 None => match self.type_.take() {
654 Some(value) => Some(EntryRef::Type(value)),
655 None => match self.context.take() {
656 Some(value) => Some(EntryRef::Context(value)),
657 None => match self.reverse.take() {
658 Some(value) => Some(EntryRef::Reverse(value)),
659 None => match self.index.take() {
660 Some(value) => Some(EntryRef::Index(value)),
661 None => match self.language.take() {
662 Some(value) => Some(EntryRef::Language(value)),
663 None => match self.direction.take() {
664 Some(value) => Some(EntryRef::Direction(value)),
665 None => match self.container.take() {
666 Some(value) => Some(EntryRef::Container(value)),
667 None => match self.nest.take() {
668 Some(value) => Some(EntryRef::Nest(value)),
669 None => match self.prefix.take() {
670 Some(value) => Some(EntryRef::Prefix(value)),
671 None => match self.propagate.take() {
672 Some(value) => Some(EntryRef::Propagate(value)),
673 None => self.protected.take().map(EntryRef::Protected),
674 },
675 },
676 },
677 },
678 },
679 },
680 },
681 },
682 },
683 },
684 }
685 }
686}
687
688impl ExactSizeIterator for Entries<'_> {}
689
690pub enum FragmentRef<'a> {
692 Entry(EntryRef<'a>),
694
695 Key(EntryKey),
697
698 Value(EntryValueRef<'a>),
700
701 ContainerFragment(&'a ContainerKind),
703}
704
705impl<'a> FragmentRef<'a> {
706 #[must_use]
708 pub fn is_key(&self) -> bool {
709 matches!(self, Self::Key(_))
710 }
711
712 #[must_use]
714 pub fn is_entry(&self) -> bool {
715 matches!(self, Self::Entry(_))
716 }
717
718 #[must_use]
720 pub fn is_array(&self) -> bool {
721 match self {
722 Self::Value(v) => v.is_array(),
723 _ => false,
724 }
725 }
726
727 #[must_use]
729 pub fn is_object(&self) -> bool {
730 match self {
731 Self::Value(v) => v.is_object(),
732 _ => false,
733 }
734 }
735
736 #[must_use]
738 pub fn sub_fragments(&self) -> SubFragments<'a> {
739 match self {
740 Self::Value(EntryValueRef::Container(Nullable::Some(c))) => SubFragments::Container(c.sub_fragments()),
741 _ => SubFragments::None,
742 }
743 }
744}
745
746pub enum SubFragments<'a> {
748 None,
750 Container(container::SubValues<'a>),
752}
753
754impl<'a> Iterator for SubFragments<'a> {
755 type Item = FragmentRef<'a>;
756
757 fn next(&mut self) -> Option<Self::Item> {
758 match self {
759 Self::None => None,
760 Self::Container(c) => c.next().map(FragmentRef::ContainerFragment),
761 }
762 }
763}