1use std::{
2 collections::HashMap,
3 fmt::{Debug, Display, Formatter},
4};
5
6#[derive(Debug, Clone, PartialEq)]
7#[cfg_attr(
8 feature = "rkyv",
9 derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize),
10 rkyv(derive(Debug)),
11 rkyv(serialize_bounds(
12 __S: rkyv::ser::Writer + rkyv::ser::Allocator,
13 __S::Error: rkyv::rancor::Source,
14 )),
15 rkyv(deserialize_bounds(__D::Error: rkyv::rancor::Source)),
16 rkyv(bytecheck(bounds(__C: rkyv::validation::ArchiveContext))),
17)]
18pub enum Input {
19 Bool(bool),
20 Int(isize),
21 Float(f64),
22 Str(String),
23 List(#[cfg_attr(feature = "rkyv", rkyv(omit_bounds))] Vec<Input>),
24 Map(#[cfg_attr(feature = "rkyv", rkyv(omit_bounds))] HashMap<String, Input>),
25}
26
27impl Input {
28 pub fn new_map() -> Self {
29 Self::Map(HashMap::new())
30 }
31
32 pub fn new_list() -> Self {
33 Self::List(Vec::new())
34 }
35
36 pub fn new_str() -> Self {
37 Self::Str(String::new())
38 }
39
40 pub fn is_bool(&self) -> bool {
41 matches!(self, Self::Bool(_))
42 }
43
44 pub fn as_bool(&self) -> Option<&bool> {
45 match self {
46 Self::Bool(value) => Some(value),
47 _ => None,
48 }
49 }
50
51 pub fn into_bool(self) -> Option<bool> {
52 match self {
53 Self::Bool(value) => Some(value),
54 _ => None,
55 }
56 }
57
58 pub fn bool_mut(&mut self) -> Option<&mut bool> {
59 match self {
60 Self::Bool(value) => Some(value),
61 _ => None,
62 }
63 }
64
65 pub fn is_int(&self) -> bool {
66 matches!(self, Self::Int(_))
67 }
68
69 pub fn as_int(&self) -> Option<&isize> {
70 match self {
71 Self::Int(value) => Some(value),
72 _ => None,
73 }
74 }
75
76 pub fn into_int(self) -> Option<isize> {
77 match self {
78 Self::Int(value) => Some(value),
79 _ => None,
80 }
81 }
82
83 pub fn int_mut(&mut self) -> Option<&mut isize> {
84 match self {
85 Self::Int(value) => Some(value),
86 _ => None,
87 }
88 }
89
90 pub fn is_float(&self) -> bool {
91 matches!(self, Self::Float(_))
92 }
93
94 pub fn as_float(&self) -> Option<&f64> {
95 match self {
96 Self::Float(value) => Some(value),
97 _ => None,
98 }
99 }
100
101 pub fn into_float(self) -> Option<f64> {
102 match self {
103 Self::Float(value) => Some(value),
104 _ => None,
105 }
106 }
107
108 pub fn float_mut(&mut self) -> Option<&mut f64> {
109 match self {
110 Self::Float(value) => Some(value),
111 _ => None,
112 }
113 }
114
115 pub fn is_str(&self) -> bool {
116 matches!(self, Self::Str(_))
117 }
118
119 pub fn as_str(&self) -> Option<&String> {
120 match self {
121 Self::Str(value) => Some(value),
122 _ => None,
123 }
124 }
125
126 pub fn into_str(self) -> Option<String> {
127 match self {
128 Self::Str(value) => Some(value),
129 _ => None,
130 }
131 }
132
133 pub fn str_mut(&mut self) -> Option<&mut String> {
134 match self {
135 Self::Str(value) => Some(value),
136 _ => None,
137 }
138 }
139
140 pub fn is_list(&self) -> bool {
141 matches!(self, Self::List(_))
142 }
143
144 pub fn as_list(&self) -> Option<&Vec<Input>> {
145 match self {
146 Self::List(value) => Some(value),
147 _ => None,
148 }
149 }
150
151 pub fn into_list(self) -> Option<Vec<Input>> {
152 match self {
153 Self::List(value) => Some(value),
154 _ => None,
155 }
156 }
157
158 pub fn list_mut(&mut self) -> Option<&mut Vec<Input>> {
159 match self {
160 Self::List(value) => Some(value),
161 _ => None,
162 }
163 }
164
165 pub fn is_map(&self) -> bool {
166 matches!(self, Self::Map(_))
167 }
168
169 pub fn as_map(&self) -> Option<&HashMap<String, Input>> {
170 match self {
171 Self::Map(value) => Some(value),
172 _ => None,
173 }
174 }
175
176 pub fn into_map(self) -> Option<HashMap<String, Input>> {
177 match self {
178 Self::Map(value) => Some(value),
179 _ => None,
180 }
181 }
182
183 pub fn map_mut(&mut self) -> Option<&mut HashMap<String, Input>> {
184 match self {
185 Self::Map(value) => Some(value),
186 _ => None,
187 }
188 }
189
190 pub fn type_name(&self) -> String {
191 match self {
192 Self::Bool(_) => Self::bool_type_name(),
193 Self::Int(_) => Self::int_type_name(),
194 Self::Float(_) => Self::float_type_name(),
195 Self::Str(_) => Self::str_type_name(),
196 Self::List(_) => Self::list_type_name(),
197 Self::Map(_) => Self::map_type_name(),
198 }
199 }
200
201 pub fn map_type_name() -> String {
202 "map".to_string()
203 }
204
205 pub fn list_type_name() -> String {
206 "list".to_string()
207 }
208
209 pub fn str_type_name() -> String {
210 "string".to_string()
211 }
212
213 pub fn int_type_name() -> String {
214 "integer".to_string()
215 }
216
217 pub fn float_type_name() -> String {
218 "float".to_string()
219 }
220
221 pub fn bool_type_name() -> String {
222 "boolean".to_string()
223 }
224}
225
226impl Display for Input {
227 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
228 match self {
229 Self::Bool(value) => write!(f, "{value}"),
230 Self::Int(value) => write!(f, "{value}"),
231 Self::Float(value) => write!(f, "{value}"),
232 Self::Str(value) => write!(f, "{value:?}"),
233 Self::List(value) => {
234 write!(f, "[")?;
235 let length = value.len();
236 for (index, inner_value) in value.iter().enumerate() {
237 write!(f, "{inner_value}")?;
238 if index < length - 1 {
239 write!(f, ", ")?;
240 }
241 }
242 write!(f, "]")
243 }
244 Self::Map(value) => {
245 write!(f, "{{")?;
246 let length = value.len();
247 for (index, (key, value)) in value.iter().enumerate() {
248 write!(f, "{key:?}: {value}")?;
249 if index < length - 1 {
250 write!(f, ", ")?;
251 }
252 }
253 write!(f, "}}")
254 }
255 }
256 }
257}