use crate::{from_str, Result};
use serde::de::{Deserializer, Visitor};
use serde::Deserialize;
use std::fmt;
use std::marker::PhantomData;
pub(crate) const RAW_JSON_TOKEN: &str = "$blazingly_json::RawJson";
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct RawJson<'a> {
json: &'a str,
}
impl<'a> RawJson<'a> {
pub(crate) const fn new(json: &'a str) -> Self {
Self { json }
}
#[must_use]
pub const fn get(self) -> &'a str {
self.json
}
pub fn deserialize<T>(self) -> Result<T>
where
T: Deserialize<'a>,
{
from_str(self.json)
}
}
struct RawJsonVisitor<'a>(PhantomData<&'a str>);
impl<'de: 'a, 'a> Visitor<'de> for RawJsonVisitor<'a> {
type Value = RawJson<'a>;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a borrowed raw JSON value")
}
fn visit_borrowed_str<E>(self, value: &'de str) -> std::result::Result<Self::Value, E> {
Ok(RawJson::new(value))
}
}
impl<'de: 'a, 'a> Deserialize<'de> for RawJson<'a> {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_newtype_struct(RAW_JSON_TOKEN, RawJsonVisitor(PhantomData))
}
}