Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Vec<T> Subcommands #4424

Closed
2 tasks done
ewoolsey opened this issue Oct 26, 2022 · 7 comments
Closed
2 tasks done

Support for Vec<T> Subcommands #4424

ewoolsey opened this issue Oct 26, 2022 · 7 comments
Labels
C-enhancement Category: Raise on the bar on expectations

Comments

@ewoolsey
Copy link

ewoolsey commented Oct 26, 2022

Please complete the following tasks

Clap Version

4.0.18

Describe your use case

I would like to parse a vector of subcommands like so:

#[derive(Parser)]
#[clap(rename_all = "snake_case")]
pub enum MyCli {
    GetPrices {
        #[command(subcommand)]
        assets: Vec<AssetInfo>,
    },
}

#[derive(Subcommand)]
#[clap(rename_all = "snake_case")]
pub enum AssetInfo {

    #[command(subcommand)]
    Base(BaseExecuteMsg),

    SetConfig {
        #[command(flatten)]
        set_config_msg: SetConfigMsg,
    },

    AddAsset {
        #[command(flatten)]
        asset_info_type: AddAssetType,
    },

    RemoveAsset {
        #[command(subcommand)]
        asset_info: RemoveAssetType,
    },

    UpdatePrice {
        #[command(subcommand)]
        asset_info: PriceType,
    },

    UpdatePrices {
        #[arg(value_parser=tuple_parser::<PriceType, Decimal256>)]
        assets: Vec<(PriceType, Decimal256)>,
    },
}

Describe the solution you'd like

I'm not sure what the best internal solution is here.

@ewoolsey ewoolsey added the C-enhancement Category: Raise on the bar on expectations label Oct 26, 2022
@epage
Copy link
Member

epage commented Oct 26, 2022

I would like to parse a vector of subcommands like so:

What do you mean by this? Could you provide a complete program (e.g. AssetInfo is missing) and example runs of the program to help clarify the point?

@ewoolsey
Copy link
Author

@epage The above is sort of a toy example as my actual use case has dozens of nested subcommands. I realize the workaround is probably to use a value parser, but that doesn't work for me since 1: its insanely clunky, 2: I'm also parsing and that would break the interactivity. For my specific use case I cannot change the structure of the enum since it is part of an external API.

@epage
Copy link
Member

epage commented Oct 26, 2022

Could you provide example runs of the program to clarify what the semantics of this feature would be?

@ewoolsey
Copy link
Author

ewoolsey commented Oct 26, 2022

Sure, as an example lets create something simpler and complete.

#[derive(Parser)]
#[clap(rename_all = "snake_case")]
pub enum MyCli {
    GetPrices {
        #[command(subcommand)]
        assets: Vec<AssetInfo>,
    },
}

#[derive(Subcommand)]
#[clap(rename_all = "snake_case")]
pub enum AssetInfo {
    Token {
        /// <string>, "atom3h6lk23h6"
        contract_addr: String
    },
    NativeToken {
        /// <string>, "uatom"
        denom: String
    },
}

This is a much simpler case then I have in reality, but useful for examining how this could work. An example run of the program could look like:

my-cli get_prices token atom3h6lk23h6 native_token uatom 

Ideally this should be implemented for any type that is IntoIterator<Item = T>. When these example args are parsed it would result in:

MyCli::GetPrices{
    assets: vec![
        AssetInfo::Token { contract_addr: atom3h6lk23h6 },
        AssetInfo::NativeToken { denom: uatom }
    ]
}

@epage
Copy link
Member

epage commented Oct 26, 2022

Sounds like this is a duplicate of #2222. Do I have that correct?

@ewoolsey
Copy link
Author

Sounds like this is a duplicate of #2222. Do I have that correct?

I think depending on how it is implemented it could possibly be a duplicate. You mention in that thread disabling subcommands though, which would sort of defeat the purpose of what I'm going for no?

@epage
Copy link
Member

epage commented Oct 26, 2022

I'd prefer issues to focus on the requirements and not implementation. As both of these are about command chaining, let's continue the conversation over there. If you need sub-subcommands for your chained commands, I'd recommend posting in there with the reasons why its needed and a proposal for what the semantics would be (e.g. do we stop chaining when entering a sub-sub-command or do we back out to the parent chained command?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-enhancement Category: Raise on the bar on expectations
Projects
None yet
Development

No branches or pull requests

2 participants