From 75d89023714cec395dbfd6fbc75a206347aba6aa Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 21 Aug 2021 13:54:13 -0700 Subject: [PATCH] Use try_fold in default implementation of collect_seq, collect_map --- serde/build.rs | 3 +++ serde/src/ser/mod.rs | 30 ++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/serde/build.rs b/serde/build.rs index 392647964..52834bfbe 100644 --- a/serde/build.rs +++ b/serde/build.rs @@ -62,8 +62,11 @@ fn main() { // Inclusive ranges methods stabilized in Rust 1.27: // https://github.com/rust-lang/rust/pull/50758 + // Also Iterator::try_for_each: + // https://blog.rust-lang.org/2018/06/21/Rust-1.27.html#library-stabilizations if minor >= 27 { println!("cargo:rustc-cfg=range_inclusive"); + println!("cargo:rustc-cfg=iterator_try_fold"); } // Non-zero integers stabilized in Rust 1.28: diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index d686c5ad4..d5bca09f9 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -1279,9 +1279,20 @@ pub trait Serializer: Sized { { let iter = iter.into_iter(); let mut serializer = try!(self.serialize_seq(iterator_len_hint(&iter))); - for item in iter { - try!(serializer.serialize_element(&item)); + + #[cfg(iterator_try_fold)] + { + let mut iter = iter; + try!(iter.try_for_each(|item| serializer.serialize_element(&item))); + } + + #[cfg(not(iterator_try_fold))] + { + for item in iter { + try!(serializer.serialize_element(&item)); + } } + serializer.end() } @@ -1319,9 +1330,20 @@ pub trait Serializer: Sized { { let iter = iter.into_iter(); let mut serializer = try!(self.serialize_map(iterator_len_hint(&iter))); - for (key, value) in iter { - try!(serializer.serialize_entry(&key, &value)); + + #[cfg(iterator_try_fold)] + { + let mut iter = iter; + try!(iter.try_for_each(|(key, value)| serializer.serialize_entry(&key, &value))); + } + + #[cfg(not(iterator_try_fold))] + { + for (key, value) in iter { + try!(serializer.serialize_entry(&key, &value)); + } } + serializer.end() }