diff --git a/serde_with/src/content/de.rs b/serde_with/src/content/de.rs index 98e8a530..e6bbf518 100644 --- a/serde_with/src/content/de.rs +++ b/serde_with/src/content/de.rs @@ -283,7 +283,7 @@ impl<'de> Visitor<'de> for ContentVisitor<'de> { where V: SeqAccess<'de>, { - let mut vec = Vec::with_capacity(size_hint_cautious(visitor.size_hint())); + let mut vec = Vec::with_capacity(size_hint_cautious::>(visitor.size_hint())); while let Some(e) = visitor.next_element()? { vec.push(e); } @@ -294,7 +294,9 @@ impl<'de> Visitor<'de> for ContentVisitor<'de> { where V: MapAccess<'de>, { - let mut vec = Vec::with_capacity(size_hint_cautious(visitor.size_hint())); + let mut vec = Vec::with_capacity(size_hint_cautious::<(Content<'_>, Content<'_>)>( + visitor.size_hint(), + )); while let Some(kv) = visitor.next_entry()? { vec.push(kv); } diff --git a/serde_with/src/de/impls.rs b/serde_with/src/de/impls.rs index 7ea590f3..76a8852c 100644 --- a/serde_with/src/de/impls.rs +++ b/serde_with/src/de/impls.rs @@ -400,7 +400,7 @@ macro_rules! seq_impl { A: SeqAccess<'de>, { #[allow(clippy::redundant_closure_call)] - let mut values = ($with_capacity)(utils::size_hint_cautious(seq.size_hint())); + let mut values = ($with_capacity)(utils::size_hint_cautious::(seq.size_hint())); while let Some(value) = seq .next_element()? @@ -465,7 +465,7 @@ macro_rules! map_impl { A: MapAccess<'de>, { #[allow(clippy::redundant_closure_call)] - let mut values = ($with_capacity)(utils::size_hint_cautious(map.size_hint())); + let mut values = ($with_capacity)(utils::size_hint_cautious::<(K, V)>(map.size_hint())); while let Some((key, value)) = (map.next_entry())?.map(|(k, v): (DeserializeAsWrap::, DeserializeAsWrap::)| (k.into_inner(), v.into_inner())) { values.insert(key, value); diff --git a/serde_with/src/utils.rs b/serde_with/src/utils.rs index 5bd48daf..77baec4e 100644 --- a/serde_with/src/utils.rs +++ b/serde_with/src/utils.rs @@ -5,8 +5,17 @@ use crate::prelude::*; /// Re-Implementation of `serde::private::de::size_hint::cautious` #[cfg(feature = "alloc")] #[inline] -pub(crate) fn size_hint_cautious(hint: Option) -> usize { - core::cmp::min(hint.unwrap_or(0), 4096) +pub(crate) fn size_hint_cautious(hint: Option) -> usize { + const MAX_PREALLOC_BYTES: usize = 1024 * 1024; + + if core::mem::size_of::() == 0 { + 0 + } else { + core::cmp::min( + hint.unwrap_or(0), + MAX_PREALLOC_BYTES / core::mem::size_of::(), + ) + } } /// Re-Implementation of `serde::private::de::size_hint::from_bounds`