nyoom_json/
write_to_json.rs

1use crate::{escape::escape_str, JsonBuffer};
2
3/// A value that is able to be written directly into JSON.
4pub trait WriteToJson<S: JsonBuffer> {
5    fn write_to_json(self, out: &mut S);
6}
7
8macro_rules! impl_int {
9    ($($ty:ty),*) => {
10        $(
11            impl<S: JsonBuffer> WriteToJson<S> for $ty {
12                #[inline(always)]
13                fn write_to_json(self, out: &mut S) {
14                    let mut int_buf = itoa::Buffer::new();
15                    out.push_str(int_buf.format(self));
16                }
17            }
18        )*
19
20    }
21}
22
23macro_rules! impl_float {
24    ($($ty:ty),*) => {
25        $(
26            impl<S: JsonBuffer> WriteToJson<S> for $ty {
27                #[inline(always)]
28                fn write_to_json(self, out: &mut S) {
29                    let mut float_buf = ryu::Buffer::new();
30                    out.push_str(float_buf.format(self));
31                }
32            }
33        )*
34
35    }
36}
37
38impl_int!(u8, u16, u32, u64, i8, i16, i32, i64);
39impl_float!(f32, f64);
40
41impl<S: JsonBuffer> WriteToJson<S> for &str {
42    #[inline(always)]
43    fn write_to_json(self, out: &mut S) {
44        out.push('"');
45        escape_str(self, out);
46        out.push('"');
47    }
48}
49
50impl<S: JsonBuffer> WriteToJson<S> for bool {
51    #[inline(always)]
52    fn write_to_json(self, out: &mut S) {
53        match self {
54            true => out.push_str("true"),
55            false => out.push_str("false"),
56        }
57    }
58}
59
60/// The JSON null value!
61pub struct Null;
62
63impl<S: JsonBuffer> WriteToJson<S> for () {
64    #[inline(always)]
65    fn write_to_json(self, out: &mut S) {
66        out.push_str("null")
67    }
68}
69
70impl<S: JsonBuffer> WriteToJson<S> for Null {
71    #[inline(always)]
72    fn write_to_json(self, out: &mut S) {
73        out.push_str("null")
74    }
75}
76
77impl<S: JsonBuffer, T> WriteToJson<S> for &T
78where
79    T: Copy + WriteToJson<S>,
80{
81    #[inline(always)]
82    fn write_to_json(self, out: &mut S) {
83        (*self).write_to_json(out)
84    }
85}
86
87impl<S: JsonBuffer, T> WriteToJson<S> for Option<T>
88where
89    T: WriteToJson<S>,
90{
91    #[inline(always)]
92    fn write_to_json(self, out: &mut S) {
93        match self {
94            Some(v) => v.write_to_json(out),
95            None => Null.write_to_json(out),
96        }
97    }
98}
99
100/// A string that will *not* have escapes applied to it. You should only use this if you're *absolutely* sure you don't need them.
101#[repr(transparent)]
102pub struct UnescapedStr<'a>(&'a str);
103
104impl<'a> UnescapedStr<'a> {
105    #[inline(always)]
106    pub fn create(val: &'a str) -> UnescapedStr<'a> {
107        debug_assert!(
108            val.as_bytes()
109                .iter()
110                .all(|val| { crate::escape::ESCAPE[*val as usize] == 0 }),
111            "string contains characters that need to be escaped!"
112        );
113
114        UnescapedStr(val)
115    }
116}
117
118impl<'a, S: JsonBuffer> WriteToJson<S> for UnescapedStr<'a> {
119    #[inline(always)]
120    fn write_to_json(self, out: &mut S) {
121        out.push('"');
122        out.push_str(self.0);
123        out.push('"');
124    }
125}