0

I have a string parsing function using regex: fn parse(s: &str) -> Option<MyObj>. It works when testing with parse("test string"). But failed when using Args. The failure is that the regex could not matching anything from s.

The way I used Args is: args().map(|arg| parse(&arg)).collect(). I could not see type error here. And println in parse shows s is the same string as "test string".


Updated my description. I am not sure if my problem is related with how String and str are different. Because I was using str and it still failed.

extern crate regex;

use regex::Regex;
use std::env::args;

struct IPRange {
    start: u32,
    mask: u8,
}

fn parse_iprange(ipr: &str) -> Option<IPRange> {
    let parser = Regex::new(
        r"^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/(\d+|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$",
    )
    .unwrap();
    let caps = parser.captures(ipr).unwrap();
    return Some(IPRange { start: 0, mask: 0 });
}

fn main() {
    let v: Vec<_> = args().map(|arg| parse_iprange(&arg)).collect();
}
$ RUST_BACKTRACE=1 cargo run 192.168.3.1/24
    Finished dev [unoptimized + debuginfo] target(s) in 0.04s
     Running `target/debug/ip_helper 192.168.3.1/24`
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/libcore/option.rs:345:21
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:39
   1: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:70
   2: std::panicking::default_hook::{{closure}}
             at src/libstd/sys_common/backtrace.rs:58
             at src/libstd/panicking.rs:200
   3: std::panicking::default_hook
             at src/libstd/panicking.rs:215
   4: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:478
   5: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:385
   6: rust_begin_unwind
             at src/libstd/panicking.rs:312
   7: core::panicking::panic_fmt
             at src/libcore/panicking.rs:85
   8: core::panicking::panic
             at src/libcore/panicking.rs:49
   9: <core::option::Option<T>>::unwrap
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858/src/libcore/macros.rs:10
  10: ip_helper::parse_iprange
             at src/main.rs:18
1
  • @Stargateur Updated. Thanks. If I replace the only line in main with parse_iprange("192.168.3.1/24"), it works. Commented Apr 3, 2019 at 7:13

1 Answer 1

2

The first item of args() is implementation behavior:

The first element is traditionally the path of the executable, but it can be set to arbitrary text, and may not even exist. This means this property should not be relied upon for security purposes.

So, you should skip it in your case:

let v: Vec<_> = args().skip(1).map(|arg| parse_iprange(&arg)).collect();
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.