1use core::fmt;
7#[cfg(not(feature = "std"))]
8use alloc::{
9 collections::BTreeMap as HashMap,
10 string::{String, ToString},
11 vec::Vec,
12};
13
14use indexmap::IndexMap;
15
16#[derive(Debug, Clone, PartialEq)]
21pub enum RsonValue {
22 Null,
24
25 Bool(bool),
27
28 Int(i64),
30
31 Float(f64),
33
34 String(String),
36
37 Char(char),
39
40 Array(Vec<RsonValue>),
42
43 Map(IndexMap<String, RsonValue>),
45
46 Struct {
48 name: String,
49 fields: IndexMap<String, RsonValue>,
50 },
51
52 Tuple(Vec<RsonValue>),
54
55 Enum {
57 name: String,
58 variant: String,
59 value: Option<Box<RsonValue>>,
60 },
61
62 Option(Option<Box<RsonValue>>),
64}
65
66#[derive(Debug, Clone, Copy, PartialEq, Eq)]
68pub enum RsonType {
69 Null,
70 Bool,
71 Int,
72 Float,
73 String,
74 Char,
75 Array,
76 Map,
77 Struct,
78 Tuple,
79 Enum,
80 Option,
81}
82
83impl RsonValue {
84 pub fn value_type(&self) -> RsonType {
86 match self {
87 RsonValue::Null => RsonType::Null,
88 RsonValue::Bool(_) => RsonType::Bool,
89 RsonValue::Int(_) => RsonType::Int,
90 RsonValue::Float(_) => RsonType::Float,
91 RsonValue::String(_) => RsonType::String,
92 RsonValue::Char(_) => RsonType::Char,
93 RsonValue::Array(_) => RsonType::Array,
94 RsonValue::Map(_) => RsonType::Map,
95 RsonValue::Struct { .. } => RsonType::Struct,
96 RsonValue::Tuple(_) => RsonType::Tuple,
97 RsonValue::Enum { .. } => RsonType::Enum,
98 RsonValue::Option(_) => RsonType::Option,
99 }
100 }
101
102 pub fn is_null(&self) -> bool {
104 matches!(self, RsonValue::Null)
105 }
106
107 pub fn is_bool(&self) -> bool {
109 matches!(self, RsonValue::Bool(_))
110 }
111
112 pub fn is_number(&self) -> bool {
114 matches!(self, RsonValue::Int(_) | RsonValue::Float(_))
115 }
116
117 pub fn is_string(&self) -> bool {
119 matches!(self, RsonValue::String(_))
120 }
121
122 pub fn is_array(&self) -> bool {
124 matches!(self, RsonValue::Array(_))
125 }
126
127 pub fn is_object(&self) -> bool {
129 matches!(self, RsonValue::Map(_) | RsonValue::Struct { .. })
130 }
131
132 pub fn as_bool(&self) -> Option<bool> {
134 match self {
135 RsonValue::Bool(b) => Some(*b),
136 _ => None,
137 }
138 }
139
140 pub fn as_i64(&self) -> Option<i64> {
142 match self {
143 RsonValue::Int(i) => Some(*i),
144 RsonValue::Float(f) if f.fract() == 0.0 => Some(*f as i64),
145 _ => None,
146 }
147 }
148
149 pub fn as_f64(&self) -> Option<f64> {
151 match self {
152 RsonValue::Float(f) => Some(*f),
153 RsonValue::Int(i) => Some(*i as f64),
154 _ => None,
155 }
156 }
157
158 pub fn as_str(&self) -> Option<&str> {
160 match self {
161 RsonValue::String(s) => Some(s),
162 _ => None,
163 }
164 }
165
166 pub fn as_array(&self) -> Option<&Vec<RsonValue>> {
168 match self {
169 RsonValue::Array(arr) => Some(arr),
170 _ => None,
171 }
172 }
173
174 pub fn as_map(&self) -> Option<&IndexMap<String, RsonValue>> {
176 match self {
177 RsonValue::Map(map) => Some(map),
178 _ => None,
179 }
180 }
181
182 pub fn get_index(&self, index: usize) -> Option<&RsonValue> {
184 match self {
185 RsonValue::Array(arr) => arr.get(index),
186 RsonValue::Tuple(arr) => arr.get(index),
187 _ => None,
188 }
189 }
190
191 pub fn get(&self, key: &str) -> Option<&RsonValue> {
193 match self {
194 RsonValue::Map(map) => map.get(key),
195 RsonValue::Struct { fields, .. } => fields.get(key),
196 _ => None,
197 }
198 }
199
200 pub fn some(value: RsonValue) -> Self {
202 RsonValue::Option(Some(Box::new(value)))
203 }
204
205 pub fn none() -> Self {
207 RsonValue::Option(None)
208 }
209}
210
211impl fmt::Display for RsonValue {
212 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
213 match self {
214 RsonValue::Null => write!(f, "null"),
215 RsonValue::Bool(b) => write!(f, "{}", b),
216 RsonValue::Int(i) => write!(f, "{}", i),
217 RsonValue::Float(fl) => write!(f, "{}", fl),
218 RsonValue::String(s) => write!(f, "\"{}\"", s),
219 RsonValue::Char(c) => write!(f, "'{}'", c),
220 RsonValue::Array(arr) => {
221 write!(f, "[")?;
222 for (i, item) in arr.iter().enumerate() {
223 if i > 0 { write!(f, ", ")?; }
224 write!(f, "{}", item)?;
225 }
226 write!(f, "]")
227 }
228 RsonValue::Map(map) => {
229 write!(f, "{{")?;
230 for (i, (key, value)) in map.iter().enumerate() {
231 if i > 0 { write!(f, ", ")?; }
232 write!(f, "{}: {}", key, value)?;
233 }
234 write!(f, "}}")
235 }
236 RsonValue::Struct { name, fields } => {
237 write!(f, "{}(", name)?;
238 for (i, (key, value)) in fields.iter().enumerate() {
239 if i > 0 { write!(f, ", ")?; }
240 write!(f, "{}: {}", key, value)?;
241 }
242 write!(f, ")")
243 }
244 RsonValue::Tuple(values) => {
245 write!(f, "(")?;
246 for (i, value) in values.iter().enumerate() {
247 if i > 0 { write!(f, ", ")?; }
248 write!(f, "{}", value)?;
249 }
250 write!(f, ")")
251 }
252 RsonValue::Enum { name, variant, value } => {
253 write!(f, "{}::{}", name, variant)?;
254 if let Some(val) = value {
255 write!(f, "({})", val)?;
256 }
257 Ok(())
258 }
259 RsonValue::Option(Some(value)) => write!(f, "Some({})", value),
260 RsonValue::Option(None) => write!(f, "None"),
261 }
262 }
263}
264
265impl fmt::Display for RsonType {
266 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
267 match self {
268 RsonType::Null => write!(f, "null"),
269 RsonType::Bool => write!(f, "bool"),
270 RsonType::Int => write!(f, "int"),
271 RsonType::Float => write!(f, "float"),
272 RsonType::String => write!(f, "string"),
273 RsonType::Char => write!(f, "char"),
274 RsonType::Array => write!(f, "array"),
275 RsonType::Map => write!(f, "map"),
276 RsonType::Struct => write!(f, "struct"),
277 RsonType::Tuple => write!(f, "tuple"),
278 RsonType::Enum => write!(f, "enum"),
279 RsonType::Option => write!(f, "option"),
280 }
281 }
282}
283
284impl From<bool> for RsonValue {
286 fn from(b: bool) -> Self {
287 RsonValue::Bool(b)
288 }
289}
290
291impl From<i32> for RsonValue {
292 fn from(i: i32) -> Self {
293 RsonValue::Int(i as i64)
294 }
295}
296
297impl From<i64> for RsonValue {
298 fn from(i: i64) -> Self {
299 RsonValue::Int(i)
300 }
301}
302
303impl From<f64> for RsonValue {
304 fn from(f: f64) -> Self {
305 RsonValue::Float(f)
306 }
307}
308
309impl From<String> for RsonValue {
310 fn from(s: String) -> Self {
311 RsonValue::String(s)
312 }
313}
314
315impl From<&str> for RsonValue {
316 fn from(s: &str) -> Self {
317 RsonValue::String(s.to_string())
318 }
319}
320
321impl From<char> for RsonValue {
322 fn from(c: char) -> Self {
323 RsonValue::Char(c)
324 }
325}
326
327impl<T: Into<RsonValue>> From<Vec<T>> for RsonValue {
328 fn from(vec: Vec<T>) -> Self {
329 RsonValue::Array(vec.into_iter().map(Into::into).collect())
330 }
331}
332
333impl<T: Into<RsonValue>> From<Option<T>> for RsonValue {
334 fn from(opt: Option<T>) -> Self {
335 RsonValue::Option(opt.map(|v| Box::new(v.into())))
336 }
337}