[−][src]Crate iter_transpose
This crate provides the IterTranspose
trait that turns an Option<I: IntoIterator>
(or Result<I: IntoIterator, E>
) into an iterator of Option<I::Item>
(or Result<I::Item, E>
):
use iter_transpose::IterTranspose; assert_eq!( Some(vec![1, 2, 3]).transpose_into_iter().collect::<Vec<_>>(), vec![Some(1), Some(2), Some(3)], ); assert_eq!( Result::<Vec<i32>, ()>::Ok(vec![1, 2, 3]) .transpose_into_iter() .collect::<Vec<_>>(), vec![Result::<i32, ()>::Ok(1), Ok(2), Ok(3)] );
Note: if the value is either None
or Err
, the iterator will be infinite.
You can use take_while_some
or take_while_ok
to truncate them.
use iter_transpose::IterTranspose; assert_eq!( Option::<Vec<i32>>::None .transpose_into_iter() .take(5) // We can take as many as we want. .collect::<Vec<_>>(), vec![None, None, None, None, None], ); assert_eq!( Result::<Vec<i32>, ()>::Err(()) .transpose_into_iter() .take(5) // We can take as many as we want. .collect::<Vec<_>>(), vec![Result::<i32, ()>::Err(()), Err(()), Err(()), Err(()), Err(())], );
Note that in case of Result<T, E>
, it must hold that E: Clone + std::fmt::Debug
.
Use Case
The main use case is when there is some optional data loaded separately from the required
data, e.g., from another file or other source, and we want to produce either a value or
None
for each element from the required list, depending on whether the optional data was
loaded or not.
#[derive(Debug, PartialEq, Eq)] struct Item { name: &'static str, description: Option<&'static str>, } fn items(names: Vec<&'static str>, descriptions: Option<Vec<&'static str>>) -> Vec<Item> { names .into_iter() .zip(descriptions.transpose_into_iter()) .map(|(name, description)| Item { name, description }) .collect() } assert_eq!( items(vec!["Alice", "Bob", "Charlie"], None), vec![ Item { name: "Alice", description: None, }, Item { name: "Bob", description: None, }, Item { name: "Charlie", description: None, }, ] ); assert_eq!( items( vec!["Alice", "Bob", "Charlie"], Some(vec!["in Wonderland", "the builder", "likes chocolate"]) ), vec![ Item { name: "Alice", description: Some("in Wonderland"), }, Item { name: "Bob", description: Some("the builder"), }, Item { name: "Charlie", description: Some("likes chocolate"), }, ] );
Other Examples
You can also use this function to iterate over all existing elements.
Handy functions are unwrap_while_some
for Option
and unwrap_while_ok
for Result
:
assert_eq!( Some((0..5)) .transpose_into_iter() .unwrap_while_some() .collect::<Vec<_>>(), Some((0..5)) .into_iter() .flatten() .collect::<Vec<_>>(), );
Structs
OptionTransposedIter | Result of calling |
ResultTransposedIter | Result of calling |
Traits
IterTranspose | Provides |