#![cfg(feature = "json")]
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::convert::Infallible;
use core::fmt::Debug;
use core::ops::Deref;
use core::str::FromStr;
use base64ct::{Base64UrlUnpadded, Encoding};
use serde::de::{DeserializeOwned, Error as _};
use serde::{Deserialize, Deserializer, Serialize};
use super::Bytes;
use crate::stream::Error;
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize)]
#[serde(bound(serialize = "Bytes<B, E>: Serialize"))]
#[serde(transparent)]
pub struct Json<T, B = Box<[u8]>, E = Base64UrlUnpadded> {
buf: Bytes<B, E>,
#[serde(skip_serializing)]
val: T,
}
impl<T, B, E> Deref for Json<T, B, E> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.val
}
}
impl<T, B: AsRef<[u8]>, E> AsRef<[u8]> for Json<T, B, E> {
fn as_ref(&self) -> &[u8] {
self.buf.as_ref()
}
}
impl<T, B, E> TryFrom<Bytes<B, E>> for Json<T, B, E>
where
Bytes<B, E>: AsRef<[u8]>,
T: DeserializeOwned,
{
type Error = serde_json::Error;
fn try_from(buf: Bytes<B, E>) -> Result<Self, Self::Error> {
Ok(Self {
val: serde_json::from_slice(buf.as_ref())?,
buf,
})
}
}
impl<T, B, E> Json<T, B, E>
where
Bytes<B, E>: From<Vec<u8>>,
T: Serialize,
{
pub fn new(value: T) -> Result<Self, serde_json::Error> {
Ok(Self {
buf: serde_json::to_vec(&value)?.into(),
val: value,
})
}
}
impl<T, B, E: Encoding> FromStr for Json<T, B, E>
where
Bytes<B, E>: FromStr<Err = Error<Infallible>>,
Bytes<B, E>: AsRef<[u8]>,
T: DeserializeOwned,
{
type Err = Error<serde_json::Error>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let buf = Bytes::from_str(s).map_err(|e| e.cast())?;
buf.try_into().map_err(Error::Inner)
}
}
impl<'de, T, B, E> Deserialize<'de> for Json<T, B, E>
where
Bytes<B, E>: Deserialize<'de>,
Bytes<B, E>: AsRef<[u8]>,
T: DeserializeOwned,
E: Encoding,
{
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Ok(match Self::try_from(Bytes::deserialize(deserializer)?) {
Err(e) => return Err(D::Error::custom(e)),
Ok(x) => x,
})
}
}