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