Skip to content

Commit 3acbfb6

Browse files
committed
into_inner function, minor changes to trait bounds
1 parent 5dec134 commit 3acbfb6

File tree

1 file changed

+29
-12
lines changed

1 file changed

+29
-12
lines changed

src/lib.rs

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ enum State {
8282
}
8383

8484
/// Parser for command-line arguments
85-
pub struct Parser<I> {
85+
pub struct Parser<I: Iterator> {
8686
iter: I,
8787
state: State,
8888

@@ -105,16 +105,19 @@ impl Parser<env::ArgsOs> {
105105
}
106106
}
107107

108-
impl<I> Parser<I> {
108+
impl<I> Parser<I>
109+
where
110+
I: Iterator<Item = OsString>,
111+
{
109112
/// Creates a `Parser` from any iterator that yields `OsString` items.
110113
///
111114
/// # Errors
112115
///
113116
/// Returns an error if the iterator is empty or the first item (program name)
114117
/// can't be converted to a valid UTF-8 string.
115-
pub fn from_arbitrary(iter: I) -> Result<Parser<<I as IntoIterator>::IntoIter>>
118+
pub fn from_arbitrary<A>(iter: A) -> Result<Parser<I>>
116119
where
117-
I: IntoIterator<Item = OsString>,
120+
A: IntoIterator<IntoIter = I>,
118121
{
119122
let mut iter = iter.into_iter();
120123
let name = match iter.next() {
@@ -124,7 +127,7 @@ impl<I> Parser<I> {
124127
}
125128
Some(val) => match val.into_string() {
126129
Ok(str) => str,
127-
Err(_e) => return Err(ParsingError::InvalidString),
130+
Err(_) => return Err(ParsingError::InvalidString),
128131
},
129132
};
130133

@@ -137,12 +140,7 @@ impl<I> Parser<I> {
137140
name,
138141
})
139142
}
140-
}
141143

142-
impl<I> Parser<I>
143-
where
144-
I: Iterator<Item = OsString>,
145-
{
146144
/// Moves to the next argument, parsing it into an `Argument` enum.
147145
///
148146
/// # Returns
@@ -158,7 +156,10 @@ where
158156
/// (malformed UTF-8 for example) or when it was in an
159157
/// invalid state, such as `-abc=value`
160158
/// (here it's invalid for multiple short options to take in a value)
161-
pub fn forward(&mut self) -> Result<Option<Argument<'_>>> {
159+
pub fn forward<'a, 'b>(&'a mut self) -> Result<Option<Argument<'b>>>
160+
where
161+
'a: 'b,
162+
{
162163
if matches!(self.state, State::End) {
163164
return Ok(None);
164165
}
@@ -312,6 +313,11 @@ where
312313
pub fn name(&self) -> &str {
313314
&self.name
314315
}
316+
317+
/// Returns the inner iterator.
318+
pub fn into_inner(self) -> I {
319+
self.iter
320+
}
315321
}
316322

317323
/// Parsing error types with descriptive messages
@@ -450,7 +456,18 @@ mod tests {
450456

451457
assert_eq!(
452458
arg.into_error("examplevalue").to_string(),
453-
"unexpected argument: --example=examplevalue\n"
459+
"unexpected argument: --example=examplevalue"
454460
);
455461
}
462+
463+
#[test]
464+
fn trailing_values() {
465+
let content = test_cmdline!(["testbin", "-meow", "--awrff=puppy", "--", "meow"]);
466+
467+
let mut parser = Parser::from_arbitrary(content).unwrap();
468+
469+
while let Some(p) = parser.forward().unwrap() {
470+
dbg!(p);
471+
}
472+
}
456473
}

0 commit comments

Comments
 (0)