1#[cfg(feature = "derive")]
8#[doc(hidden)]
9pub use avila_serde_derive::Serialize as SerializeMacro;
10#[cfg(feature = "derive")]
11#[doc(hidden)]
12pub use avila_serde_derive::Deserialize as DeserializeMacro;
13
14use std::collections::HashMap;
15use std::fmt;
16
17pub trait Serialize {
23 fn to_value(&self) -> Value;
24
25 fn to_json(&self) -> String {
26 self.to_value().to_json()
27 }
28
29 fn to_json_pretty(&self) -> String {
30 self.to_value().to_json_pretty()
31 }
32}
33
34pub trait Deserialize: Sized {
36 fn from_value(value: Value) -> Result<Self, Error>;
37
38 fn from_json(json: &str) -> Result<Self, Error> {
39 let value = Value::from_json(json)?;
40 Self::from_value(value)
41 }
42}
43
44impl Serialize for bool {
49 fn to_value(&self) -> Value {
50 Value::Bool(*self)
51 }
52}
53
54impl Deserialize for bool {
55 fn from_value(value: Value) -> Result<Self, Error> {
56 match value {
57 Value::Bool(b) => Ok(b),
58 _ => Err(Error::TypeMismatch("bool")),
59 }
60 }
61}
62
63impl Serialize for f64 {
64 fn to_value(&self) -> Value {
65 Value::Number(*self)
66 }
67}
68
69impl Deserialize for f64 {
70 fn from_value(value: Value) -> Result<Self, Error> {
71 match value {
72 Value::Number(n) => Ok(n),
73 _ => Err(Error::TypeMismatch("number")),
74 }
75 }
76}
77
78impl Serialize for i32 {
79 fn to_value(&self) -> Value {
80 Value::Number(*self as f64)
81 }
82}
83
84impl Deserialize for i32 {
85 fn from_value(value: Value) -> Result<Self, Error> {
86 match value {
87 Value::Number(n) => Ok(n as i32),
88 _ => Err(Error::TypeMismatch("number")),
89 }
90 }
91}
92
93impl Serialize for u64 {
94 fn to_value(&self) -> Value {
95 Value::Number(*self as f64)
96 }
97}
98
99impl Deserialize for u64 {
100 fn from_value(value: Value) -> Result<Self, Error> {
101 match value {
102 Value::Number(n) => Ok(n as u64),
103 _ => Err(Error::TypeMismatch("number")),
104 }
105 }
106}
107
108impl Serialize for usize {
109 fn to_value(&self) -> Value {
110 Value::Number(*self as f64)
111 }
112}
113
114impl Deserialize for usize {
115 fn from_value(value: Value) -> Result<Self, Error> {
116 match value {
117 Value::Number(n) => Ok(n as usize),
118 _ => Err(Error::TypeMismatch("number")),
119 }
120 }
121}
122
123impl Serialize for String {
124 fn to_value(&self) -> Value {
125 Value::String(self.clone())
126 }
127}
128
129impl Deserialize for String {
130 fn from_value(value: Value) -> Result<Self, Error> {
131 match value {
132 Value::String(s) => Ok(s),
133 _ => Err(Error::TypeMismatch("string")),
134 }
135 }
136}
137
138impl<T: Serialize> Serialize for Vec<T> {
139 fn to_value(&self) -> Value {
140 Value::Array(self.iter().map(|item| item.to_value()).collect())
141 }
142}
143
144impl<T: Deserialize> Deserialize for Vec<T> {
145 fn from_value(value: Value) -> Result<Self, Error> {
146 match value {
147 Value::Array(arr) => {
148 arr.into_iter()
149 .map(|v| T::from_value(v))
150 .collect()
151 }
152 _ => Err(Error::TypeMismatch("array")),
153 }
154 }
155}
156
157impl<T: Serialize> Serialize for Option<T> {
158 fn to_value(&self) -> Value {
159 match self {
160 Some(value) => value.to_value(),
161 None => Value::Null,
162 }
163 }
164}
165
166impl<T: Deserialize> Deserialize for Option<T> {
167 fn from_value(value: Value) -> Result<Self, Error> {
168 match value {
169 Value::Null => Ok(None),
170 _ => Ok(Some(T::from_value(value)?)),
171 }
172 }
173}
174
175impl<K: ToString, V: Serialize> Serialize for HashMap<K, V> {
176 fn to_value(&self) -> Value {
177 let mut map = HashMap::new();
178 for (k, v) in self {
179 map.insert(k.to_string(), v.to_value());
180 }
181 Value::Object(map)
182 }
183}
184
185impl<V: Deserialize> Deserialize for HashMap<String, V> {
186 fn from_value(value: Value) -> Result<Self, Error> {
187 match value {
188 Value::Object(obj) => {
189 obj.into_iter()
190 .map(|(k, v)| Ok((k, V::from_value(v)?)))
191 .collect()
192 }
193 _ => Err(Error::TypeMismatch("object")),
194 }
195 }
196}
197
198#[derive(Debug, Clone, PartialEq)]
200pub enum Value {
201 Null,
202 Bool(bool),
203 Number(f64),
204 String(String),
205 Array(Vec<Value>),
206 Object(HashMap<String, Value>),
207}
208
209impl Value {
210 pub fn from_json(json: &str) -> Result<Self, Error> {
212 let mut parser = Parser::new(json);
213 parser.parse()
214 }
215
216 pub fn to_json(&self) -> String {
218 match self {
219 Value::Null => "null".to_string(),
220 Value::Bool(b) => b.to_string(),
221 Value::Number(n) => {
222 if n.is_finite() {
223 format!("{}", n)
224 } else {
225 "null".to_string()
226 }
227 }
228 Value::String(s) => format!("\"{}\"", escape_string(s)),
229 Value::Array(arr) => {
230 let items: Vec<String> = arr.iter().map(|v| v.to_json()).collect();
231 format!("[{}]", items.join(","))
232 }
233 Value::Object(obj) => {
234 let pairs: Vec<String> = obj
235 .iter()
236 .map(|(k, v)| format!("\"{}\":{}", escape_string(k), v.to_json()))
237 .collect();
238 format!("{{{}}}", pairs.join(","))
239 }
240 }
241 }
242
243 pub fn to_json_pretty(&self) -> String {
245 self.to_json_pretty_indent(0)
246 }
247
248 fn to_json_pretty_indent(&self, indent: usize) -> String {
249 let ind = " ".repeat(indent);
250 let ind_next = " ".repeat(indent + 1);
251
252 match self {
253 Value::Array(arr) if arr.is_empty() => "[]".to_string(),
254 Value::Array(arr) => {
255 let items: Vec<String> = arr
256 .iter()
257 .map(|v| format!("{}{}", ind_next, v.to_json_pretty_indent(indent + 1)))
258 .collect();
259 format!("[\n{}\n{}]", items.join(",\n"), ind)
260 }
261 Value::Object(obj) if obj.is_empty() => "{}".to_string(),
262 Value::Object(obj) => {
263 let pairs: Vec<String> = obj
264 .iter()
265 .map(|(k, v)| {
266 format!(
267 "{}\"{}\": {}",
268 ind_next,
269 escape_string(k),
270 v.to_json_pretty_indent(indent + 1)
271 )
272 })
273 .collect();
274 format!("{{\n{}\n{}}}", pairs.join(",\n"), ind)
275 }
276 _ => self.to_json(),
277 }
278 }
279
280 pub fn as_str(&self) -> Option<&str> {
282 match self {
283 Value::String(s) => Some(s),
284 _ => None,
285 }
286 }
287
288 pub fn as_f64(&self) -> Option<f64> {
290 match self {
291 Value::Number(n) => Some(*n),
292 _ => None,
293 }
294 }
295
296 pub fn as_bool(&self) -> Option<bool> {
298 match self {
299 Value::Bool(b) => Some(*b),
300 _ => None,
301 }
302 }
303
304 pub fn as_array(&self) -> Option<&Vec<Value>> {
306 match self {
307 Value::Array(arr) => Some(arr),
308 _ => None,
309 }
310 }
311
312 pub fn as_object(&self) -> Option<&HashMap<String, Value>> {
314 match self {
315 Value::Object(obj) => Some(obj),
316 _ => None,
317 }
318 }
319}
320
321fn escape_string(s: &str) -> String {
322 s.replace('\\', "\\\\")
323 .replace('\"', "\\\"")
324 .replace('\n', "\\n")
325 .replace('\r', "\\r")
326 .replace('\t', "\\t")
327}
328
329struct Parser {
330 chars: Vec<char>,
331 pos: usize,
332}
333
334impl Parser {
335 fn new(input: &str) -> Self {
336 Self {
337 chars: input.chars().collect(),
338 pos: 0,
339 }
340 }
341
342 fn parse(&mut self) -> Result<Value, Error> {
343 self.skip_whitespace();
344 self.parse_value()
345 }
346
347 fn parse_value(&mut self) -> Result<Value, Error> {
348 self.skip_whitespace();
349
350 if self.pos >= self.chars.len() {
351 return Err(Error::UnexpectedEnd);
352 }
353
354 match self.chars[self.pos] {
355 'n' => self.parse_null(),
356 't' | 'f' => self.parse_bool(),
357 '\"' => self.parse_string(),
358 '[' => self.parse_array(),
359 '{' => self.parse_object(),
360 '-' | '0'..='9' => self.parse_number(),
361 _ => Err(Error::InvalidChar(self.chars[self.pos])),
362 }
363 }
364
365 fn parse_null(&mut self) -> Result<Value, Error> {
366 if self.consume_word("null") {
367 Ok(Value::Null)
368 } else {
369 Err(Error::InvalidLiteral)
370 }
371 }
372
373 fn parse_bool(&mut self) -> Result<Value, Error> {
374 if self.consume_word("true") {
375 Ok(Value::Bool(true))
376 } else if self.consume_word("false") {
377 Ok(Value::Bool(false))
378 } else {
379 Err(Error::InvalidLiteral)
380 }
381 }
382
383 fn parse_string(&mut self) -> Result<Value, Error> {
384 self.consume_char('\"')?;
385 let mut s = String::new();
386
387 while self.pos < self.chars.len() && self.chars[self.pos] != '\"' {
388 if self.chars[self.pos] == '\\' {
389 self.pos += 1;
390 if self.pos >= self.chars.len() {
391 return Err(Error::UnexpectedEnd);
392 }
393 match self.chars[self.pos] {
394 'n' => s.push('\n'),
395 't' => s.push('\t'),
396 'r' => s.push('\r'),
397 '\"' => s.push('\"'),
398 '\\' => s.push('\\'),
399 _ => s.push(self.chars[self.pos]),
400 }
401 } else {
402 s.push(self.chars[self.pos]);
403 }
404 self.pos += 1;
405 }
406
407 self.consume_char('\"')?;
408 Ok(Value::String(s))
409 }
410
411 fn parse_number(&mut self) -> Result<Value, Error> {
412 let start = self.pos;
413
414 if self.chars[self.pos] == '-' {
415 self.pos += 1;
416 }
417
418 while self.pos < self.chars.len() && (self.chars[self.pos].is_numeric() || self.chars[self.pos] == '.') {
419 self.pos += 1;
420 }
421
422 let num_str: String = self.chars[start..self.pos].iter().collect();
423 num_str
424 .parse::<f64>()
425 .map(Value::Number)
426 .map_err(|_| Error::InvalidNumber)
427 }
428
429 fn parse_array(&mut self) -> Result<Value, Error> {
430 self.consume_char('[')?;
431 let mut arr = Vec::new();
432
433 self.skip_whitespace();
434 if self.pos < self.chars.len() && self.chars[self.pos] == ']' {
435 self.pos += 1;
436 return Ok(Value::Array(arr));
437 }
438
439 loop {
440 arr.push(self.parse_value()?);
441 self.skip_whitespace();
442
443 if self.pos >= self.chars.len() {
444 return Err(Error::UnexpectedEnd);
445 }
446
447 if self.chars[self.pos] == ']' {
448 self.pos += 1;
449 break;
450 }
451
452 self.consume_char(',')?;
453 }
454
455 Ok(Value::Array(arr))
456 }
457
458 fn parse_object(&mut self) -> Result<Value, Error> {
459 self.consume_char('{')?;
460 let mut obj = HashMap::new();
461
462 self.skip_whitespace();
463 if self.pos < self.chars.len() && self.chars[self.pos] == '}' {
464 self.pos += 1;
465 return Ok(Value::Object(obj));
466 }
467
468 loop {
469 self.skip_whitespace();
470 let key = match self.parse_string()? {
471 Value::String(s) => s,
472 _ => return Err(Error::ExpectedString),
473 };
474
475 self.skip_whitespace();
476 self.consume_char(':')?;
477
478 let value = self.parse_value()?;
479 obj.insert(key, value);
480
481 self.skip_whitespace();
482 if self.pos >= self.chars.len() {
483 return Err(Error::UnexpectedEnd);
484 }
485
486 if self.chars[self.pos] == '}' {
487 self.pos += 1;
488 break;
489 }
490
491 self.consume_char(',')?;
492 }
493
494 Ok(Value::Object(obj))
495 }
496
497 fn consume_char(&mut self, expected: char) -> Result<(), Error> {
498 if self.pos >= self.chars.len() {
499 return Err(Error::UnexpectedEnd);
500 }
501 if self.chars[self.pos] != expected {
502 return Err(Error::ExpectedChar(expected));
503 }
504 self.pos += 1;
505 Ok(())
506 }
507
508 fn consume_word(&mut self, word: &str) -> bool {
509 let end = self.pos + word.len();
510 if end > self.chars.len() {
511 return false;
512 }
513
514 let slice: String = self.chars[self.pos..end].iter().collect();
515 if slice == word {
516 self.pos = end;
517 true
518 } else {
519 false
520 }
521 }
522
523 fn skip_whitespace(&mut self) {
524 while self.pos < self.chars.len() && self.chars[self.pos].is_whitespace() {
525 self.pos += 1;
526 }
527 }
528}
529
530#[derive(Debug, Clone)]
531pub enum Error {
532 UnexpectedEnd,
533 InvalidChar(char),
534 InvalidLiteral,
535 InvalidNumber,
536 ExpectedChar(char),
537 ExpectedString,
538 ExpectedObject,
539 TypeMismatch(&'static str),
540 MissingField(String),
541 Parse(String),
542 NotImplemented,
543}
544
545impl fmt::Display for Error {
546 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
547 match self {
548 Error::UnexpectedEnd => write!(f, "Unexpected end of input"),
549 Error::InvalidChar(c) => write!(f, "Invalid character: {}", c),
550 Error::InvalidLiteral => write!(f, "Invalid literal"),
551 Error::InvalidNumber => write!(f, "Invalid number"),
552 Error::ExpectedChar(c) => write!(f, "Expected character: {}", c),
553 Error::ExpectedString => write!(f, "Expected string"),
554 Error::ExpectedObject => write!(f, "Expected object"),
555 Error::TypeMismatch(t) => write!(f, "Type mismatch: expected {}", t),
556 Error::MissingField(field) => write!(f, "Missing field: {}", field),
557 Error::Parse(msg) => write!(f, "Parse error: {}", msg),
558 Error::NotImplemented => write!(f, "Not implemented"),
559 }
560 }
561}
562
563impl std::error::Error for Error {}
564
565#[cfg(test)]
566mod tests {
567 use super::*;
568
569 #[test]
570 fn test_parse_string() {
571 let v = Value::from_json("\"hello\"").unwrap();
572 assert_eq!(v, Value::String("hello".to_string()));
573 }
574
575 #[test]
576 fn test_parse_number() {
577 let v = Value::from_json("42").unwrap();
578 assert_eq!(v, Value::Number(42.0));
579 }
580
581 #[test]
582 fn test_parse_array() {
583 let v = Value::from_json("[1,2,3]").unwrap();
584 if let Value::Array(arr) = v {
585 assert_eq!(arr.len(), 3);
586 } else {
587 panic!("Expected array");
588 }
589 }
590
591 #[test]
592 fn test_parse_object() {
593 let v = Value::from_json(r#"{"name":"test","value":42}"#).unwrap();
594 if let Value::Object(obj) = v {
595 assert_eq!(obj.get("name").and_then(|v| v.as_str()), Some("test"));
596 assert_eq!(obj.get("value").and_then(|v| v.as_f64()), Some(42.0));
597 } else {
598 panic!("Expected object");
599 }
600 }
601
602 #[test]
603 fn test_to_json() {
604 let v = Value::String("hello".to_string());
605 assert_eq!(v.to_json(), "\"hello\"");
606 }
607}
608
609pub mod prelude {
615 pub use crate::{Serialize, Deserialize, Value, Error};
616
617 #[cfg(feature = "derive")]
618 pub use crate::{SerializeMacro as Serialize, DeserializeMacro as Deserialize};
619}
620
621#[macro_export]
637macro_rules! json {
638 (null) => {
639 $crate::Value::Null
640 };
641
642 (true) => {
643 $crate::Value::Bool(true)
644 };
645
646 (false) => {
647 $crate::Value::Bool(false)
648 };
649
650 ($val:expr) => {
651 {
652 let v = $val;
653 $crate::__json_internal_to_value(v)
654 }
655 };
656
657 ([$($element:tt),* $(,)?]) => {
658 $crate::Value::Array(vec![$($crate::json!($element)),*])
659 };
660
661 ({$($key:tt : $value:tt),* $(,)?}) => {
662 {
663 let mut map = std::collections::HashMap::new();
664 $(
665 map.insert($crate::__json_key!($key), $crate::json!($value));
666 )*
667 $crate::Value::Object(map)
668 }
669 };
670}
671
672#[doc(hidden)]
673#[macro_export]
674macro_rules! __json_key {
675 ($key:ident) => {
676 stringify!($key).to_string()
677 };
678 ($key:expr) => {
679 $key.to_string()
680 };
681}
682
683#[doc(hidden)]
684pub fn __json_internal_to_value<T: Into<Value>>(v: T) -> Value {
685 v.into()
686}
687
688impl From<bool> for Value {
689 fn from(b: bool) -> Self {
690 Value::Bool(b)
691 }
692}
693
694impl From<f64> for Value {
695 fn from(n: f64) -> Self {
696 Value::Number(n)
697 }
698}
699
700impl From<i32> for Value {
701 fn from(n: i32) -> Self {
702 Value::Number(n as f64)
703 }
704}
705
706impl From<u64> for Value {
707 fn from(n: u64) -> Self {
708 Value::Number(n as f64)
709 }
710}
711
712impl From<String> for Value {
713 fn from(s: String) -> Self {
714 Value::String(s)
715 }
716}
717
718impl From<&str> for Value {
719 fn from(s: &str) -> Self {
720 Value::String(s.to_string())
721 }
722}
723
724impl<T: Into<Value>> From<Vec<T>> for Value {
725 fn from(v: Vec<T>) -> Self {
726 Value::Array(v.into_iter().map(|x| x.into()).collect())
727 }
728}
729
730impl From<HashMap<String, Value>> for Value {
731 fn from(m: HashMap<String, Value>) -> Self {
732 Value::Object(m)
733 }
734}