pub mod error;
pub use tiny_serde_derive::Serialize;
use std::collections::HashMap;
#[derive(Clone, Debug)]
pub enum Value {
Null,
Boolean(bool),
Number(f64),
String(String),
Array(Vec<Value>),
Object(HashMap<String, Value>),
}
impl ToString for Value {
fn to_string(&self) -> String {
match self {
Self::Null => "null".to_string(),
Self::Boolean(b) => match b {
true => "true",
false => "false",
}
.to_string(),
Self::Number(nb) => nb.to_string(),
Self::String(value) => {
format!("\"{value}\"")
}
Self::Array(array) => {
let mut final_value = "[".to_string();
let last_index = array.len() - 1;
for (i, value) in array.iter().enumerate() {
if i < last_index {
final_value += &format!("{},", value.to_string());
} else {
final_value += &format!("{}", value.to_string());
}
}
final_value += "]";
final_value
}
Self::Object(node) => {
let mut final_value = "{".to_string();
let last_index = node.len() - 1;
let mut i = 0;
for (key, value) in node.iter() {
if i < last_index {
final_value += &format!("\"{key}\":{},", value.to_string());
} else {
final_value += &format!("\"{key}\":{}", value.to_string());
}
i += 1;
}
final_value += "}";
final_value
}
}
}
}
pub trait Serialize {
fn serialize(&self) -> Value;
}
pub fn to_string<S: Serialize>(value: &S) -> String {
value.serialize().to_string()
}
fn patch_control_characters(input: &str) -> String {
let input = input
.chars()
.map(|c| {
if c == '\\' {
r#"\\"#.to_string()
} else if c == '"' {
r#"\""#.to_string()
} else {
c.to_string()
}
})
.collect::<String>();
input
}
impl Serialize for String {
fn serialize(&self) -> Value {
let value = patch_control_characters(self);
Value::String(value)
}
}
impl<S: Serialize> Serialize for Option<S> {
fn serialize(&self) -> Value {
match self {
Some(value) => value.serialize(),
None => Value::Null,
}
}
}
impl Serialize for bool {
fn serialize(&self) -> Value {
Value::Boolean(*self)
}
}
impl Serialize for f64 {
fn serialize(&self) -> Value {
Value::Number(*self)
}
}
impl Serialize for Vec<Value> {
fn serialize(&self) -> Value {
Value::Array(self.clone())
}
}
impl Serialize for HashMap<String, Value> {
fn serialize(&self) -> Value {
Value::Object(self.clone())
}
}