mirror of
https://github.com/icewind1991/warp-real-ip.git
synced 2026-06-03 18:54:06 +02:00
cleanup CommaSeparatedIterator a bit more
This commit is contained in:
parent
b6db1736eb
commit
4f7758b22e
1 changed files with 44 additions and 49 deletions
95
src/lib.rs
95
src/lib.rs
|
|
@ -76,11 +76,17 @@ pub fn get_forwarded_for() -> impl Filter<Extract = (Vec<IpAddr>,), Error = Infa
|
||||||
.unify()
|
.unify()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
enum CommaSeparatedIteratorState {
|
enum CommaSeparatedIteratorState {
|
||||||
|
/// Start of string or after a ',' (including whitespace)
|
||||||
Default,
|
Default,
|
||||||
|
/// Inside a double quote
|
||||||
Quoted,
|
Quoted,
|
||||||
|
/// After escape character inside quote
|
||||||
QuotedPair,
|
QuotedPair,
|
||||||
|
/// Non quoted part
|
||||||
Token,
|
Token,
|
||||||
|
/// After closing double quote
|
||||||
PostAmbleForQuoted,
|
PostAmbleForQuoted,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,63 +117,52 @@ impl<'a> Iterator for CommaSeparatedIterator<'a> {
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
while let Some((i, c)) = self.char_indices.next() {
|
while let Some((i, c)) = self.char_indices.next() {
|
||||||
let (next, next_state) = match self.state {
|
let (next, next_state) = match (self.state, c) {
|
||||||
CommaSeparatedIteratorState::Default => match c {
|
(CommaSeparatedIteratorState::Default, '"') => {
|
||||||
'"' => {
|
self.s = i;
|
||||||
self.s = i;
|
|
||||||
(None, CommaSeparatedIteratorState::Quoted)
|
|
||||||
}
|
|
||||||
' ' | '\t' => (None, CommaSeparatedIteratorState::Default),
|
|
||||||
',' => (
|
|
||||||
Some(Some(&self.target[i..i])),
|
|
||||||
CommaSeparatedIteratorState::Default,
|
|
||||||
),
|
|
||||||
_ => {
|
|
||||||
self.s = i;
|
|
||||||
(None, CommaSeparatedIteratorState::Token)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
CommaSeparatedIteratorState::Quoted => match c {
|
|
||||||
'"' => (
|
|
||||||
Some(Some(&self.target[self.s..i + 1])),
|
|
||||||
CommaSeparatedIteratorState::PostAmbleForQuoted,
|
|
||||||
),
|
|
||||||
'\\' => (None, CommaSeparatedIteratorState::QuotedPair),
|
|
||||||
_ => (None, CommaSeparatedIteratorState::Quoted),
|
|
||||||
},
|
|
||||||
CommaSeparatedIteratorState::QuotedPair => {
|
|
||||||
(None, CommaSeparatedIteratorState::Quoted)
|
(None, CommaSeparatedIteratorState::Quoted)
|
||||||
}
|
}
|
||||||
CommaSeparatedIteratorState::Token => match c {
|
(CommaSeparatedIteratorState::Default, ' ' | '\t') => {
|
||||||
',' => (
|
(None, CommaSeparatedIteratorState::Default)
|
||||||
Some(Some(&self.target[self.s..i])),
|
}
|
||||||
CommaSeparatedIteratorState::Default,
|
(CommaSeparatedIteratorState::Default, ',') => (
|
||||||
),
|
Some(Some(&self.target[i..i])),
|
||||||
_ => (None, CommaSeparatedIteratorState::Token),
|
CommaSeparatedIteratorState::Default,
|
||||||
},
|
),
|
||||||
CommaSeparatedIteratorState::PostAmbleForQuoted => match c {
|
(CommaSeparatedIteratorState::Default, _) => {
|
||||||
',' => (None, CommaSeparatedIteratorState::Default),
|
self.s = i;
|
||||||
_ => (None, CommaSeparatedIteratorState::PostAmbleForQuoted),
|
(None, CommaSeparatedIteratorState::Token)
|
||||||
},
|
}
|
||||||
|
(CommaSeparatedIteratorState::Quoted, '"') => (
|
||||||
|
Some(Some(&self.target[self.s..i + 1])),
|
||||||
|
CommaSeparatedIteratorState::PostAmbleForQuoted,
|
||||||
|
),
|
||||||
|
(CommaSeparatedIteratorState::Quoted, '\\') => {
|
||||||
|
(None, CommaSeparatedIteratorState::QuotedPair)
|
||||||
|
}
|
||||||
|
(CommaSeparatedIteratorState::QuotedPair, _) => {
|
||||||
|
(None, CommaSeparatedIteratorState::Quoted)
|
||||||
|
}
|
||||||
|
(CommaSeparatedIteratorState::Token, ',') => (
|
||||||
|
Some(Some(&self.target[self.s..i])),
|
||||||
|
CommaSeparatedIteratorState::Default,
|
||||||
|
),
|
||||||
|
(CommaSeparatedIteratorState::PostAmbleForQuoted, ',') => {
|
||||||
|
(None, CommaSeparatedIteratorState::Default)
|
||||||
|
}
|
||||||
|
(current_state, _) => (None, current_state),
|
||||||
};
|
};
|
||||||
match (next, next_state) {
|
self.state = next_state;
|
||||||
(Some(next), next_state) => {
|
if let Some(next) = next {
|
||||||
self.state = next_state;
|
return next;
|
||||||
return next;
|
|
||||||
}
|
|
||||||
(None, next_state) => {
|
|
||||||
self.state = next_state;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match self.state {
|
match self.state {
|
||||||
CommaSeparatedIteratorState::Default
|
CommaSeparatedIteratorState::Default
|
||||||
| CommaSeparatedIteratorState::PostAmbleForQuoted => None,
|
| CommaSeparatedIteratorState::PostAmbleForQuoted => None,
|
||||||
CommaSeparatedIteratorState::Quoted | CommaSeparatedIteratorState::QuotedPair => {
|
CommaSeparatedIteratorState::Quoted
|
||||||
self.state = CommaSeparatedIteratorState::Default;
|
| CommaSeparatedIteratorState::QuotedPair
|
||||||
Some(&self.target[self.s..])
|
| CommaSeparatedIteratorState::Token => {
|
||||||
}
|
|
||||||
CommaSeparatedIteratorState::Token => {
|
|
||||||
self.state = CommaSeparatedIteratorState::Default;
|
self.state = CommaSeparatedIteratorState::Default;
|
||||||
Some(&self.target[self.s..])
|
Some(&self.target[self.s..])
|
||||||
}
|
}
|
||||||
|
|
@ -253,7 +248,7 @@ mod tests {
|
||||||
"\"jkl\"",
|
"\"jkl\"",
|
||||||
"\"mno\"",
|
"\"mno\"",
|
||||||
"pqr",
|
"pqr",
|
||||||
"\"abc, def\""
|
"\"abc, def\"",
|
||||||
],
|
],
|
||||||
CommaSeparatedIterator::new(
|
CommaSeparatedIterator::new(
|
||||||
"abc,\"def\", \"ghi\",\t\"jkl\" , \"mno\",\tpqr, \"abc, def\""
|
"abc,\"def\", \"ghi\",\t\"jkl\" , \"mno\",\tpqr, \"abc, def\""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue