diff options
author | Joel Galenson <jgalenson@google.com> | 2021-10-05 02:50:14 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-10-05 02:50:14 +0000 |
commit | 0623dde5d2d9f458d11a4d39bbb49c6960b03550 (patch) | |
tree | dcdcdf580f1d5e13f66f39a30d019d195bc01324 | |
parent | 0b52c693d156ff7b4b76be1a22f9f12da0c5abef (diff) | |
parent | 453b8fcadf64ed4c3433a562479d25001ee7d425 (diff) | |
download | peeking_take_while-0623dde5d2d9f458d11a4d39bbb49c6960b03550.tar.gz |
Upgrade rust/crates/peeking_take_while to 1.0.0 am: 2ad6afbd5a am: 40cc7b8646 am: 8ff6149e77 am: 7ebcc8378b am: 453b8fcadf
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/peeking_take_while/+/1833579
Change-Id: I4ee640b1d24c8ca194365a23d728f21501be2229
-rw-r--r-- | .cargo_vcs_info.json | 5 | ||||
-rw-r--r-- | Android.bp | 20 | ||||
-rw-r--r-- | Cargo.toml | 24 | ||||
-rw-r--r-- | Cargo.toml.orig | 15 | ||||
-rw-r--r-- | METADATA | 10 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | patches/std.diff | 15 | ||||
-rw-r--r-- | src/lib.rs | 188 |
8 files changed, 219 insertions, 60 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json new file mode 100644 index 0000000..cae8cb0 --- /dev/null +++ b/.cargo_vcs_info.json @@ -0,0 +1,5 @@ +{ + "git": { + "sha1": "f201f1457476f0829c4d7704a1cc02bef7aacb83" + } +} @@ -1,4 +1,5 @@ // This file is generated by cargo2android.py --run --dependencies --device --tests. +// Do not modify this file as changes will be overridden on upgrade. package { default_applicable_licenses: [ @@ -40,27 +41,36 @@ license { rust_library { name: "libpeeking_take_while", + // has rustc warnings host_supported: true, crate_name: "peeking_take_while", + cargo_env_compat: true, + cargo_pkg_version: "1.0.0", srcs: ["src/lib.rs"], - edition: "2015", + edition: "2018", } rust_defaults { - name: "peeking_take_while_defaults", + name: "peeking_take_while_test_defaults", crate_name: "peeking_take_while", + // has rustc warnings srcs: ["src/lib.rs"], + cargo_env_compat: true, + cargo_pkg_version: "1.0.0", test_suites: ["general-tests"], auto_gen_config: true, - edition: "2015", + edition: "2018", } rust_test_host { name: "peeking_take_while_host_test_src_lib", - defaults: ["peeking_take_while_defaults"], + defaults: ["peeking_take_while_test_defaults"], + test_options: { + unit_test: true, + }, } rust_test { name: "peeking_take_while_device_test_src_lib", - defaults: ["peeking_take_while_defaults"], + defaults: ["peeking_take_while_test_defaults"], } @@ -1,14 +1,24 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + [package] +edition = "2018" +name = "peeking_take_while" +version = "1.0.0" authors = ["Nick Fitzgerald <fitzgen@gmail.com>"] description = "Like `Iterator::take_while`, but calls the predicate on a peeked value. This allows you to use `Iterator::by_ref` and `Iterator::take_while` together, and still get the first value for which the `take_while` predicate returned false after dropping the `by_ref`." -categories = ["rust-patterns"] -keywords = ["iterator", "take_while", "peek", "by_ref"] -license = "Apache-2.0/MIT" -name = "peeking_take_while" readme = "./README.md" +keywords = ["iterator", "take_while", "peek", "by_ref"] +categories = ["no-std", "rust-patterns"] +license = "MIT OR Apache-2.0" repository = "https://github.com/fitzgen/peeking_take_while" -version = "0.1.2" - -[badges] [badges.travis-ci] repository = "fitzgen/peeking_take_while" diff --git a/Cargo.toml.orig b/Cargo.toml.orig new file mode 100644 index 0000000..5075103 --- /dev/null +++ b/Cargo.toml.orig @@ -0,0 +1,15 @@ +[package] +authors = ["Nick Fitzgerald <fitzgen@gmail.com>"] +description = "Like `Iterator::take_while`, but calls the predicate on a peeked value. This allows you to use `Iterator::by_ref` and `Iterator::take_while` together, and still get the first value for which the `take_while` predicate returned false after dropping the `by_ref`." +categories = ["no-std", "rust-patterns"] +edition = "2018" +keywords = ["iterator", "take_while", "peek", "by_ref"] +license = "MIT OR Apache-2.0" +name = "peeking_take_while" +readme = "./README.md" +repository = "https://github.com/fitzgen/peeking_take_while" +version = "1.0.0" + +[badges] +[badges.travis-ci] +repository = "fitzgen/peeking_take_while" @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/peeking_take_while/peeking_take_while-0.1.2.crate" + value: "https://static.crates.io/crates/peeking_take_while/peeking_take_while-1.0.0.crate" } - version: "0.1.2" + version: "1.0.0" license_type: NOTICE last_upgrade_date { - year: 2020 - month: 3 - day: 31 + year: 2021 + month: 9 + day: 30 } } @@ -15,8 +15,6 @@ hand, `take_while` will consume that first item for which the predicate returns `false`, and it will be lost. ```rust -extern crate peeking_take_while; - // Bring the `peeking_take_while` method for peekable iterators into // scope. use peeking_take_while::PeekableExt; diff --git a/patches/std.diff b/patches/std.diff new file mode 100644 index 0000000..3849c79 --- /dev/null +++ b/patches/std.diff @@ -0,0 +1,15 @@ +diff --git a/src/lib.rs b/src/lib.rs +index 9fc1c3e..ee4c928 100644 +--- a/src/lib.rs ++++ b/src/lib.rs +@@ -67,6 +67,10 @@ + unsafe_code + )] + ++// ANDROID: Unconditionally use std to allow building as a dylib ++#[macro_use] ++extern crate std; ++ + use core::fmt; + + /// The `Iterator` extension trait that provides the `peeking_take_while` @@ -1,5 +1,3 @@ -//! # `peeking_take_while` -//! //! Provides the `peeking_take_while` iterator adaptor method. //! //! The `peeking_take_while` method is very similar to `take_while`, but behaves @@ -12,9 +10,11 @@ //! other hand, `take_while` will consume that first item for which the //! predicate returns `false`, and it will be lost. //! -//! ``` -//! extern crate peeking_take_while; +//! In case the closure may have side effects, it could be necessary to apply +//! [`fuse`](Iterator::fuse) on the returned iterator, to prevent the predicate +//! from being called after it first returned `false`. //! +//! ``` //! // Bring the `peeking_take_while` method for peekable iterators into //! // scope. //! use peeking_take_while::PeekableExt; @@ -58,60 +58,166 @@ //! # } //! ``` -use std::iter::Peekable; +#![no_std] +#![forbid( + clippy::as_conversions, + clippy::cast_ptr_alignment, + missing_docs, + trivial_casts, + unsafe_code +)] -/// The iterator returned by `peeking_take_while`. +// ANDROID: Unconditionally use std to allow building as a dylib +#[macro_use] +extern crate std; + +use core::fmt; + +/// The `Iterator` extension trait that provides the `peeking_take_while` +/// method. /// /// See the [module documentation](./index.html) for details. -pub struct PeekingTakeWhile<'a, I, P> - where I: 'a + Iterator +pub trait PeekableExt<I>: Iterator +where + I: Iterator, { - iter: &'a mut Peekable<I>, - predicate: P, + /// The `peeking_take_while` method is very similar to `take_while`, but behaves + /// differently when used with a borrowed iterator (perhaps returned by + /// `Iterator::by_ref`). + /// + /// `peeking_take_while` peeks at the next item in the iterator and runs the + /// predicate on that peeked item. This avoids consuming the first item yielded + /// by the underlying iterator for which the predicate returns `false`. On the + /// other hand, `take_while` will consume that first item for which the + /// predicate returns `false`, and it will be lost. + /// + /// In contrast to `take_while`, iterating the iterator might call the predicate again + /// after it first returned `false` (the returned iterator isn't fused). + /// If that is not intended, calling [`fuse`](Iterator::fuse) on the returned iterator + /// prevents that. + fn peeking_take_while<P>(&mut self, predicate: P) -> PeekingTakeWhile<'_, I, P> + where + P: FnMut(&Self::Item) -> bool; } -impl<'a, I, P> Iterator for PeekingTakeWhile<'a, I, P> - where I: Iterator, - I::Item: ::std::fmt::Debug, - P: FnMut(&<I as Iterator>::Item) -> bool -{ - type Item = <I as Iterator>::Item; - - fn next(&mut self) -> Option<Self::Item> { - let predicate = &mut self.predicate; - if self.iter.peek().map_or(false, |x| !(predicate)(x)) { - None - } else { - self.iter.next() +impl<I: Iterator> PeekableExt<I> for core::iter::Peekable<I> { + #[inline] + fn peeking_take_while<P>(&mut self, predicate: P) -> PeekingTakeWhile<'_, I, P> + where + P: FnMut(&Self::Item) -> bool, + { + PeekingTakeWhile { + iter: self, + predicate, } } } -/// The `Iterator` extension trait that provides the `peeking_take_while` -/// method. +/// The iterator returned by `peeking_take_while`. /// /// See the [module documentation](./index.html) for details. -pub trait PeekableExt<'a, I>: Iterator - where I: 'a + Iterator +pub struct PeekingTakeWhile<'a, I, P> +where + I: Iterator, { - /// The `Iterator` extension trait that provides the `peeking_take_while` - /// method. - /// - /// See the [module documentation](./index.html) for details. - fn peeking_take_while<P>(&'a mut self, predicate: P) -> PeekingTakeWhile<'a, I, P> - where Self: Sized, - P: FnMut(&<Self as Iterator>::Item) -> bool; + pub(crate) iter: &'a mut core::iter::Peekable<I>, + pub(crate) predicate: P, } -impl<'a, I> PeekableExt<'a, I> for Peekable<I> - where I: 'a + Iterator +impl<I, P> fmt::Debug for PeekingTakeWhile<'_, I, P> +where + I: Iterator + fmt::Debug, + I::Item: fmt::Debug, { - fn peeking_take_while<P>(&'a mut self, predicate: P) -> PeekingTakeWhile<I, P> - where P: FnMut(&<Self as Iterator>::Item) -> bool + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("PeekingTakeWhile") + .field("iter", &self.iter) + .finish() + } +} + +impl<I, P> Iterator for PeekingTakeWhile<'_, I, P> +where + I: Iterator, + P: FnMut(&I::Item) -> bool, +{ + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option<Self::Item> { + self.iter.next_if(&mut self.predicate) + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + // can't know a lower bound, due to the predicate + (0, self.iter.size_hint().1) + } + + #[inline] + fn fold<B, F>(mut self, mut accum: B, mut f: F) -> B + where + F: FnMut(B, I::Item) -> B, { - PeekingTakeWhile { - iter: self, - predicate: predicate, + while let Some(x) = self.iter.next_if(&mut self.predicate) { + accum = f(accum, x); } + accum + } +} + +// interestingly, `PeekingTakeWhile` is not automatically fused, +// even when the inner iterator is fused, see also: `tests::not_fused`. + +#[cfg(test)] +mod tests { + use crate::PeekableExt; + + #[test] + fn basic() { + let mut it0 = (1..11).peekable(); + let a: u32 = it0.peeking_take_while(|&i| i < 5).sum(); + let b: u32 = it0.sum(); + assert_eq!(a, 10); + assert_eq!(b, 45); + } + + #[test] + fn basic_fused() { + let mut it0 = (1..11).peekable(); + let a: u32 = it0.peeking_take_while(|&i| i < 5).fuse().sum(); + let b: u32 = it0.sum(); + assert_eq!(a, 10); + assert_eq!(b, 45); + } + + #[test] + fn not_fused() { + let mut it0 = (0..10).peekable(); + let mut ax = true; + let mut it1 = it0.peeking_take_while(|_| { + ax = !ax; + ax + }); + assert!(it1.next().is_none()); + assert_eq!(it1.next(), Some(0)); + assert!(it1.next().is_none()); + assert_eq!(it1.next(), Some(1)); + assert_eq!(ax, true); + } + + #[test] + fn fused() { + let mut it0 = (0..10).peekable(); + let mut ax = true; + let mut it1 = it0 + .peeking_take_while(|_| { + ax = !ax; + ax + }) + .fuse(); + assert!(it1.next().is_none()); + assert!(it1.next().is_none()); + assert_eq!(ax, false); } } |