I know this is not a support site or programming course but I can't figure this thing out. If you do know #rust perhaps you can give me a helping hand. I am trying to contribute to an app.

I'd like to parse ipv4 addresses given as command line argument values.
I have got two arguments accepting ipv4 address.
If I specify single such option all is fine.
If I specify both, I 'm getting error like this:

thread 'main' (624061) panicked at /home/peto/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/clap-3.2.25/src/parser/matches/arg_matches.rs:1879:13:
Must use `Arg::allow_invalid_utf8` with `_os` lookups at `[hash: A8F400C40154F09]`

This is simplified version of my code showcasing the issue:
```
use std::net::{IpAddr, Ipv4Addr};
use clap::{App, AppSettings, Arg, value_parser};

#[tokio::main]
async fn main() -> Result<(), Error> {
let mut app = App::new("Server APP")
.about("My super cool app")
.setting(AppSettings::DeriveDisplayOrder)
.setting(AppSettings::SubcommandsNegateReqs)
.arg(
Arg::with_name("socket")
.required(true)
.takes_value(true)
.long("socket")
.help("Unix socket path"),
)
.arg(
Arg::with_name("relayaddress")
.required(false)
.takes_value(true)
.long("relay-address")
.value_parser(value_parser!(Ipv4Addr))
.help("External relay ipv4 address used together with --listen-address to run behind a nat"),
)
.arg(
Arg::with_name("listenaddress")
.required(false)
.takes_value(true)
.long("listen-address")
.value_parser(value_parser!(Ipv4Addr))
.help("Local listen ipv4 address used together with --relay-address to run behind a nat"),
);
let matches = app.clone().get_matches();
if matches.is_present("relayaddress") & matches.is_present("listenaddress") {
let external_ip = IpAddr::V4(matches.get_one::<Ipv4Addr>("relayaddress").expect("Invalid address"));
let local_ip = IpAddr::V4(
matches.get_one::<Ipv4Addr>("listenaddress").expect("Invalid address"));
println!("Listening on local IP: {local_ip}");
println!("Relaying through external IP: {external_ip}");
}}
```

#rust #rustlang #programming #fedihelp

reshared this

in reply to Peter Vágner

I know this is not a support site or programming course but I can't figure this thing out. If you do know #rust perhaps you can give me a helping hand. I am trying to contribute to an app.

Sensitive content

in reply to Federico Mena Quintero

I know this is not a support site or programming course but I can't figure this thing out. If you do know #rust perhaps you can give me a helping hand. I am trying to contribute to an app.
@Federico Mena Quintero Oh, huge thanks for taking a look. Yes it's clap 3. It's not my decision, I'm attempting to contribute to an existing project so if I can make it work without major changes that might be helpfull. As I don't feel qualified for making decisions when it comes to this. I'm novice when it comes to #rust.
--socket argument is required, other two arguments are supposed to be used together and this condition is tested at runtime.
So if I specify all three command line arguments, I am always getting that error.
I have attempted using os::str and casting but the issue remains. I am simply compiling the app with cargo build --release.
Have you been just adding stuff I may have overlooked when trying to simplify for posting or did you actually changed something please?
in reply to Federico Mena Quintero

I know this is not a support site or programming course but I can't figure this thing out. If you do know #rust perhaps you can give me a helping hand. I am trying to contribute to an app.
@Federico Mena Quintero I've figured it out finally. The issue was not parsing ipv4 addresses but using matches.from_os() on the socket argument.
I have changed it to use std::path::PathBuf and it's working fine for me now.
Huge thanks for friendly hint and looking at my code.