json_ld_syntax/
container.rs

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 {
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}