Search code examples
rustclap

rust clap parse ipv4Addr


I want to use the clap derive API in order to parse an Ipv4Addr.

#![allow(unused)]
use clap; // 3.1.6
use clap::Parser;
use std::net::Ipv4Addr;

#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
struct Args {
    
    #[clap(short, long, parse(from_str))]
    ip_dst: Ipv4Addr,

}

fn main() {
    let args = Args::parse();
}

My attempt gives the following error even though Ipv4Addr seems to implement FromStr which provides from_str

error[E0277]: the trait bound `Ipv4Addr: From<&str>` is not satisfied
  --> src/main.rs:10:31
   |
10 |     #[clap(short, long, parse(from_str))]
   |                               ^^^^^^^^ the trait `From<&str>` is not implemented for `Ipv4Addr`
   |
   = help: the following implementations were found:
             <Ipv4Addr as From<[u8; 4]>>
             <Ipv4Addr as From<u32>>

For more information about this error, try `rustc --explain E0277`.

My Questions are:

  • Why isn't the method provided by FromStr used?
  • How can I fix the program to do what I want?

Solution

  • What you want is what is used by default (since Ipv4Addr implements FromStr), without specifiying any parse option:

    use clap; // 3.1.6
    use clap::Parser;
    use std::net::Ipv4Addr;
    
    #[derive(Parser, Debug)]
    #[clap(author, version, about, long_about = None)]
    struct Args {
        #[clap(short, long)]
        ip_dst: Ipv4Addr,
    }
    

    Playground

    Otherwise, you need to use try_from_str as per the example:

    #![allow(unused)]
    use clap; // 3.1.6
    use clap::Parser;
    use std::net::Ipv4Addr;
    
    #[derive(Parser, Debug)]
    #[clap(author, version, about, long_about = None)]
    struct Args {
        
        #[clap(short, long, parse(try_from_str))]
        ip_dst: Ipv4Addr,
    
    }
    

    Playground