spacejson 0.0.14

Derive JSON interfaces for types
Documentation
//! Json implementation for array

use crate::{Json, String, Vec, format};
use anyhow::Result;
use serde::{Serialize, de::DeserializeOwned};

impl<M: Serialize + DeserializeOwned, N> Json<Vec<M>> for Vec<N>
where
    N: Json<M>,
{
    fn to_json(self) -> Vec<M> {
        self.into_iter().map(|v| v.to_json()).collect()
    }

    fn from_json(json: Vec<M>) -> Result<Self> {
        json.into_iter().map(|v| N::from_json(v)).collect()
    }
}

macro_rules! impl_bytes {
    ($($len:expr),*) => {
        $(
            impl Json<String> for [u8; $len] {
                fn to_json(self) -> String {
                    format!("0x{}", hex::encode(self))
                }

                fn from_json(json: String) -> Result<Self> {
                    let bytes = hex::decode(json.trim_start_matches("0x")).map_err(|e| anyhow::anyhow!("failed to decode json string: {e:?}"))?;
                    let len = bytes.len();

                    bytes.try_into().map_err(|_| {
                        anyhow::anyhow!(
                            "Invalid hex string, target length is {len}, actual length is {actual}",
                            len = $len,
                            actual = len
                        )
                    })
                }
            }
        )*
    };
}

impl_bytes!(
    1, 2, 3, 4, 5, 6, 8, 12, 16, 17, 32, 64, 96, 128, 144, 256, 784
);

macro_rules! impl_array {
    ($($len:expr),*) => {
        $(
            impl<M: Serialize + DeserializeOwned, N: Default> Json<Vec<M>> for [N; $len]
            where
                N: Json<M>,
            {
                fn to_json(self) -> Vec<M> {
                    self.into_iter().map(|v| v.to_json()).collect()
                }

                fn from_json(json: Vec<M>) -> Result<Self> {
                    let mut array = Vec::with_capacity($len);
                    for v in json {
                        array.push(N::from_json(v)?);
                    }
                    array.try_into().map_err(|_| anyhow::anyhow!("Invalid array length"))
                }
            }
        )*
    };
}

impl_array!(1, 2, 3, 4, 5, 6, 8, 12, 16, 32, 64, 96, 128, 144, 256, 784);