Skip to content

Commit

Permalink
Merge pull request #9 from george-cosma/rust_port
Browse files Browse the repository at this point in the history
Some command line argument parsing with clap
  • Loading branch information
alexandruradovici authored Jan 27, 2023
2 parents 74d3758 + 0e504ab commit c3cc608
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 9 deletions.
3 changes: 2 additions & 1 deletion rust/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/target
/target
/Cargo.lock
7 changes: 0 additions & 7 deletions rust/Cargo.lock

This file was deleted.

1 change: 1 addition & 0 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
clap = { version = "4.1.1", features = ["cargo"] }
72 changes: 72 additions & 0 deletions rust/src/cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use clap::{arg, crate_version, Command};

/// Create the [command](clap::Command) object which will handle all of the command line arguments.
pub fn make_cli() -> Command {
Command::new("tockloader")
.about("This is a sample description.")
.version(crate_version!())
.arg_required_else_help(true)
.subcommands(get_subcommands())
.args([
arg!(--debug "Print additional debugging information").action(clap::ArgAction::SetTrue)
])
// Note: arg_require_else_help will trigger the help command if no argument/subcommand is given.
// This means that the --debug flag will not trigger the help menu, even if alone it does nothing.
}

/// Generate all of the [subcommands](clap::Command) used by the program.
fn get_subcommands() -> Vec<Command> {
vec![Command::new("listen")
.about("Open a terminal to receive UART data")
.args(get_app_args())
.args(get_channel_args())
.arg_required_else_help(true)]
}

/// Generate all of the [arguments](clap::Arg) that are required by subcommands which work with apps.
fn get_app_args() -> Vec<clap::Arg> {
vec![
arg!(-a --"app-address" <ADDRESS> "Address where apps are located"),
arg!(--force "Allow apps on boards that are not listed as compatible")
.action(clap::ArgAction::SetTrue),
arg!(--"bundle-apps" "Concatenate apps and flash all together, re-flashing apps as needed")
.action(clap::ArgAction::SetTrue),
]
// Note: the .action(clap::ArgAction::SetTrue) doesn't seem to be necessary, though in clap documentation it is used.
}

/// Generate all of the [arguments](clap::Arg) that are required by subcommands which work
/// with channels and computer-board communication.
fn get_channel_args() -> Vec<clap::Arg> {
vec![
arg!(-p --port "The serial port or device name to use"),
arg!(--serial "Use the serial bootloader to flash")
.action(clap::ArgAction::SetTrue),
arg!(--jlink "Use JLinkExe to flash")
.action(clap::ArgAction::SetTrue),
arg!(--openocd "Use OpenOCD to flash")
.action(clap::ArgAction::SetTrue),
arg!(--"jlink-device" <DEVICE> "The device type to pass to JLinkExe. Useful for initial commissioning.")
.default_value("cortex-m0"),
arg!(--"jlink-cmd" <CMD> "The JLinkExe binary to invoke"),
arg!(--"jlink-speed" <SPEED> "The JLink speed to pass to JLinkExe"),
arg!(--"jlink-if" <INTERFACE> "The interface type to pass to JLinkExe"),
arg!(--"openocd-board" <CFG_FILE> "The cfg file in OpenOCD `board` folder"),
arg!(--"openocd-cmd" <CMD> "The openocd binary to invoke")
.default_value("openocd"),
// These may not work out of the box
arg!(--"openocd-options" <OPTIONS> "Tockloader-specific flags to direct how Tockloader uses OpenOCD"),
arg!(--"openocd-commands" <CMDS> "Directly specify which OpenOCD commands to use for \"program\", \"read\", or \"erase\" actions"),
// -----
arg!(--"flash-file" "Operate on a binary flash file instead of a proper board")
.action(clap::ArgAction::SetTrue),
arg!(--board <BOARD> "Explicitly specify the board that is being targeted"),
arg!(--arch <ARCH> "Explicitly specify the architecture of the board that is being targeted"),
arg!(--"page-size" <SIZE> "Explicitly specify how many bytes in a flash page")
.default_value("0"),
arg!(--"baud-rate" <RATE> "If using serial, set the target baud rate")
.default_value("115200"),
arg!(--"no-bootloader-entry" "Tell Tockloader to assume the bootloader is already active")
.action(clap::ArgAction::SetTrue),
]
}
26 changes: 25 additions & 1 deletion rust/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
mod cli;
use cli::make_cli;

fn main() {
println!("Hello, world!");
let matches = make_cli().get_matches();

if matches.get_flag("debug") {
println!("Debug mode enabled");
}

match matches.subcommand() {
Some(("listen", sub_matches)) => {
println!("Got the listen subcommand");
let default_adr = "NONE".to_string();
let adr = sub_matches
.get_one::<String>("app-address")
.unwrap_or(&default_adr);
println!("{}", format!("With App Address {adr}"));
}
// If only the "--debug" flag is set, then this branch is executed
// Or, more likely at this stage, a subcommand hasn't been implemented yet.
_ => {
println!("Could not run the provided subcommand.");
_ = make_cli().print_help();
}
}
}

0 comments on commit c3cc608

Please sign in to comment.