pub(crate) mod duration;
use crate::prelude::*;
#[cfg(feature = "alloc")]
#[inline]
pub(crate) fn size_hint_cautious<Element>(hint: Option<usize>) -> usize {
const MAX_PREALLOC_BYTES: usize = 1024 * 1024;
if core::mem::size_of::<Element>() == 0 {
0
} else {
core::cmp::min(
hint.unwrap_or(0),
MAX_PREALLOC_BYTES / core::mem::size_of::<Element>(),
)
}
}
#[cfg(feature = "alloc")]
#[inline]
pub fn size_hint_from_bounds<I>(iter: &I) -> Option<usize>
where
I: Iterator,
{
fn _size_hint_from_bounds(bounds: (usize, Option<usize>)) -> Option<usize> {
match bounds {
(lower, Some(upper)) if lower == upper => Some(upper),
_ => None,
}
}
_size_hint_from_bounds(iter.size_hint())
}
pub(crate) const NANOS_PER_SEC: u128 = 1_000_000_000;
pub(crate) const NANOS_PER_SEC_F64: f64 = 1_000_000_000.0;
pub(crate) const U64_MAX: u128 = u64::MAX as u128;
pub(crate) struct MapIter<'de, A, K, V> {
pub(crate) access: A,
marker: PhantomData<(&'de (), K, V)>,
}
impl<'de, A, K, V> MapIter<'de, A, K, V> {
pub(crate) fn new(access: A) -> Self
where
A: MapAccess<'de>,
{
Self {
access,
marker: PhantomData,
}
}
}
impl<'de, A, K, V> Iterator for MapIter<'de, A, K, V>
where
A: MapAccess<'de>,
K: Deserialize<'de>,
V: Deserialize<'de>,
{
type Item = Result<(K, V), A::Error>;
fn next(&mut self) -> Option<Self::Item> {
self.access.next_entry().transpose()
}
fn size_hint(&self) -> (usize, Option<usize>) {
match self.access.size_hint() {
Some(size) => (size, Some(size)),
None => (0, None),
}
}
}
pub(crate) struct SeqIter<'de, A, T> {
access: A,
marker: PhantomData<(&'de (), T)>,
}
impl<'de, A, T> SeqIter<'de, A, T> {
pub(crate) fn new(access: A) -> Self
where
A: SeqAccess<'de>,
{
Self {
access,
marker: PhantomData,
}
}
}
impl<'de, A, T> Iterator for SeqIter<'de, A, T>
where
A: SeqAccess<'de>,
T: Deserialize<'de>,
{
type Item = Result<T, A::Error>;
fn next(&mut self) -> Option<Self::Item> {
self.access.next_element().transpose()
}
fn size_hint(&self) -> (usize, Option<usize>) {
match self.access.size_hint() {
Some(size) => (size, Some(size)),
None => (0, None),
}
}
}
pub(crate) fn duration_signed_from_secs_f64(secs: f64) -> Result<DurationSigned, &'static str> {
const MAX_NANOS_F64: f64 = ((U64_MAX + 1) * NANOS_PER_SEC) as f64;
let mut nanos = secs * NANOS_PER_SEC_F64;
if !nanos.is_finite() {
return Err("got non-finite value when converting float to duration");
}
if nanos >= MAX_NANOS_F64 {
return Err("overflow when converting float to duration");
}
let mut sign = Sign::Positive;
if nanos < 0.0 {
nanos = -nanos;
sign = Sign::Negative;
}
let nanos = nanos as u128;
Ok(DurationSigned::new(
sign,
(nanos / NANOS_PER_SEC) as u64,
(nanos % NANOS_PER_SEC) as u32,
))
}
pub(crate) fn array_from_iterator<I, T, E, const N: usize>(
mut iter: I,
expected: &dyn Expected,
) -> Result<[T; N], E>
where
I: Iterator<Item = Result<T, E>>,
E: DeError,
{
use core::mem::MaybeUninit;
fn drop_array_elems<T, const N: usize>(num: usize, mut arr: [MaybeUninit<T>; N]) {
arr[..num].iter_mut().for_each(|elem| {
unsafe { core::ptr::drop_in_place(elem.as_mut_ptr()) };
});
}
let mut arr: [MaybeUninit<T>; N] = unsafe { MaybeUninit::uninit().assume_init() };
for (idx, elem) in arr[..].iter_mut().enumerate() {
*elem = match iter.next() {
Some(Ok(value)) => MaybeUninit::new(value),
Some(Err(err)) => {
drop_array_elems(idx, arr);
return Err(err);
}
None => {
drop_array_elems(idx, arr);
return Err(DeError::invalid_length(idx, expected));
}
};
}
Ok(unsafe { core::mem::transmute_copy::<_, [T; N]>(&arr) })
}
struct BufWriter<'a> {
bytes: &'a mut [u8],
offset: usize,
}
impl<'a> BufWriter<'a> {
fn new(bytes: &'a mut [u8]) -> Self {
BufWriter { bytes, offset: 0 }
}
fn into_str(self) -> &'a str {
let slice = &self.bytes[..self.offset];
core::str::from_utf8(slice)
.unwrap_or("Failed to extract valid string from BufWriter. This should never happen.")
}
}
impl core::fmt::Write for BufWriter<'_> {
fn write_str(&mut self, s: &str) -> fmt::Result {
if s.len() > self.bytes.len() - self.offset {
Err(fmt::Error)
} else {
self.bytes[self.offset..self.offset + s.len()].copy_from_slice(s.as_bytes());
self.offset += s.len();
Ok(())
}
}
}
pub(crate) fn get_unexpected_i128(value: i128, buf: &mut [u8; 58]) -> Unexpected<'_> {
let mut writer = BufWriter::new(buf);
fmt::Write::write_fmt(&mut writer, format_args!("integer `{value}` as i128")).unwrap();
Unexpected::Other(writer.into_str())
}
pub(crate) fn get_unexpected_u128(value: u128, buf: &mut [u8; 58]) -> Unexpected<'_> {
let mut writer = BufWriter::new(buf);
fmt::Write::write_fmt(&mut writer, format_args!("integer `{value}` as u128")).unwrap();
Unexpected::Other(writer.into_str())
}