Repository navigation
feat(cli): default a payment's currency to its wallet's, and units to base units #55
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
base: test/cli-help-dry-runs
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,7 @@ use crate::{ | |
| pick, | ||
| price::{PRICE_URL, PriceService}, | ||
| terminal::Terminal, | ||
| wallet_currency, | ||
| }; | ||
| use serde::Serialize; | ||
| use std::process::ExitCode; | ||
|
|
@@ -86,15 +87,17 @@ fn process_exit(code: i32) -> ExitCode { | |
| } | ||
|
|
||
| async fn execute(invocation: Invocation, submission: &SubmissionState) -> Result<()> { | ||
| let Invocation { global, command } = invocation; | ||
| let Invocation { | ||
| global, | ||
| mut command, | ||
| } = invocation; | ||
| if let Command::Local(LocalCommand::Completions { shell }) = command { | ||
| // The generator panics on a write error, so render to memory and use the normal | ||
| // stdout error policy when writing the completed script. | ||
| let mut script = Vec::new(); | ||
| clap_complete::generate(shell, &mut cli::command(), BINARY_NAME, &mut script); | ||
| return write_stdout(&script); | ||
| } | ||
| let terminal = global.terminal(); | ||
| // `reserve` is false for a description, which goes to stdout and never reserves the file. | ||
| let output = |reserve: bool| { | ||
| Output::new( | ||
|
|
@@ -104,34 +107,15 @@ async fn execute(invocation: Invocation, submission: &SubmissionState) -> Result | |
| ) | ||
| }; | ||
| // Price commands need neither configuration nor credentials. | ||
| if let Command::Local(LocalCommand::Price(_) | LocalCommand::Convert(_)) = &command { | ||
| if let Command::Local(local @ (LocalCommand::Price(_) | LocalCommand::Convert(_))) = command { | ||
| let mut out = output(true)?; | ||
| let service = PriceService::new( | ||
| global.price_url.as_deref().unwrap_or(PRICE_URL), | ||
| global.timeout, | ||
| )?; | ||
| const WAITING: &str = "Waiting for price service..."; | ||
| let envelope = match command { | ||
| Command::Local(LocalCommand::Price(flags)) => Envelope::local( | ||
| terminal | ||
| .during(WAITING, service.report(flags.at.as_deref())) | ||
| .await?, | ||
| )?, | ||
| Command::Local(LocalCommand::Convert(flags)) => Envelope::local( | ||
| terminal | ||
| .during( | ||
| WAITING, | ||
| service.convert(&flags.request(), flags.at.as_deref()), | ||
| ) | ||
| .await?, | ||
| )?, | ||
| _ => unreachable!("matched above"), | ||
| }; | ||
| let envelope = price_command(local, &global).await?; | ||
| return out.write(envelope, &[]); | ||
| } | ||
| let mut settings = Settings::open(config::directory(global.config_dir.clone())?)?; | ||
| let mut scope = settings.scope(global.scope_selection())?; | ||
| pick::fill(&command, &global, &settings, &mut scope, submission).await?; | ||
| wallet_currency::fill(&mut command, &global, &settings, &scope, submission).await?; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line takes The price and convert block above (lines 110-133) is its own command handler, with its own // Price commands need neither configuration nor credentials.
if let Command::Local(local @ (LocalCommand::Price(_) | LocalCommand::Convert(_))) = command {
let mut out = output(true)?;
let envelope = price_command(local, &global).await?;
return out.write(envelope, &[]);
}and add, before /// Read the price service for `price` or `convert`.
async fn price_command(command: LocalCommand, global: &GlobalFlags) -> Result<Envelope> {
let service = PriceService::new(
global.price_url.as_deref().unwrap_or(PRICE_URL),
global.timeout,
)?;
let terminal = global.terminal();
const WAITING: &str = "Waiting for price service...";
match command {
LocalCommand::Price(flags) => Envelope::local(
terminal
.during(WAITING, service.report(flags.at.as_deref()))
.await?,
),
LocalCommand::Convert(flags) => Envelope::local(
terminal
.during(
WAITING,
service.convert(&flags.request(), flags.at.as_deref()),
)
.await?,
),
_ => unreachable!("only price commands are passed"),
}
}That takes |
||
| match command { | ||
| Command::Api(api) => { | ||
| let execution = Execution::resolve(&api, config::execute_variable()?); | ||
|
|
@@ -149,6 +133,32 @@ async fn execute(invocation: Invocation, submission: &SubmissionState) -> Result | |
| } | ||
| } | ||
|
|
||
| /// Read the price service for `price` or `convert`. | ||
| async fn price_command(command: LocalCommand, global: &GlobalFlags) -> Result<Envelope> { | ||
| let service = PriceService::new( | ||
| global.price_url.as_deref().unwrap_or(PRICE_URL), | ||
| global.timeout, | ||
| )?; | ||
| let terminal = global.terminal(); | ||
| const WAITING: &str = "Waiting for price service..."; | ||
| match command { | ||
| LocalCommand::Price(flags) => Envelope::local( | ||
| terminal | ||
| .during(WAITING, service.report(flags.at.as_deref())) | ||
| .await?, | ||
| ), | ||
| LocalCommand::Convert(flags) => Envelope::local( | ||
| terminal | ||
| .during( | ||
| WAITING, | ||
| service.convert(&flags.request(), flags.at.as_deref()), | ||
| ) | ||
| .await?, | ||
| ), | ||
| _ => unreachable!("only price commands are passed"), | ||
| } | ||
| } | ||
|
|
||
| async fn local_command( | ||
| command: LocalCommand, | ||
| global: &GlobalFlags, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DisplayforCurrency, spelled as--currencytakes it. The fullstd::fmtpaths matchimpl std::fmt::Display for Errorinsrc/error.rs.