Skip to content

Commit

Permalink
port adstool to clap 3.0 (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
birkenfeld authored Aug 9, 2024
1 parent cd737c8 commit e7f0f6b
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 43 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ once_cell = "1.19.0"
parse_int = "0.6.0"
quick-xml = "0.36.1"
regex = "<1.10.0"
structopt = "0.3.26"
clap = { version = "3.2.25", features = ["derive"] }
strum = { version = "0.26.3", features = ["derive"] }
time = { version = "<0.3.18", features = ["formatting"] }
88 changes: 46 additions & 42 deletions examples/adstool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,21 @@ use std::str::FromStr;
use byteorder::{ByteOrder, BE, LE, WriteBytesExt};
use itertools::Itertools;
use parse_int::parse;
use structopt::{clap::AppSettings, clap::ArgGroup, StructOpt};
use clap::{Parser, Subcommand, ArgGroup, AppSettings};
use strum::EnumString;
use quick_xml::{events::Event, name::QName};
use time::OffsetDateTime;

#[derive(StructOpt, Debug)]
#[structopt(global_setting = AppSettings::UnifiedHelpMessage)]
#[structopt(global_setting = AppSettings::DisableHelpSubcommand)]
#[structopt(global_setting = AppSettings::DeriveDisplayOrder)]
#[derive(Parser, Debug)]
#[clap(disable_help_subcommand = true)]
#[clap(global_setting = AppSettings::DeriveDisplayOrder)]
/// A utility for managing ADS servers.
struct Args {
#[structopt(subcommand)]
#[clap(subcommand)]
cmd: Cmd,
/// If true, automatically try to set a route with the default password
/// before connecting.
#[structopt(short, long)]
#[clap(short, long)]
autoroute: bool,
/// Target for the command.
///
Expand All @@ -44,22 +43,27 @@ struct Args {
target: Target,
}

#[derive(StructOpt, Debug)]
#[derive(Subcommand, Debug)]
enum Cmd {
/// Query basic information about the system over UDP.
Info,
/// Query extended information about the system over ADS.
TargetDesc,
#[clap(subcommand)]
Route(RouteAction),
#[clap(subcommand)]
File(FileAction),
#[clap(subcommand)]
License(LicenseAction),
State(StateArgs),
#[clap(subcommand)]
Raw(RawAction),
#[clap(subcommand)]
Var(VarAction),
Exec(ExecArgs),
}

#[derive(StructOpt, Debug)]
#[derive(Subcommand, Debug)]
/// Manipulate ADS routes.
enum RouteAction {
/// Add an ADS route to the remote TwinCAT system.
Expand All @@ -68,7 +72,7 @@ enum RouteAction {
List,
}

#[derive(StructOpt, Debug)]
#[derive(Parser, Debug)]
struct AddRouteArgs {
/// hostname or IP address of the route's destionation
addr: String,
Expand All @@ -77,23 +81,23 @@ struct AddRouteArgs {
netid: ads::AmsNetId,

/// name of the new route (defaults to `addr`)
#[structopt(long)]
#[clap(long)]
routename: Option<String>,

/// password for logging into the system (defaults to `1`)
#[structopt(long, default_value = "1")]
#[clap(long, default_value = "1")]
password: String,

/// username for logging into the system (defaults to `Administrator`)
#[structopt(long, default_value = "Administrator")]
#[clap(long, default_value = "Administrator")]
username: String,

/// mark route as temporary?
#[structopt(long)]
#[clap(long)]
temporary: bool,
}

#[derive(StructOpt, Debug)]
#[derive(Subcommand, Debug)]
/// Execute operations on files on the TwinCAT system.
enum FileAction {
/// List remote files in the given directory.
Expand All @@ -111,7 +115,7 @@ enum FileAction {
/// the file path
path: String,
/// whether to append to the file when writing
#[structopt(long)]
#[clap(long)]
append: bool,
},
/// Delete a remote file.
Expand All @@ -121,7 +125,7 @@ enum FileAction {
},
}

#[derive(StructOpt, Debug)]
#[derive(Subcommand, Debug)]
/// Query different license ids.
enum LicenseAction {
/// Get the platform ID
Expand All @@ -134,7 +138,7 @@ enum LicenseAction {
Modules,
}

#[derive(StructOpt, Debug)]
#[derive(Parser, Debug)]
/// Read or write the ADS state of the device.
struct StateArgs {
/// if given, the target state
Expand All @@ -145,60 +149,60 @@ struct StateArgs {
target_state: Option<ads::AdsState>,
}

#[derive(StructOpt, Debug)]
#[derive(Subcommand, Debug)]
/// Raw read or write access for an indexgroup.
enum RawAction {
/// Read some data from an index. Specify either --length (to print raw
/// bytes) or --type (to convert to a data type and print that).
#[structopt(group = ArgGroup::with_name("spec").required(true))]
#[clap(group = ArgGroup::with_name("spec").required(true))]
Read {
/// the index group, can be 0xABCD
#[structopt(parse(try_from_str = parse))]
#[clap(parse(try_from_str = parse))]
index_group: u32,
/// the index offset, can be 0xABCD
#[structopt(parse(try_from_str = parse))]
#[clap(parse(try_from_str = parse))]
index_offset: u32,
/// the length, can be 0xABCD
#[structopt(long, parse(try_from_str = parse), group = "spec")]
#[clap(long, parse(try_from_str = parse), group = "spec")]
length: Option<usize>,
/// the data type
#[structopt(long, group = "spec")]
#[clap(long, group = "spec")]
r#type: Option<VarType>,
/// whether to print integers as hex, or raw data as hexdump
#[structopt(long)]
#[clap(long)]
hex: bool,
},
/// Write some data to an index. Data is read from stdin.
Write {
/// the index group, can be 0xABCD
#[structopt(parse(try_from_str = parse))]
#[clap(parse(try_from_str = parse))]
index_group: u32,
/// the index offset, can be 0xABCD
#[structopt(parse(try_from_str = parse))]
#[clap(parse(try_from_str = parse))]
index_offset: u32,
},
/// Write some data (read from stdin), then read data from an index.
#[structopt(group = ArgGroup::with_name("spec").required(true))]
#[clap(group = ArgGroup::with_name("spec").required(true))]
WriteRead {
/// the index group, can be 0xABCD
#[structopt(parse(try_from_str = parse))]
#[clap(parse(try_from_str = parse))]
index_group: u32,
/// the index offset, can be 0xABCD
#[structopt(parse(try_from_str = parse))]
#[clap(parse(try_from_str = parse))]
index_offset: u32,
/// the length to read, can be 0xABCD
#[structopt(long, parse(try_from_str = parse), group = "spec")]
#[clap(long, parse(try_from_str = parse), group = "spec")]
length: Option<usize>,
/// the data type to interpret the read data as
#[structopt(long, group = "spec")]
#[clap(long, group = "spec")]
r#type: Option<VarType>,
/// whether to print integers as hex, or raw data as hexdump
#[structopt(long)]
#[clap(long)]
hex: bool,
},
}

#[derive(StructOpt, Debug)]
#[derive(Subcommand, Debug)]
/// Variable read or write access.
enum VarAction {
/// List variables together with their types, sizes and offsets.
Expand All @@ -212,18 +216,18 @@ enum VarAction {
filter: Option<String>,
},
/// Read a variable by name.
#[structopt(group = ArgGroup::with_name("spec"))]
#[clap(group = ArgGroup::with_name("spec"))]
Read {
/// the variable name
name: String,
/// the variable type
#[structopt(long, group = "spec")]
#[clap(long, group = "spec")]
r#type: Option<VarType>,
/// the length to read, can be 0xABCD
#[structopt(long, parse(try_from_str = parse), group = "spec")]
#[clap(long, parse(try_from_str = parse), group = "spec")]
length: Option<usize>,
/// whether to print integers as hex
#[structopt(long)]
#[clap(long)]
hex: bool,
},
/// Write a variable by name. If --type is given, the new value
Expand All @@ -233,21 +237,21 @@ enum VarAction {
/// the variable name
name: String,
/// the new value, if given, to write
#[structopt(requires = "type")]
#[clap(requires = "type")]
value: Option<String>,
/// the variable type
#[structopt(long)]
#[clap(long)]
r#type: Option<VarType>,
}
}

#[derive(StructOpt, Debug)]
#[derive(Parser, Debug)]
/// Execute a system command on the target.
struct ExecArgs {
/// the executable with path
program: String,
/// the working directory (defaults to the executable's)
#[structopt(long)]
#[clap(long)]
workingdir: Option<String>,
/// arguments for the executable
args: Vec<String>,
Expand Down

0 comments on commit e7f0f6b

Please sign in to comment.