json_ld_syntax/
container.rs1use 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 {
6 #[cfg_attr(feature = "serde", serde(rename = "@graph"))]
7 Graph,
8
9 #[cfg_attr(feature = "serde", serde(rename = "@id"))]
10 Id,
11
12 #[cfg_attr(feature = "serde", serde(rename = "@index"))]
13 Index,
14
15 #[cfg_attr(feature = "serde", serde(rename = "@language"))]
16 Language,
17
18 #[cfg_attr(feature = "serde", serde(rename = "@list"))]
19 List,
20
21 #[cfg_attr(feature = "serde", serde(rename = "@set"))]
22 Set,
23
24 #[cfg_attr(feature = "serde", serde(rename = "@type"))]
25 Type,
26}
27
28impl ContainerKind {
29 pub fn into_keyword(self) -> Keyword {
30 self.into()
31 }
32
33 pub fn keyword(&self) -> Keyword {
34 self.into_keyword()
35 }
36
37 pub fn as_str(&self) -> &'static str {
38 self.into_keyword().into_str()
39 }
40}
41
42impl<'a> TryFrom<&'a str> for ContainerKind {
43 type Error = &'a str;
44
45 fn try_from(str: &'a str) -> Result<ContainerKind, &'a str> {
46 use ContainerKind::*;
47 match str {
48 "@graph" => Ok(Graph),
49 "@id" => Ok(Id),
50 "@index" => Ok(Index),
51 "@language" => Ok(Language),
52 "@list" => Ok(List),
53 "@set" => Ok(Set),
54 "@type" => Ok(Type),
55 _ => Err(str),
56 }
57 }
58}
59
60impl TryFrom<Keyword> for ContainerKind {
61 type Error = Keyword;
62
63 fn try_from(k: Keyword) -> Result<ContainerKind, Keyword> {
64 use ContainerKind::*;
65 match k {
66 Keyword::Graph => Ok(Graph),
67 Keyword::Id => Ok(Id),
68 Keyword::Index => Ok(Index),
69 Keyword::Language => Ok(Language),
70 Keyword::List => Ok(List),
71 Keyword::Set => Ok(Set),
72 Keyword::Type => Ok(Type),
73 k => Err(k),
74 }
75 }
76}
77
78impl From<ContainerKind> for Keyword {
79 fn from(c: ContainerKind) -> Keyword {
80 use ContainerKind::*;
81 match c {
82 Graph => Keyword::Graph,
83 Id => Keyword::Id,
84 Index => Keyword::Index,
85 Language => Keyword::Language,
86 List => Keyword::List,
87 Set => Keyword::Set,
88 Type => Keyword::Type,
89 }
90 }
91}
92
93impl From<ContainerKind> for Container {
94 fn from(c: ContainerKind) -> Self {
95 Container::One(c)
96 }
97}
98
99#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
100#[cfg_attr(
101 feature = "serde",
102 derive(serde::Serialize, serde::Deserialize),
103 serde(untagged)
104)]
105pub enum Container {
106 One(ContainerKind),
107 Many(Vec<ContainerKind>),
108}
109
110impl Container {
111 pub fn is_array(&self) -> bool {
112 matches!(self, Self::Many(_))
113 }
114
115 pub fn sub_fragments(&self) -> SubValues {
116 match self {
117 Self::One(_) => SubValues::None,
118 Self::Many(m) => SubValues::Many(m.iter()),
119 }
120 }
121}
122
123pub enum SubValues<'a> {
124 None,
125 Many(std::slice::Iter<'a, ContainerKind>),
126}
127
128impl<'a> Iterator for SubValues<'a> {
129 type Item = &'a ContainerKind;
130
131 fn size_hint(&self) -> (usize, Option<usize>) {
132 match self {
133 Self::None => (0, Some(0)),
134 Self::Many(m) => m.size_hint(),
135 }
136 }
137
138 fn next(&mut self) -> Option<Self::Item> {
139 match self {
140 Self::None => None,
141 Self::Many(m) => m.next(),
142 }
143 }
144}
145
146impl<'a> ExactSizeIterator for SubValues<'a> {}
147
148impl<'a> DoubleEndedIterator for SubValues<'a> {
149 fn next_back(&mut self) -> Option<Self::Item> {
150 match self {
151 Self::None => None,
152 Self::Many(m) => m.next_back(),
153 }
154 }
155}