1use crate::Keyword;
2
3#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
4#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5pub enum ContainerKind {
7 #[cfg_attr(feature = "serde", serde(rename = "@graph"))]
8 Graph,
10
11 #[cfg_attr(feature = "serde", serde(rename = "@id"))]
12 Id,
14
15 #[cfg_attr(feature = "serde", serde(rename = "@index"))]
16 Index,
19
20 #[cfg_attr(feature = "serde", serde(rename = "@language"))]
21 Language,
24
25 #[cfg_attr(feature = "serde", serde(rename = "@list"))]
26 List,
28
29 #[cfg_attr(feature = "serde", serde(rename = "@set"))]
30 Set,
32
33 #[cfg_attr(feature = "serde", serde(rename = "@type"))]
34 Type,
36}
37
38impl ContainerKind {
39 #[must_use]
41 pub fn into_keyword(self) -> Keyword {
42 self.into()
43 }
44
45 #[must_use]
47 pub fn keyword(&self) -> Keyword {
48 self.into_keyword()
49 }
50
51 #[must_use]
54 pub fn as_str(&self) -> &'static str {
55 self.into_keyword().into_str()
56 }
57}
58
59impl<'a> TryFrom<&'a str> for ContainerKind {
60 type Error = &'a str;
61
62 fn try_from(str: &'a str) -> Result<ContainerKind, &'a str> {
63 use ContainerKind::{Graph, Id, Index, Language, List, Set, Type};
64 match str {
65 "@graph" => Ok(Graph),
66 "@id" => Ok(Id),
67 "@index" => Ok(Index),
68 "@language" => Ok(Language),
69 "@list" => Ok(List),
70 "@set" => Ok(Set),
71 "@type" => Ok(Type),
72 _ => Err(str),
73 }
74 }
75}
76
77impl TryFrom<Keyword> for ContainerKind {
78 type Error = Keyword;
79
80 fn try_from(k: Keyword) -> Result<ContainerKind, Keyword> {
81 use ContainerKind::{Graph, Id, Index, Language, List, Set, Type};
82 match k {
83 Keyword::Graph => Ok(Graph),
84 Keyword::Id => Ok(Id),
85 Keyword::Index => Ok(Index),
86 Keyword::Language => Ok(Language),
87 Keyword::List => Ok(List),
88 Keyword::Set => Ok(Set),
89 Keyword::Type => Ok(Type),
90 k => Err(k),
91 }
92 }
93}
94
95impl From<ContainerKind> for Keyword {
96 fn from(c: ContainerKind) -> Keyword {
97 use ContainerKind::{Graph, Id, Index, Language, List, Set, Type};
98 match c {
99 Graph => Keyword::Graph,
100 Id => Keyword::Id,
101 Index => Keyword::Index,
102 Language => Keyword::Language,
103 List => Keyword::List,
104 Set => Keyword::Set,
105 Type => Keyword::Type,
106 }
107 }
108}
109
110impl From<ContainerKind> for Container {
111 fn from(c: ContainerKind) -> Self {
112 Container::One(c)
113 }
114}
115
116#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
117#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(untagged))]
118pub enum Container {
120 One(ContainerKind),
122 Many(Vec<ContainerKind>),
124}
125
126impl Container {
127 #[must_use]
129 pub fn is_array(&self) -> bool {
130 matches!(self, Self::Many(_))
131 }
132
133 #[must_use]
138 pub fn sub_fragments(&self) -> SubValues<'_> {
139 match self {
140 Self::One(_) => SubValues::None,
141 Self::Many(m) => SubValues::Many(m.iter()),
142 }
143 }
144}
145
146pub enum SubValues<'a> {
148 None,
150 Many(std::slice::Iter<'a, ContainerKind>),
152}
153
154impl<'a> Iterator for SubValues<'a> {
155 type Item = &'a ContainerKind;
156
157 fn size_hint(&self) -> (usize, Option<usize>) {
158 match self {
159 Self::None => (0, Some(0)),
160 Self::Many(m) => m.size_hint(),
161 }
162 }
163
164 fn next(&mut self) -> Option<Self::Item> {
165 match self {
166 Self::None => None,
167 Self::Many(m) => m.next(),
168 }
169 }
170}
171
172impl ExactSizeIterator for SubValues<'_> {}
173
174impl DoubleEndedIterator for SubValues<'_> {
175 fn next_back(&mut self) -> Option<Self::Item> {
176 match self {
177 Self::None => None,
178 Self::Many(m) => m.next_back(),
179 }
180 }
181}