forked from rust-lang/rustup
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathargsource.rs
More file actions
66 lines (59 loc) · 1.69 KB
/
argsource.rs
File metadata and controls
66 lines (59 loc) · 1.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/// Abstracts over reading the current process environment variables as a
/// zero-cost abstraction to support threaded in-process testing.
use std::env;
use std::ffi::OsString;
use std::marker::PhantomData;
use enum_dispatch::enum_dispatch;
#[enum_dispatch]
pub trait ArgSource {
fn args(&self) -> Box<dyn Iterator<Item = String>>;
fn args_os(&self) -> Box<dyn Iterator<Item = OsString>>;
}
/// Implements ArgSource with `std::env::args`
impl ArgSource for super::OSProcess {
fn args(&self) -> Box<dyn Iterator<Item = String>> {
Box::new(env::args())
}
fn args_os(&self) -> Box<dyn Iterator<Item = OsString>> {
Box::new(env::args_os())
}
}
/// Helper for ArgSource over `Vec<String>`
pub(crate) struct VecArgs<T> {
v: Vec<String>,
i: usize,
_marker: PhantomData<T>,
}
impl<T> From<&Vec<String>> for VecArgs<T> {
fn from(source: &Vec<String>) -> Self {
let v = source.clone();
VecArgs {
v,
i: 0,
_marker: PhantomData,
}
}
}
impl<T: From<String>> Iterator for VecArgs<T> {
type Item = T;
fn next(&mut self) -> Option<T> {
if self.i == self.v.len() {
return None;
}
let i = self.i;
self.i += 1;
Some(T::from(self.v[i].clone()))
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.v.len(), Some(self.v.len()))
}
}
#[cfg(feature = "test")]
impl ArgSource for super::TestProcess {
fn args(&self) -> Box<dyn Iterator<Item = String>> {
Box::new(VecArgs::<String>::from(&self.args))
}
fn args_os(&self) -> Box<dyn Iterator<Item = OsString>> {
Box::new(VecArgs::<OsString>::from(&self.args))
}
}