Guest User

Untitled

a guest
Feb 24th, 2018
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.65 KB | None | 0 0
  1. use std::convert::AsRef;
  2. use std::ffi::OsStr;
  3.  
  4. #[derive(Clone, Debug)]
  5. #[must_use = "join_args is lazy and does nothing unless consumed"]
  6. pub struct JoinArgs<A, B> {
  7. a: A,
  8. b: B,
  9. state: JoinState,
  10. }
  11.  
  12. #[derive(Clone, Debug)]
  13. enum JoinState {
  14. Both,
  15. Front,
  16. Back,
  17. }
  18.  
  19. /// Chains two iterable argument lists.
  20. pub fn join_args<I1, I2>(iter1: I1, iter2: I2) -> JoinArgs<I1::IntoIter, I2::IntoIter>
  21. where
  22. I1: IntoIterator,
  23. I2: IntoIterator,
  24. {
  25. JoinArgs {
  26. a: iter1.into_iter(),
  27. b: iter2.into_iter(),
  28. state: JoinState::Both,
  29. }
  30. }
  31.  
  32. impl<'a, 'b, A, B, S1, S2> Iterator for JoinArgs<A, B>
  33. where
  34. 'b: 'a,
  35. A: Iterator<Item = &'a S1>,
  36. S1: AsRef<OsStr> + 'a,
  37. B: Iterator<Item = &'b S2>,
  38. S2: AsRef<OsStr> + 'b,
  39. {
  40. type Item = &'a OsStr;
  41.  
  42. fn next(&mut self) -> Option<Self::Item> {
  43. match self.state {
  44. JoinState::Both => match self.a.next() {
  45. Some(x) => Some(x.as_ref()),
  46. None => {
  47. self.state = JoinState::Back;
  48. self.b.next().map(AsRef::as_ref)
  49. }
  50. },
  51. JoinState::Front => self.a.next().map(AsRef::as_ref),
  52. JoinState::Back => self.b.next().map(AsRef::as_ref),
  53. }
  54. }
  55. }
  56.  
  57. #[cfg(test)]
  58. mod tests {
  59. use super::*;
  60.  
  61. use std::ffi::OsString;
  62.  
  63. #[test]
  64. fn test_join_args() {
  65. let a = &[OsStr::new("abc"), OsStr::new("def")];
  66. let b = vec![OsString::from("ghi")];
  67. let result: Vec<&OsStr> = join_args(a, &b).collect();
  68. assert_eq!(
  69. result,
  70. [OsStr::new("abc"), OsStr::new("def"), OsStr::new("ghi"),]
  71. );
  72. }
  73. }
Add Comment
Please, Sign In to add comment