use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
use std::error::Error;
use crate::{JsonNode, JsonPropertyMap};
pub trait ToJsonNode {
fn to_json_node(&self) -> JsonNode;
}
impl ToJsonNode for String {
fn to_json_node(&self) -> JsonNode {
JsonNode::String(self.clone())
}
}
impl ToJsonNode for &str {
fn to_json_node(&self) -> JsonNode {
JsonNode::String(self.to_string())
}
}
impl ToJsonNode for i32 {
fn to_json_node(&self) -> JsonNode {
JsonNode::Integer(i64::from(*self))
}
}
impl ToJsonNode for i64 {
fn to_json_node(&self) -> JsonNode {
JsonNode::Integer(*self)
}
}
impl ToJsonNode for f32 {
fn to_json_node(&self) -> JsonNode {
JsonNode::Float(f64::from(*self))
}
}
impl ToJsonNode for f64 {
fn to_json_node(&self) -> JsonNode {
JsonNode::Float(*self)
}
}
impl ToJsonNode for u32 {
fn to_json_node(&self) -> JsonNode {
JsonNode::Integer(i64::from(*self))
}
}
impl ToJsonNode for bool {
fn to_json_node(&self) -> JsonNode {
JsonNode::Boolean(*self)
}
}
impl ToJsonNode for Option<String> {
fn to_json_node(&self) -> JsonNode {
match self {
Some(value) => JsonNode::String(value.clone()),
None => JsonNode::Null,
}
}
}
impl ToJsonNode for Option<&str> {
fn to_json_node(&self) -> JsonNode {
match self {
Some(value) => JsonNode::String(value.to_string()),
None => JsonNode::Null,
}
}
}
impl ToJsonNode for Option<i32> {
fn to_json_node(&self) -> JsonNode {
match self {
Some(value) => JsonNode::Integer(i64::from(*value)),
None => JsonNode::Null,
}
}
}
impl ToJsonNode for Option<i64> {
fn to_json_node(&self) -> JsonNode {
match self {
Some(value) => JsonNode::Integer(*value),
None => JsonNode::Null,
}
}
}
impl ToJsonNode for Option<f32> {
fn to_json_node(&self) -> JsonNode {
match self {
Some(value) => JsonNode::Float(f64::from(*value)),
None => JsonNode::Null,
}
}
}
impl ToJsonNode for Option<f64> {
fn to_json_node(&self) -> JsonNode {
match self {
Some(value) => JsonNode::Float(*value),
None => JsonNode::Null,
}
}
}
impl ToJsonNode for Option<u32> {
fn to_json_node(&self) -> JsonNode {
match self {
Some(value) => JsonNode::Integer(i64::from(*value)),
None => JsonNode::Null,
}
}
}
impl ToJsonNode for Option<bool> {
fn to_json_node(&self) -> JsonNode {
match self {
Some(value) => JsonNode::Boolean(*value),
None => JsonNode::Null,
}
}
}
impl<E: Error> ToJsonNode for Result<String, E> {
fn to_json_node(&self) -> JsonNode {
match self {
Ok(value) => JsonNode::Object(JsonPropertyMap::from([
("type".to_string(), "ok".to_json_node()),
("value".to_string(), value.to_json_node()),
])),
Err(_) => JsonNode::Object(JsonPropertyMap::from([
("type".to_string(), "error".to_json_node()),
("error".to_string(), "Could not convert to JSON".to_json_node()),
])),
}
}
}
impl<E: Error> ToJsonNode for Result<&str, E> {
fn to_json_node(&self) -> JsonNode {
match self {
Ok(value) => JsonNode::Object(JsonPropertyMap::from([
("type".to_string(), "ok".to_json_node()),
("value".to_string(), value.to_json_node()),
])),
Err(_) => JsonNode::Object(JsonPropertyMap::from([
("type".to_string(), "error".to_json_node()),
("error".to_string(), "Could not convert to JSON".to_json_node()),
])),
}
}
}
impl<E: Error> ToJsonNode for Result<i32, E> {
fn to_json_node(&self) -> JsonNode {
match self {
Ok(value) => JsonNode::Object(JsonPropertyMap::from([
("type".to_string(), "ok".to_json_node()),
("value".to_string(), value.to_json_node()),
])),
Err(_) => JsonNode::Object(JsonPropertyMap::from([
("type".to_string(), "error".to_json_node()),
("error".to_string(), "Could not convert to JSON".to_json_node()),
])),
}
}
}
impl<E: Error> ToJsonNode for Result<i64, E> {
fn to_json_node(&self) -> JsonNode {
match self {
Ok(value) => JsonNode::Object(JsonPropertyMap::from([
("type".to_string(), "ok".to_json_node()),
("value".to_string(), value.to_json_node()),
])),
Err(_) => JsonNode::Object(JsonPropertyMap::from([
("type".to_string(), "error".to_json_node()),
("error".to_string(), "Could not convert to JSON".to_json_node()),
])),
}
}
}
impl<E: Error> ToJsonNode for Result<f32, E> {
fn to_json_node(&self) -> JsonNode {
match self {
Ok(value) => JsonNode::Object(JsonPropertyMap::from([
("type".to_string(), "ok".to_json_node()),
("value".to_string(), value.to_json_node()),
])),
Err(_) => JsonNode::Object(JsonPropertyMap::from([
("type".to_string(), "error".to_json_node()),
("error".to_string(), "Could not convert to JSON".to_json_node()),
])),
}
}
}
impl<E: Error> ToJsonNode for Result<f64, E> {
fn to_json_node(&self) -> JsonNode {
match self {
Ok(value) => JsonNode::Object(JsonPropertyMap::from([
("type".to_string(), "ok".to_json_node()),
("value".to_string(), value.to_json_node()),
])),
Err(_) => JsonNode::Object(JsonPropertyMap::from([
("type".to_string(), "error".to_json_node()),
("error".to_string(), "Could not convert to JSON".to_json_node()),
])),
}
}
}
impl<E: Error> ToJsonNode for Result<u32, E> {
fn to_json_node(&self) -> JsonNode {
match self {
Ok(value) => JsonNode::Object(JsonPropertyMap::from([
("type".to_string(), "ok".to_json_node()),
("value".to_string(), value.to_json_node()),
])),
Err(_) => JsonNode::Object(JsonPropertyMap::from([
("type".to_string(), "error".to_json_node()),
("error".to_string(), "Could not convert to JSON".to_json_node()),
])),
}
}
}
impl<E: Error> ToJsonNode for Result<bool, E> {
fn to_json_node(&self) -> JsonNode {
match self {
Ok(value) => JsonNode::Object(JsonPropertyMap::from([
("type".to_string(), "ok".to_json_node()),
("value".to_string(), value.to_json_node()),
])),
Err(_) => JsonNode::Object(JsonPropertyMap::from([
("type".to_string(), "error".to_json_node()),
("error".to_string(), "Could not convert to JSON".to_json_node()),
])),
}
}
}
impl<T: ToJsonNode, const COUNT: usize> ToJsonNode for [T; COUNT] {
fn to_json_node(&self) -> JsonNode {
JsonNode::Array(self.iter().map(|value| value.to_json_node()).collect())
}
}
impl<T: ToJsonNode> ToJsonNode for [T] {
fn to_json_node(&self) -> JsonNode {
JsonNode::Array(self.iter().map(|value| value.to_json_node()).collect())
}
}
impl<T: ToJsonNode> ToJsonNode for Vec<T> {
fn to_json_node(&self) -> JsonNode {
JsonNode::Array(self.iter().map(|value| value.to_json_node()).collect())
}
}
impl<T: ToJsonNode> ToJsonNode for VecDeque<T> {
fn to_json_node(&self) -> JsonNode {
JsonNode::Array(self.iter().map(|value| value.to_json_node()).collect())
}
}
impl<T: ToJsonNode> ToJsonNode for LinkedList<T> {
fn to_json_node(&self) -> JsonNode {
JsonNode::Array(self.iter().map(|value| value.to_json_node()).collect())
}
}
impl<T: ToJsonNode> ToJsonNode for HashSet<T> {
fn to_json_node(&self) -> JsonNode {
JsonNode::Array(self.iter().map(|value| value.to_json_node()).collect())
}
}
impl<T: ToJsonNode> ToJsonNode for BTreeSet<T> {
fn to_json_node(&self) -> JsonNode {
JsonNode::Array(self.iter().map(|value| value.to_json_node()).collect())
}
}
impl<T: ToJsonNode> ToJsonNode for BinaryHeap<T> {
fn to_json_node(&self) -> JsonNode {
JsonNode::Array(self.iter().map(|value| value.to_json_node()).collect())
}
}
impl<T: ToJsonNode> ToJsonNode for Vec<(String, T)> {
fn to_json_node(&self) -> JsonNode {
JsonNode::Object(
self.iter()
.map(|(key, value)| (key.clone(), value.to_json_node()))
.collect(),
)
}
}
impl<T: ToJsonNode> ToJsonNode for VecDeque<(String, T)> {
fn to_json_node(&self) -> JsonNode {
JsonNode::Object(
self.iter()
.map(|(key, value)| (key.clone(), value.to_json_node()))
.collect(),
)
}
}
impl<T: ToJsonNode> ToJsonNode for LinkedList<(String, T)> {
fn to_json_node(&self) -> JsonNode {
JsonNode::Object(
self.iter()
.map(|(key, value)| (key.clone(), value.to_json_node()))
.collect(),
)
}
}
impl<T: ToJsonNode> ToJsonNode for HashSet<(String, T)> {
fn to_json_node(&self) -> JsonNode {
JsonNode::Object(
self.iter()
.map(|(key, value)| (key.clone(), value.to_json_node()))
.collect(),
)
}
}
impl<T: ToJsonNode> ToJsonNode for BTreeSet<(String, T)> {
fn to_json_node(&self) -> JsonNode {
JsonNode::Object(
self.iter()
.map(|(key, value)| (key.clone(), value.to_json_node()))
.collect(),
)
}
}
impl<T: ToJsonNode> ToJsonNode for BinaryHeap<(String, T)> {
fn to_json_node(&self) -> JsonNode {
JsonNode::Object(
self.iter()
.map(|(key, value)| (key.clone(), value.to_json_node()))
.collect(),
)
}
}
impl<V: ToJsonNode> ToJsonNode for HashMap<String, V> {
fn to_json_node(&self) -> JsonNode {
JsonNode::Object(
self.iter()
.map(|(key, value)| (key.clone(), value.to_json_node()))
.collect::<JsonPropertyMap>(),
)
}
}
impl<V: ToJsonNode> ToJsonNode for BTreeMap<String, V> {
fn to_json_node(&self) -> JsonNode {
JsonNode::Object(
self.iter()
.map(|(key, value)| (key.clone(), value.to_json_node()))
.collect::<JsonPropertyMap>(),
)
}
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
use crate::{JsonNode, JsonPropertyMap, ToJsonNode};
struct Person {
name: String,
age: i64,
}
impl ToJsonNode for Person {
fn to_json_node(&self) -> JsonNode {
JsonNode::Object(JsonPropertyMap::from([
("name".to_owned(), JsonNode::String(self.name.clone())),
("age".to_owned(), self.age.to_json_node()),
]))
}
}
let person = Person {
name: "John Doe".to_owned(),
age: 42,
};
let person_node = person.to_json_node();
let person_node_json = person_node.to_json_string();
assert_eq!(
person_node_json,
r#"{"name":"John Doe","age":42}"#
);
}
}