core_json_traits/
primitives.rs

1use crate::{Read, Stack, JsonError, Value, JsonDeserialize, JsonSerialize};
2
3impl JsonDeserialize for i8 {
4  fn deserialize<'read, 'parent, B: Read<'read>, S: Stack>(
5    value: Value<'read, 'parent, B, S>,
6  ) -> Result<Self, JsonError<'read, B, S>> {
7    value
8      .to_number()?
9      .i64()
10      .ok_or(JsonError::TypeError)?
11      .try_into()
12      .map_err(|_| JsonError::TypeError)
13  }
14}
15impl JsonDeserialize for i16 {
16  fn deserialize<'read, 'parent, B: Read<'read>, S: Stack>(
17    value: Value<'read, 'parent, B, S>,
18  ) -> Result<Self, JsonError<'read, B, S>> {
19    value
20      .to_number()?
21      .i64()
22      .ok_or(JsonError::TypeError)?
23      .try_into()
24      .map_err(|_| JsonError::TypeError)
25  }
26}
27impl JsonDeserialize for i32 {
28  fn deserialize<'read, 'parent, B: Read<'read>, S: Stack>(
29    value: Value<'read, 'parent, B, S>,
30  ) -> Result<Self, JsonError<'read, B, S>> {
31    value
32      .to_number()?
33      .i64()
34      .ok_or(JsonError::TypeError)?
35      .try_into()
36      .map_err(|_| JsonError::TypeError)
37  }
38}
39impl JsonDeserialize for i64 {
40  fn deserialize<'read, 'parent, B: Read<'read>, S: Stack>(
41    value: Value<'read, 'parent, B, S>,
42  ) -> Result<Self, JsonError<'read, B, S>> {
43    value.to_number()?.i64().ok_or(JsonError::TypeError)
44  }
45}
46
47impl JsonDeserialize for u8 {
48  fn deserialize<'read, 'parent, B: Read<'read>, S: Stack>(
49    value: Value<'read, 'parent, B, S>,
50  ) -> Result<Self, JsonError<'read, B, S>> {
51    value
52      .to_number()?
53      .i64()
54      .ok_or(JsonError::TypeError)?
55      .try_into()
56      .map_err(|_| JsonError::TypeError)
57  }
58}
59impl JsonDeserialize for u16 {
60  fn deserialize<'read, 'parent, B: Read<'read>, S: Stack>(
61    value: Value<'read, 'parent, B, S>,
62  ) -> Result<Self, JsonError<'read, B, S>> {
63    value
64      .to_number()?
65      .i64()
66      .ok_or(JsonError::TypeError)?
67      .try_into()
68      .map_err(|_| JsonError::TypeError)
69  }
70}
71impl JsonDeserialize for u32 {
72  fn deserialize<'read, 'parent, B: Read<'read>, S: Stack>(
73    value: Value<'read, 'parent, B, S>,
74  ) -> Result<Self, JsonError<'read, B, S>> {
75    value
76      .to_number()?
77      .i64()
78      .ok_or(JsonError::TypeError)?
79      .try_into()
80      .map_err(|_| JsonError::TypeError)
81  }
82}
83impl JsonDeserialize for u64 {
84  fn deserialize<'read, 'parent, B: Read<'read>, S: Stack>(
85    value: Value<'read, 'parent, B, S>,
86  ) -> Result<Self, JsonError<'read, B, S>> {
87    value
88      .to_number()?
89      .i64()
90      .ok_or(JsonError::TypeError)?
91      .try_into()
92      .map_err(|_| JsonError::TypeError)
93  }
94}
95
96impl JsonDeserialize for bool {
97  fn deserialize<'read, 'parent, B: Read<'read>, S: Stack>(
98    value: Value<'read, 'parent, B, S>,
99  ) -> Result<Self, JsonError<'read, B, S>> {
100    value.to_bool()
101  }
102}
103
104/// Deserialize `null` as `()`.
105impl JsonDeserialize for () {
106  fn deserialize<'read, 'parent, B: Read<'read>, S: Stack>(
107    value: Value<'read, 'parent, B, S>,
108  ) -> Result<Self, JsonError<'read, B, S>> {
109    value.to_null()
110  }
111}
112
113struct IntInterator {
114  buf: [u8; 20],
115  i: usize,
116  len: usize,
117}
118impl IntInterator {
119  fn new(value: impl core::fmt::Display) -> Self {
120    use core::fmt::Write;
121
122    /// A `core::fmt::Write` which writes to a slice.
123    ///
124    /// We use this to achieve a non-allocating `core::fmt::Write` for primitives we know a bound
125    /// for.
126    struct SliceWrite<'a>(&'a mut [u8], usize);
127    impl<'a> Write for SliceWrite<'a> {
128      #[inline(always)]
129      fn write_str(&mut self, s: &str) -> core::fmt::Result {
130        let remaining = self.0.len() - self.1;
131        if remaining < s.len() {
132          Err(core::fmt::Error)?;
133        }
134        self.0[self.1 .. (self.1 + s.len())].copy_from_slice(s.as_bytes());
135        self.1 += s.len();
136        Ok(())
137      }
138    }
139
140    let mut buf = [0; 20];
141    let mut writer = SliceWrite(&mut buf, 0);
142    write!(&mut writer, "{}", value).expect("integer primitive exceeded 20 base-10 digits");
143    let len = writer.1;
144
145    IntInterator { buf, i: 0, len }
146  }
147}
148impl Iterator for IntInterator {
149  type Item = char;
150  fn next(&mut self) -> Option<Self::Item> {
151    if self.i == self.len {
152      None?;
153    }
154    let result = self.buf[self.i];
155    self.i += 1;
156    // This is a safe cast so long as Rust's display of an `u64` yields ASCII
157    Some(result as char)
158  }
159}
160impl JsonSerialize for i8 {
161  fn serialize(&self) -> impl Iterator<Item = char> {
162    IntInterator::new(*self)
163  }
164}
165impl JsonSerialize for i16 {
166  fn serialize(&self) -> impl Iterator<Item = char> {
167    IntInterator::new(*self)
168  }
169}
170impl JsonSerialize for i32 {
171  fn serialize(&self) -> impl Iterator<Item = char> {
172    IntInterator::new(*self)
173  }
174}
175impl JsonSerialize for i64 {
176  fn serialize(&self) -> impl Iterator<Item = char> {
177    IntInterator::new(*self)
178  }
179}
180impl JsonSerialize for u8 {
181  fn serialize(&self) -> impl Iterator<Item = char> {
182    IntInterator::new(*self)
183  }
184}
185impl JsonSerialize for u16 {
186  fn serialize(&self) -> impl Iterator<Item = char> {
187    IntInterator::new(*self)
188  }
189}
190impl JsonSerialize for u32 {
191  fn serialize(&self) -> impl Iterator<Item = char> {
192    IntInterator::new(*self)
193  }
194}
195impl JsonSerialize for u64 {
196  fn serialize(&self) -> impl Iterator<Item = char> {
197    IntInterator::new(*self)
198  }
199}
200
201impl JsonSerialize for bool {
202  fn serialize(&self) -> impl Iterator<Item = char> {
203    (if *self { "true" } else { "false" }).chars()
204  }
205}
206
207/// Serialize `()` as `null`.
208impl JsonSerialize for () {
209  fn serialize(&self) -> impl Iterator<Item = char> {
210    "null".chars()
211  }
212}
213
214#[test]
215fn test_int_iterator() {
216  assert_eq!(JsonSerialize::serialize(&0u8).collect::<String>(), "0");
217  assert_eq!(JsonSerialize::serialize(&1u8).collect::<String>(), "1");
218  assert_eq!(JsonSerialize::serialize(&u64::MAX).collect::<String>(), format!("{}", u64::MAX));
219  assert_eq!(JsonSerialize::serialize(&i64::MAX).collect::<String>(), format!("{}", i64::MAX));
220  assert_eq!(JsonSerialize::serialize(&i64::MIN).collect::<String>(), format!("{}", i64::MIN));
221}