1use crate::{from_str, Result};
2use serde::de::{Deserializer, Visitor};
3use serde::Deserialize;
4use std::fmt;
5use std::marker::PhantomData;
6
7pub(crate) const RAW_JSON_TOKEN: &str = "$blazingly_json::RawJson";
8
9#[derive(Clone, Copy, Debug, Eq, PartialEq)]
16pub struct RawJson<'a> {
17 json: &'a str,
18}
19
20impl<'a> RawJson<'a> {
21 pub(crate) const fn new(json: &'a str) -> Self {
22 Self { json }
23 }
24
25 #[must_use]
27 pub const fn get(self) -> &'a str {
28 self.json
29 }
30
31 pub fn deserialize<T>(self) -> Result<T>
37 where
38 T: Deserialize<'a>,
39 {
40 from_str(self.json)
41 }
42}
43
44struct RawJsonVisitor<'a>(PhantomData<&'a str>);
45
46impl<'de: 'a, 'a> Visitor<'de> for RawJsonVisitor<'a> {
47 type Value = RawJson<'a>;
48
49 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
50 formatter.write_str("a borrowed raw JSON value")
51 }
52
53 fn visit_borrowed_str<E>(self, value: &'de str) -> std::result::Result<Self::Value, E> {
54 Ok(RawJson::new(value))
55 }
56}
57
58impl<'de: 'a, 'a> Deserialize<'de> for RawJson<'a> {
59 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
60 where
61 D: Deserializer<'de>,
62 {
63 deserializer.deserialize_newtype_struct(RAW_JSON_TOKEN, RawJsonVisitor(PhantomData))
64 }
65}