diff --git a/src/de.rs b/src/de.rs index 890a516..3aa8f29 100644 --- a/src/de.rs +++ b/src/de.rs @@ -4,7 +4,7 @@ use crate::error::{Error, ErrorCode, Result}; use crate::lib::str::FromStr; use crate::lib::*; use crate::number::Number; -use crate::read::{self, Reference}; +use crate::read::{self, Fused, Reference}; use serde::de::{self, Expected, Unexpected}; use serde::{forward_to_deserialize_any, serde_if_integer128}; @@ -2181,6 +2181,13 @@ where } } +impl<'de, R, T> FusedIterator for StreamDeserializer<'de, R, T> +where + R: Read<'de> + Fused, + T: de::Deserialize<'de>, +{ +} + ////////////////////////////////////////////////////////////////////////////// fn from_trait<'de, R, T>(read: R) -> Result diff --git a/src/lib.rs b/src/lib.rs index a276b38..83a7bad 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -363,6 +363,7 @@ mod lib { pub use self::core::default::{self, Default}; pub use self::core::fmt::{self, Debug, Display}; pub use self::core::hash::{self, Hash}; + pub use self::core::iter::FusedIterator; pub use self::core::marker::{self, PhantomData}; pub use self::core::result::{self, Result}; pub use self::core::{borrow, char, cmp, iter, mem, num, ops, slice, str}; diff --git a/src/map.rs b/src/map.rs index 9891d5b..449c453 100644 --- a/src/map.rs +++ b/src/map.rs @@ -397,6 +397,8 @@ macro_rules! delegate_iterator { self.iter.len() } } + + impl $($generics)* FusedIterator for $name $($generics)* {} } } diff --git a/src/read.rs b/src/read.rs index 01d3068..b8233db 100644 --- a/src/read.rs +++ b/src/read.rs @@ -718,6 +718,11 @@ impl<'a> Read<'a> for StrRead<'a> { ////////////////////////////////////////////////////////////////////////////// +/// Marker for whether StreamDeserializer can implement FusedIterator. +pub trait Fused: private::Sealed {} +impl<'a> Fused for SliceRead<'a> {} +impl<'a> Fused for StrRead<'a> {} + // Lookup table of bytes that must be escaped. A value of true at index i means // that byte i requires an escape sequence in the input. static ESCAPE: [bool; 256] = {