Line data Source code
1 : use core::fmt;
2 : use std::collections::{BTreeMap, HashMap};
3 :
4 : use crate::str::{format_escaped_fmt, format_escaped_str};
5 : use crate::{KeyEncoder, ObjectSer, ValueSer, value_as_list, value_as_object};
6 :
7 : /// Write a value to the underlying json representation.
8 : pub trait ValueEncoder {
9 : fn encode(self, v: ValueSer<'_>);
10 : }
11 :
12 19 : pub(crate) fn write_int(x: impl itoa::Integer, b: &mut Vec<u8>) {
13 19 : b.extend_from_slice(itoa::Buffer::new().format(x).as_bytes());
14 19 : }
15 :
16 14 : pub(crate) fn write_float(x: impl ryu::Float, b: &mut Vec<u8>) {
17 14 : b.extend_from_slice(ryu::Buffer::new().format(x).as_bytes());
18 14 : }
19 :
20 : impl<T: Copy + ValueEncoder> ValueEncoder for &T {
21 : #[inline]
22 0 : fn encode(self, v: ValueSer<'_>) {
23 0 : T::encode(*self, v);
24 0 : }
25 : }
26 :
27 : impl ValueEncoder for &str {
28 : #[inline]
29 37 : fn encode(self, v: ValueSer<'_>) {
30 37 : format_escaped_str(v.buf, self);
31 37 : v.finish();
32 8 : }
33 : }
34 :
35 : impl ValueEncoder for fmt::Arguments<'_> {
36 : #[inline]
37 0 : fn encode(self, v: ValueSer<'_>) {
38 0 : if let Some(s) = self.as_str() {
39 0 : format_escaped_str(v.buf, s);
40 0 : } else {
41 0 : format_escaped_fmt(v.buf, self);
42 0 : }
43 0 : v.finish();
44 0 : }
45 : }
46 :
47 : macro_rules! int {
48 : [$($t:ty),*] => {
49 : $(
50 : impl ValueEncoder for $t {
51 : #[inline]
52 19 : fn encode(self, v: ValueSer<'_>) {
53 19 : write_int(self, v.buf);
54 19 : v.finish();
55 5 : }
56 : }
57 : )*
58 : };
59 : }
60 :
61 : int![u8, u16, u32, u64, usize, u128];
62 : int![i8, i16, i32, i64, isize, i128];
63 :
64 : macro_rules! float {
65 : [$($t:ty),*] => {
66 : $(
67 : impl ValueEncoder for $t {
68 : #[inline]
69 14 : fn encode(self, v: ValueSer<'_>) {
70 14 : write_float(self, v.buf);
71 14 : v.finish();
72 0 : }
73 : }
74 : )*
75 : };
76 : }
77 :
78 : float![f32, f64];
79 :
80 : impl ValueEncoder for bool {
81 : #[inline]
82 12 : fn encode(self, v: ValueSer<'_>) {
83 12 : v.write_raw_json(if self { b"true" } else { b"false" });
84 0 : }
85 : }
86 :
87 : impl<T: ValueEncoder> ValueEncoder for Option<T> {
88 : #[inline]
89 0 : fn encode(self, v: ValueSer<'_>) {
90 0 : match self {
91 0 : Some(value) => value.encode(v),
92 0 : None => Null.encode(v),
93 : }
94 0 : }
95 : }
96 :
97 : impl KeyEncoder for &str {
98 : #[inline]
99 7 : fn write_key<'a>(self, obj: &'a mut ObjectSer) -> ValueSer<'a> {
100 7 : let obj = &mut *obj;
101 7 : obj.entry_inner(|b| format_escaped_str(b, self))
102 7 : }
103 : }
104 :
105 : impl KeyEncoder for fmt::Arguments<'_> {
106 : #[inline]
107 1 : fn write_key<'a>(self, obj: &'a mut ObjectSer) -> ValueSer<'a> {
108 1 : if let Some(key) = self.as_str() {
109 0 : obj.entry_inner(|b| format_escaped_str(b, key))
110 : } else {
111 1 : obj.entry_inner(|b| format_escaped_fmt(b, self))
112 : }
113 1 : }
114 : }
115 :
116 : /// Represents the JSON null value.
117 : pub struct Null;
118 :
119 : impl ValueEncoder for Null {
120 : #[inline]
121 12 : fn encode(self, v: ValueSer<'_>) {
122 12 : v.write_raw_json(b"null");
123 5 : }
124 : }
125 :
126 : impl<T: ValueEncoder> ValueEncoder for Vec<T> {
127 : #[inline]
128 0 : fn encode(self, v: ValueSer<'_>) {
129 0 : value_as_list!(|v| {
130 0 : for t in self {
131 0 : v.entry().value(t);
132 0 : }
133 : });
134 0 : }
135 : }
136 :
137 : impl<T: Copy + ValueEncoder> ValueEncoder for &[T] {
138 : #[inline]
139 0 : fn encode(self, v: ValueSer<'_>) {
140 0 : value_as_list!(|v| {
141 0 : for t in self {
142 0 : v.entry().value(t);
143 0 : }
144 : });
145 0 : }
146 : }
147 :
148 : impl<K: KeyEncoder, V: ValueEncoder, S> ValueEncoder for HashMap<K, V, S> {
149 : #[inline]
150 0 : fn encode(self, o: ValueSer<'_>) {
151 0 : value_as_object!(|o| {
152 0 : for (k, v) in self {
153 0 : o.entry(k, v);
154 0 : }
155 : });
156 0 : }
157 : }
158 :
159 : impl<K: KeyEncoder, V: ValueEncoder> ValueEncoder for BTreeMap<K, V> {
160 : #[inline]
161 0 : fn encode(self, o: ValueSer<'_>) {
162 0 : value_as_object!(|o| {
163 0 : for (k, v) in self {
164 0 : o.entry(k, v);
165 0 : }
166 : });
167 0 : }
168 : }
|