use crate::error::ParseError;
use crate::Value;
pub trait IntoJson {
fn to_json(&self) -> Value;
}
pub trait FromJson {
fn from_json(value: &Value) -> Result<Self, ParseError>
where
Self: Sized;
}
impl<T> From<T> for Value
where
T: IntoJson,
{
fn from(value: T) -> Self {
value.to_json()
}
}
impl IntoJson for bool {
fn to_json(&self) -> Value {
Value::Bool(*self)
}
}
impl IntoJson for String {
fn to_json(&self) -> Value {
Value::String(self.to_owned())
}
}
impl IntoJson for &str {
fn to_json(&self) -> Value {
Value::String(self.to_string())
}
}
impl<T> IntoJson for Option<T>
where
T: IntoJson,
{
fn to_json(&self) -> Value {
match self {
Some(v) => v.to_json(),
None => Value::Null,
}
}
}
impl<T> IntoJson for Vec<T>
where
T: IntoJson,
{
fn to_json(&self) -> Value {
Value::Array(self.iter().map(|v| v.to_json()).collect())
}
}
impl<T> IntoJson for &T
where
T: IntoJson,
{
fn to_json(&self) -> Value {
(**self).to_json()
}
}
macro_rules! impl_into_json_for_number {
($($t:ty),*) => {
$(
impl IntoJson for $t {
fn to_json(&self) -> Value {
Value::Number(*self as f64)
}
}
)*
};
}
impl_into_json_for_number!(
u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64
);
impl FromJson for Value {
fn from_json(value: &Value) -> Result<Self, ParseError> {
Ok(value.clone())
}
}
impl FromJson for bool {
fn from_json(value: &Value) -> Result<Self, ParseError> {
match value {
Value::Bool(b) => Ok(*b),
_ => Err(ParseError::TypeError),
}
}
}
impl FromJson for String {
fn from_json(value: &Value) -> Result<Self, ParseError> {
match value {
Value::String(s) => Ok(s.clone()),
_ => Err(ParseError::TypeError),
}
}
}
impl<T> FromJson for Option<T>
where
T: FromJson,
{
fn from_json(value: &Value) -> Result<Self, ParseError>
where
Self: Sized,
{
match value {
Value::Null => Ok(None),
_ => T::from_json(value).map(Some),
}
}
}
impl<T> FromJson for Vec<T>
where
T: FromJson,
{
fn from_json(value: &Value) -> Result<Self, ParseError>
where
Self: Sized,
{
match value {
Value::Array(v) => v.iter().map(|v| T::from_json(v)).collect(),
_ => Err(ParseError::TypeError),
}
}
}
macro_rules! impl_from_json_for_number {
($($t:ty),*) => {
$(
impl FromJson for $t {
fn from_json(value: &Value) -> Result<Self, ParseError>
where
Self: Sized,
{
match value {
Value::Number(n) => Ok(*n as Self),
_ => Err(ParseError::TypeError),
}
}
}
)*
};
}
impl_from_json_for_number!(
u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64
);