Clap : Could not downcast to alloc::vec::Vec<(char, num_notation::number::Number)>, need to downcast to (char, num_notation::number::Number)

I am using clap for a custom cli that I am making , in which I use Vec<(char,Number)> , as HashMap<char,Number> gave a list of more errors. So my code compiles , but at runtime it gives me

    Finished dev [unoptimized + debuginfo] target(s) in 1.13s
     Running `C:\Users\Aarav Aditya Shah\Documents\GitHub\project-codebases\rust\arkley\target\debug\arkley_cli.exe evaluate -e "2x +5t" -v x=4`
thread 'main' panicked at 'Mismatch between definition and access of `value`. Could not downcast to alloc::vec::Vec<(char, Number)>, need to downcast to (char, num_notation::number::Number)
', arkley_cli\src\parser.rs:51:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `C:\Users\Aarav Aditya Shah\Documents\GitHub\project-codebases\rust\arkley\target\debug\arkley_cli.exe evaluate -e "2x +5t" -v x=4` (exit code: 101)

Note : (char,Number) is replacable with (char,f64) and error still happens.

Here is the code that i use

#[derive(Subcommand)]
pub(super) enum Arguments {
#[clap(about = "Evaluate a mathematical expression")]
    Evaluate {
        #[arg(
            short = 'e',
            long = "expression",
            required = true,
        )]
        expression_or_equation : String,

        #[arg(
            short,
            long,
            value_parser = parse_key_val,
        )]
        value : Vec<(char,f64)> // Number replaced to f64
    }
}

// [Copyed from here](https://github.com/clap-rs/clap/blob/master/examples/typed-derive.rs#L46) with custom changes
fn parse_key_val(s: &str) -> Result<(char,Number), Box<dyn Error + Send + Sync + 'static>> {
    let pos = s
        .trim() // Added trim here
        .find('=')
        .ok_or_else(|| format!("invalid KEY=value: no `=` found in `{s}`"))?;
    Ok((s[..pos].parse()?, s[pos + 1..].try_into()?))
}

So I copyed the example given so pass key=value input with clap , but this gives me an error.

I thought to use this answer. Given below

use clap::Parser; // 4.2.7

#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
pub struct Cli {
    #[clap(short, long, value_delimiter = ' ', num_args = 1..)]
    pub list: Option<Vec<i32>>,
}

fn main() {
    let cli = Cli::parse();
    print

But that leads to ...

error[E0599]: the method `value_parser` exists for reference `&&&&&&_AutoValueParser<Vec<(char, Number)>>`, but its trait bounds were not satisfied
    --> arkley_cli\src\parser.rs:46:9
     |
46   |         #[clap(short, long, value_delimiter = ' ', num_args = 1..)]
     |         ^ method cannot be called on `&&&&&&_AutoValueParser<Vec<(char, Number)>>` due to unsatisfied trait bounds
     |
    ::: C:\Users\Aarav Aditya Shah\.cargo\registry\src\index.crates.io-6f17d22bba15001f\clap_builder-4.4.7\src\builder\value_parser.rs:2462:1
     |
2462 | pub struct _AutoValueParser<T>(std::marker::PhantomData<T>);
     | ------------------------------ doesn't satisfy `_: _ValueParserViaParse`
     |
    ::: C:\Users\Aarav Aditya Shah\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\alloc\src\vec\mod.rs:396:1
     |
396  | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> {
     | ------------------------------------------------------------------------------------------------
     | |
     | doesn't satisfy `Vec<(char, arkley_algebra::Number)>: From<&'s str>`
     | doesn't satisfy `Vec<(char, arkley_algebra::Number)>: FromStr`
     | doesn't satisfy `Vec<(char, arkley_algebra::Number)>: ValueEnum`
     | doesn't satisfy `_: From<&OsStr>`
     | doesn't satisfy `_: From<OsString>`
     | doesn't satisfy `_: From<String>`
     | doesn't satisfy `_: ValueParserFactory`
     |
     = note: the following trait bounds were not satisfied:
             `Vec<(char, arkley_algebra::Number)>: ValueEnum`
             which is required by `&&&&&_AutoValueParser<Vec<(char, arkley_algebra::Number)>>: clap::builder::via_prelude::_ValueParserViaValueEnum`
             `Vec<(char, arkley_algebra::Number)>: ValueParserFactory`
             which is required by `&&&&&&_AutoValueParser<Vec<(char, arkley_algebra::Number)>>: clap::builder::via_prelude::_ValueParserViaFactory`
             `Vec<(char, arkley_algebra::Number)>: From<OsString>`
             which is required by `&&&&_AutoValueParser<Vec<(char, arkley_algebra::Number)>>: clap::builder::via_prelude::_ValueParserViaFromOsString`
             `Vec<(char, arkley_algebra::Number)>: From<&'s std::ffi::OsStr>`
             which is required by `&&&_AutoValueParser<Vec<(char, arkley_algebra::Number)>>: clap::builder::via_prelude::_ValueParserViaFromOsStr`
             `Vec<(char, arkley_algebra::Number)>: From<std::string::String>`
             which is required by `&&_AutoValueParser<Vec<(char, arkley_algebra::Number)>>: clap::builder::via_prelude::_ValueParserViaFromString`
             `Vec<(char, arkley_algebra::Number)>: From<&'s str>`
             which is required by `&_AutoValueParser<Vec<(char, arkley_algebra::Number)>>: clap::builder::via_prelude::_ValueParserViaFromStr`
             `Vec<(char, arkley_algebra::Number)>: FromStr`
             which is required by `_AutoValueParser<Vec<(char, arkley_algebra::Number)>>: clap::builder::via_prelude::_ValueParserViaParse`
     = note: this error originates in the macro `clap::value_parser` (in Nightly builds, run with -Z macro-backtrace for more info)

So I am not really sure what to do to solve this issue , so if anyone has any ideas plz do tell

I think by using value_parser you're promising to handle all of the parsing, so the "repeated option" support for Vec doesn't work the way it usually would.

I'm wondering if you are facing the same issue described in this topic? I.e. maybe using Box<[(char, Number)]> instead of Vec<(char, Number)> with value_parser would solve your error? (I'm on mobile so I can't really investigate this myself)

In fact , both of the suggestions above solve the issue entirely , the given parser in the question with the fact it 'thinks' the final type is given

@Deaths-Door Can you post the code you wrote which solved the issue? I'm having a similar issue and I don't understand how to create a solution from this information.

@Quaternions , I apologize for the inconvenience, but I cannot find the code I wrote to solve this issue. However, I do remember that the custom parser needs to handle all the parsing so for vec<T> it should return vec<T> . eg

fn parse_key_val(s: &str) -> Result<(char,Number), Box<dyn Error + Send + Sync + 'static>> { /**/ }

Should be

fn parse_key_val(s: &str) -> Result<Vec<(char,Number)>, Box<dyn Error + Send + Sync + 'static>> { /**/ }

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.