1pub(crate) mod duration;
2
3use crate::prelude::*;
4
5#[cfg(feature = "alloc")]
7#[inline]
8pub(crate) fn size_hint_cautious<Element>(hint: Option<usize>) -> usize {
9 const MAX_PREALLOC_BYTES: usize = 1024 * 1024;
10
11 if core::mem::size_of::<Element>() == 0 {
12 0
13 } else {
14 core::cmp::min(
15 hint.unwrap_or(0),
16 MAX_PREALLOC_BYTES / core::mem::size_of::<Element>(),
17 )
18 }
19}
20
21#[cfg(feature = "alloc")]
23#[inline]
24pub fn size_hint_from_bounds<I>(iter: &I) -> Option<usize>
25where
26 I: Iterator,
27{
28 fn _size_hint_from_bounds(bounds: (usize, Option<usize>)) -> Option<usize> {
29 match bounds {
30 (lower, Some(upper)) if lower == upper => Some(upper),
31 _ => None,
32 }
33 }
34 _size_hint_from_bounds(iter.size_hint())
35}
36
37pub(crate) const NANOS_PER_SEC: u128 = 1_000_000_000;
38pub(crate) const NANOS_PER_SEC_F64: f64 = 1_000_000_000.0;
39pub(crate) const U64_MAX: u128 = u64::MAX as u128;
44
45pub(crate) struct MapIter<'de, A, K, V> {
46 pub(crate) access: A,
47 marker: PhantomData<(&'de (), K, V)>,
48}
49
50impl<'de, A, K, V> MapIter<'de, A, K, V> {
51 pub(crate) fn new(access: A) -> Self
52 where
53 A: MapAccess<'de>,
54 {
55 Self {
56 access,
57 marker: PhantomData,
58 }
59 }
60}
61
62impl<'de, A, K, V> Iterator for MapIter<'de, A, K, V>
63where
64 A: MapAccess<'de>,
65 K: Deserialize<'de>,
66 V: Deserialize<'de>,
67{
68 type Item = Result<(K, V), A::Error>;
69
70 fn next(&mut self) -> Option<Self::Item> {
71 self.access.next_entry().transpose()
72 }
73
74 fn size_hint(&self) -> (usize, Option<usize>) {
75 match self.access.size_hint() {
76 Some(size) => (size, Some(size)),
77 None => (0, None),
78 }
79 }
80}
81
82pub(crate) struct SeqIter<'de, A, T> {
83 access: A,
84 marker: PhantomData<(&'de (), T)>,
85}
86
87impl<'de, A, T> SeqIter<'de, A, T> {
88 pub(crate) fn new(access: A) -> Self
89 where
90 A: SeqAccess<'de>,
91 {
92 Self {
93 access,
94 marker: PhantomData,
95 }
96 }
97}
98
99impl<'de, A, T> Iterator for SeqIter<'de, A, T>
100where
101 A: SeqAccess<'de>,
102 T: Deserialize<'de>,
103{
104 type Item = Result<T, A::Error>;
105
106 fn next(&mut self) -> Option<Self::Item> {
107 self.access.next_element().transpose()
108 }
109
110 fn size_hint(&self) -> (usize, Option<usize>) {
111 match self.access.size_hint() {
112 Some(size) => (size, Some(size)),
113 None => (0, None),
114 }
115 }
116}
117
118pub(crate) fn duration_signed_from_secs_f64(secs: f64) -> Result<DurationSigned, &'static str> {
119 const MAX_NANOS_F64: f64 = ((U64_MAX + 1) * NANOS_PER_SEC) as f64;
120 let mut nanos = secs * NANOS_PER_SEC_F64;
123 if !nanos.is_finite() {
124 return Err("got non-finite value when converting float to duration");
125 }
126 if nanos >= MAX_NANOS_F64 {
127 return Err("overflow when converting float to duration");
128 }
129 let mut sign = Sign::Positive;
130 if nanos < 0.0 {
131 nanos = -nanos;
132 sign = Sign::Negative;
133 }
134 let nanos = nanos as u128;
135 Ok(DurationSigned::new(
136 sign,
137 (nanos / NANOS_PER_SEC) as u64,
138 (nanos % NANOS_PER_SEC) as u32,
139 ))
140}
141
142pub(crate) fn array_from_iterator<I, T, E, const N: usize>(
148 mut iter: I,
149 expected: &dyn Expected,
150) -> Result<[T; N], E>
151where
152 I: Iterator<Item = Result<T, E>>,
153 E: DeError,
154{
155 use core::mem::MaybeUninit;
156
157 fn drop_array_elems<T, const N: usize>(num: usize, mut arr: [MaybeUninit<T>; N]) {
158 arr[..num].iter_mut().for_each(|elem| {
159 unsafe { core::ptr::drop_in_place(elem.as_mut_ptr()) };
162 });
163 }
164
165 let mut arr: [MaybeUninit<T>; N] = unsafe { MaybeUninit::uninit().assume_init() };
173
174 for (idx, elem) in arr[..].iter_mut().enumerate() {
180 *elem = match iter.next() {
181 Some(Ok(value)) => MaybeUninit::new(value),
182 Some(Err(err)) => {
183 drop_array_elems(idx, arr);
184 return Err(err);
185 }
186 None => {
187 drop_array_elems(idx, arr);
188 return Err(DeError::invalid_length(idx, expected));
189 }
190 };
191 }
192
193 Ok(unsafe { core::mem::transmute_copy::<_, [T; N]>(&arr) })
198}
199
200struct BufWriter<'a> {
202 bytes: &'a mut [u8],
203 offset: usize,
204}
205
206impl<'a> BufWriter<'a> {
207 fn new(bytes: &'a mut [u8]) -> Self {
208 BufWriter { bytes, offset: 0 }
209 }
210
211 fn into_str(self) -> &'a str {
212 let slice = &self.bytes[..self.offset];
213 core::str::from_utf8(slice)
214 .unwrap_or("Failed to extract valid string from BufWriter. This should never happen.")
215 }
216}
217
218impl core::fmt::Write for BufWriter<'_> {
219 fn write_str(&mut self, s: &str) -> fmt::Result {
220 if s.len() > self.bytes.len() - self.offset {
221 Err(fmt::Error)
222 } else {
223 self.bytes[self.offset..self.offset + s.len()].copy_from_slice(s.as_bytes());
224 self.offset += s.len();
225 Ok(())
226 }
227 }
228}
229
230pub(crate) fn get_unexpected_i128(value: i128, buf: &mut [u8; 58]) -> Unexpected<'_> {
232 let mut writer = BufWriter::new(buf);
233 fmt::Write::write_fmt(&mut writer, format_args!("integer `{value}` as i128")).unwrap();
234 Unexpected::Other(writer.into_str())
235}
236
237pub(crate) fn get_unexpected_u128(value: u128, buf: &mut [u8; 58]) -> Unexpected<'_> {
239 let mut writer = BufWriter::new(buf);
240 fmt::Write::write_fmt(&mut writer, format_args!("integer `{value}` as u128")).unwrap();
241 Unexpected::Other(writer.into_str())
242}
243
244#[cfg(any(
245 feature = "schemars_0_8",
246 feature = "schemars_0_9",
247 feature = "schemars_1"
248))]
249pub(crate) struct DropGuard<T, F: FnOnce(T)> {
250 value: core::mem::ManuallyDrop<T>,
251 guard: Option<F>,
252}
253
254#[cfg(any(
255 feature = "schemars_0_8",
256 feature = "schemars_0_9",
257 feature = "schemars_1"
258))]
259impl<T, F: FnOnce(T)> DropGuard<T, F> {
260 pub fn new(value: T, guard: F) -> Self {
261 Self {
262 value: core::mem::ManuallyDrop::new(value),
263 guard: Some(guard),
264 }
265 }
266
267 pub fn unguarded(value: T) -> Self {
268 Self {
269 value: core::mem::ManuallyDrop::new(value),
270 guard: None,
271 }
272 }
273}
274
275#[cfg(any(
276 feature = "schemars_0_8",
277 feature = "schemars_0_9",
278 feature = "schemars_1"
279))]
280impl<T, F: FnOnce(T)> core::ops::Deref for DropGuard<T, F> {
281 type Target = T;
282
283 fn deref(&self) -> &Self::Target {
284 &self.value
285 }
286}
287
288#[cfg(any(
289 feature = "schemars_0_8",
290 feature = "schemars_0_9",
291 feature = "schemars_1"
292))]
293impl<T, F: FnOnce(T)> core::ops::DerefMut for DropGuard<T, F> {
294 fn deref_mut(&mut self) -> &mut Self::Target {
295 &mut self.value
296 }
297}
298
299#[cfg(any(
300 feature = "schemars_0_8",
301 feature = "schemars_0_9",
302 feature = "schemars_1"
303))]
304impl<T, F: FnOnce(T)> Drop for DropGuard<T, F> {
305 fn drop(&mut self) {
306 let value = unsafe { core::mem::ManuallyDrop::take(&mut self.value) };
308
309 if let Some(guard) = self.guard.take() {
310 guard(value);
311 }
312 }
313}
314
315#[cfg(any(feature = "schemars_0_9", feature = "schemars_1"))]
316pub(crate) trait NumberExt: Sized {
317 fn saturating_sub(&self, count: u64) -> Self;
318}
319
320#[cfg(any(feature = "schemars_0_9", feature = "schemars_1"))]
321impl NumberExt for serde_json::Number {
322 fn saturating_sub(&self, count: u64) -> Self {
323 if let Some(v) = self.as_u64() {
324 return v.saturating_sub(count).into();
325 }
326
327 if let Some(v) = self.as_i64() {
328 if count < i64::MAX as u64 {
329 return v.saturating_sub(count as _).into();
330 }
331 }
332
333 if let Some(v) = self.as_f64() {
334 return serde_json::Number::from_f64(v - (count as f64))
335 .expect("saturating_sub resulted in NaN");
336 }
337
338 unreachable!()
339 }
340}