From c37cb6c3bbcbf552f316be8f6fe01d275074a3a2 Mon Sep 17 00:00:00 2001 From: Avril Date: Tue, 10 Nov 2020 17:12:29 +0000 Subject: [PATCH] maybe-many --- Cargo.toml | 6 ++--- src/maybe.rs | 69 ++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 66 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 69688fd..83cb83c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ad-hoc-iter" -version = "0.1.1" +version = "0.2.0" description = "Ad-hoc exact size owning iterator macro and other optional utils" repository = "https://git.flanchan.moe/flanchan/ad-hoc-iter" keywords = ["iterator", "macro", "iter"] @@ -9,9 +9,7 @@ edition = "2018" license = "MIT" [features] -default = ["maybe-many"] - -# Enable the `maybe` module +# Enable the incomplete `maybe` module maybe-many = [] [dependencies] diff --git a/src/maybe.rs b/src/maybe.rs index 65ccee0..7bfe10e 100644 --- a/src/maybe.rs +++ b/src/maybe.rs @@ -7,20 +7,62 @@ /// An iterator that can yield `0,1,2+` items #[derive(Debug, Clone)] pub enum MaybeMany +where U: IntoIterator { None, One(T), Many(U), } -impl MaybeMany +impl MaybeMany> { + /// A single variant + #[inline] pub fn one(value: T) -> Self + { + Self::One(value) + } +} + +impl MaybeMany> +{ + /// An empty variant that yields no values ever. + #[inline] pub fn none() -> Self + { + Self::None + } +} + +impl MaybeMany +where U: IntoIterator + +{ + /// Consume into the `Many` variant. + pub fn into_many(self) -> MaybeMany + { + MaybeMany::Many(self) + } + + /// Chain another iterator to this one + pub fn chain(self, iter: I) -> MaybeMany::IntoIter, I::IntoIter>> + where I: IntoIterator + { + MaybeMany::Many(self.into_iter().chain(iter.into_iter())) + } + + /// Into a boxed `MaybeMany` type. + pub fn boxed(self) -> MaybeMany+'static>> + where U: 'static, + T: 'static + { + MaybeMany::Many(Box::new(self.into_iter())) + } + /// Try to guess the size. /// /// * `None` => `Some(0)` /// * `One(_)` => `Some(1)` /// * `Many(_) => `None` - #[inline] pub const fn size_hint(&self) -> Option + #[inline] pub fn size_hint(&self) -> Option { match self { Self::None => Some(0), @@ -29,7 +71,7 @@ impl MaybeMany } } /// Is this an empty instance - #[inline] pub const fn is_none(&self) -> bool + #[inline] pub fn is_none(&self) -> bool { if let Self::None = self { true @@ -38,7 +80,7 @@ impl MaybeMany } } /// Is this a single value instance? - #[inline] pub const fn is_single(&self) -> bool + #[inline] pub fn is_single(&self) -> bool { if let Self::One(_) = self { true @@ -47,7 +89,7 @@ impl MaybeMany } } /// Is this a 2+ value instance? - #[inline] pub const fn is_many(&self) -> bool + #[inline] pub fn is_many(&self) -> bool { if let Self::Many(_) = self { true @@ -100,6 +142,7 @@ impl MaybeMany /// An iterator for `MaybeMany` instances. #[non_exhaustive] #[derive(Debug, Clone)] pub enum MaybeManyIter +where U: Iterator { None, One(std::iter::Once), @@ -145,3 +188,19 @@ impl> IntoIterator for MaybeMany } } } + +#[cfg(test)] +mod tests +{ + use super::*; + #[test] + fn into_many() + { + let mut mayb = MaybeMany::one("hello").boxed(); + mayb = mayb.chain(vec!["world", "!"]).boxed(); + + let output: Vec<_> = mayb.into_iter().collect(); + + assert_eq!(&output[..], &["hello", "world", "!"]); + } +}