Skip to content

sketch an alternative structure using Clap beta#5

Draft
danieleades wants to merge 2 commits intoOverkillGuy:masterfrom
danieleades:clap-beta
Draft

sketch an alternative structure using Clap beta#5
danieleades wants to merge 2 commits intoOverkillGuy:masterfrom
danieleades:clap-beta

Conversation

@danieleades
Copy link
Contributor

here's a sketch of an alternative formulation of a way to structure a CLI app using the clap 3.0 beta (itself a port of structopt back in to the clap codebase)

I've not actually seen this pattern documented before, but I doubt I've invented it.

  • subcommands are separate structs, and the parent command is an enum
  • 'run' methods are implemented directly on the argument structs

it gives you nice encapsulation, since by definition all of the required inputs are fields of the struct itself.

All of the extra stuff, like setting the binary name, the project version, the author, etc. are all done automatically by the derive macro based on the contents of Cargo.toml (but can be overridden if you wish!) The implementation i've added here is completely equivalent to the original argument parsing logic.

note I've used io::Result<()> but that's probably not ideal if you're wanting something a little more human-readable. I recommend taking a look at these two crates-

  • anyhow - flexible error handling for when something goes a bit wrong
  • human_panic - human-readable panic! messages for when things go very wrong

@danieleades
Copy link
Contributor Author

i'm updated this pull request to show how you can break this down into separate modules. Again, just a sketch. Take what's useful and ignore the rest!

@OverkillGuy
Copy link
Owner

Ooh, good shout on the module-making, I tried my hand in the ongoing decode branch (see 1debdd1, separated because it fails tests right now, intentionally, what with the unimplemented feature). All I understood regarding local imports so far is that:

  • in binary-mode (not lib.rs), separate file needs to be included in main somehow for cargo test to pick it up
  • including a local file is done via mod xyz; with xyz.rs the other file

@danieleades
Copy link
Contributor Author

danieleades commented Mar 4, 2021

Ooh, good shout on the module-making, I tried my hand in the ongoing decode branch (see 1debdd1, separated because it fails tests right now, intentionally, what with the unimplemented feature). All I understood regarding local imports so far is that:

  • in binary-mode (not lib.rs), separate file needs to be included in main somehow for cargo test to pick it up

there's no difference between the module structure for binary or library

  • including a local file is done via mod xyz; with xyz.rs the other file

yep! actually the module system is quite similar to python, except

  • modules are not implicit, they always have to be declared
  • modules don't have to be in separate files, you can have a module block inside another file
  • module members are private by default. you have to explicitly export them to the enclosing module using pub

@OverkillGuy
Copy link
Owner

This does look nice, but I'll likely adopt it once I've gone around the codebase a bunch on basic features, and find the basic clap features limiting/overly verbose.
The use of beta lib is also a mild concern, so giving this PR time to cool down will help stabilize the package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants