aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Galenson <jgalenson@google.com>2021-10-05 02:50:14 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-10-05 02:50:14 +0000
commit0623dde5d2d9f458d11a4d39bbb49c6960b03550 (patch)
treedcdcdf580f1d5e13f66f39a30d019d195bc01324
parent0b52c693d156ff7b4b76be1a22f9f12da0c5abef (diff)
parent453b8fcadf64ed4c3433a562479d25001ee7d425 (diff)
downloadpeeking_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.json5
-rw-r--r--Android.bp20
-rw-r--r--Cargo.toml24
-rw-r--r--Cargo.toml.orig15
-rw-r--r--METADATA10
-rw-r--r--README.md2
-rw-r--r--patches/std.diff15
-rw-r--r--src/lib.rs188
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"
+ }
+}
diff --git a/Android.bp b/Android.bp
index 5caa0f5..0c1448a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -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"],
}
diff --git a/Cargo.toml b/Cargo.toml
index 40aeef2..f4b6efb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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"
diff --git a/METADATA b/METADATA
index 9fc8d6a..2cb4b6c 100644
--- a/METADATA
+++ b/METADATA
@@ -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
}
}
diff --git a/README.md b/README.md
index c7486b7..988ec30 100644
--- a/README.md
+++ b/README.md
@@ -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`
diff --git a/src/lib.rs b/src/lib.rs
index 67f36d8..ee4c928 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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);
}
}