Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::convert::AsRef;
- use std::ffi::OsStr;
- #[derive(Clone, Debug)]
- #[must_use = "join_args is lazy and does nothing unless consumed"]
- pub struct JoinArgs<A, B> {
- a: A,
- b: B,
- state: JoinState,
- }
- #[derive(Clone, Debug)]
- enum JoinState {
- Both,
- Front,
- Back,
- }
- /// Chains two iterable argument lists.
- pub fn join_args<I1, I2>(iter1: I1, iter2: I2) -> JoinArgs<I1::IntoIter, I2::IntoIter>
- where
- I1: IntoIterator,
- I2: IntoIterator,
- {
- JoinArgs {
- a: iter1.into_iter(),
- b: iter2.into_iter(),
- state: JoinState::Both,
- }
- }
- impl<'a, 'b, A, B, S1, S2> Iterator for JoinArgs<A, B>
- where
- 'b: 'a,
- A: Iterator<Item = &'a S1>,
- S1: AsRef<OsStr> + 'a,
- B: Iterator<Item = &'b S2>,
- S2: AsRef<OsStr> + 'b,
- {
- type Item = &'a OsStr;
- fn next(&mut self) -> Option<Self::Item> {
- match self.state {
- JoinState::Both => match self.a.next() {
- Some(x) => Some(x.as_ref()),
- None => {
- self.state = JoinState::Back;
- self.b.next().map(AsRef::as_ref)
- }
- },
- JoinState::Front => self.a.next().map(AsRef::as_ref),
- JoinState::Back => self.b.next().map(AsRef::as_ref),
- }
- }
- }
- #[cfg(test)]
- mod tests {
- use super::*;
- use std::ffi::OsString;
- #[test]
- fn test_join_args() {
- let a = &[OsStr::new("abc"), OsStr::new("def")];
- let b = vec![OsString::from("ghi")];
- let result: Vec<&OsStr> = join_args(a, &b).collect();
- assert_eq!(
- result,
- [OsStr::new("abc"), OsStr::new("def"), OsStr::new("ghi"),]
- );
- }
- }
Add Comment
Please, Sign In to add comment