parse_arguments: work with utf8 bytes and reduce indentation

We are only caring about '=' and '-' which are single-byte
codepoints, so there's no reason not to work on a byte
slice.

Also, some indentation reduction:

Transform
    if (a) {
        ...
        return A;
    }
    return B;
into
    if (!a)
        return B;
    return A;

and
    if (a)
        if (b)
            foo()
into
    if (a && b)
        return;

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2018-12-28 13:14:13 +01:00
parent 248c17af39
commit ad8a98f7e4
1 changed files with 30 additions and 21 deletions

View File

@ -12,35 +12,44 @@ enum RawArgument {
} }
fn parse_argument(arg: &str) -> RawArgument { fn parse_argument(arg: &str) -> RawArgument {
let bytes = arg.as_bytes();
let chars: Vec<char> = arg.chars().collect(); let length = bytes.len();
let length = chars.len(); if length < 2 || bytes[0] != b'-' {
return RawArgument::Argument {
value: arg.to_string(),
};
}
if length >= 2 { let mut first = 1;
if chars[0] == '-' { if bytes[1] == b'-' {
let mut first = 1; if length == 2 {
return RawArgument::Separator;
}
first = 2;
}
if chars[1] == '-' { for start in first..length {
if length == 2 { return RawArgument::Separator; } if bytes[start] == b'=' {
first = 2; // Since we take a &str, we know the contents of it are valid utf8.
} // Since bytes[start] == b'=', we know the byte beginning at start is a single-byte
// code pointer. We also know that 'first' points exactly after a single-byte code
for start in first..length { // point as it points to the first byte after a hyphen.
if chars[start] == '=' { // Therefore we know arg[first..start] is valid utf-8, therefore it is safe to use
let name: String = chars[first..start].iter().collect(); // get_unchecked() to speed things up.
let value: String = chars[start+1..length].iter().collect(); return RawArgument::Option {
return RawArgument::Option { name, value: Some(value) } name: unsafe { arg.get_unchecked(first..start).to_string() },
} value: Some(unsafe { arg.get_unchecked((start + 1)..).to_string() }),
} };
let name: String = chars[first..].iter().collect();
return RawArgument::Option { name: name, value: None }
} }
} }
RawArgument::Argument { value: arg.to_string() } return RawArgument::Option {
name: unsafe { arg.get_unchecked(first..).to_string() },
value: None,
};
} }
pub fn parse_arguments( pub fn parse_arguments(