Fix use of --output when importing to cert-store is the default

- As clap can not use `Default` as advertised for certain types [1], use
  `Option<FileOrStdout>` instead in cases where the default is to import
  to cert-store. Semantically, this works as before: By default import
  to cert-store, when providing "-" output to stdout and when providing
  a file name output to the file.
- Since `FileOrCertStore` can not wrap any other type under the given
  circumstances, turn it into an empty struct that only implements
  `ClapData` to provide static strings for the clap setup.
- Adapt the help message for `FileOrCertStore` to mention, that
  providing "-" leads to output on stdout.

Fixes #133

[1] https://github.com/clap-rs/clap/issues/4558
This commit is contained in:
David Runge 2023-06-19 11:06:47 +02:00
parent e8b31100cb
commit 6ac9c2761a
No known key found for this signature in database
GPG Key ID: BB992F9864FAD168
5 changed files with 22 additions and 66 deletions

View File

@ -48,7 +48,6 @@ use crate::{
};
use crate::sq_cli;
use crate::sq_cli::types::FileOrStdout;
const NP: NullPolicy = NullPolicy::new();
@ -409,9 +408,8 @@ pub fn dispatch_keyserver(mut config: Config, c: sq_cli::keyserver::Command)
let cert = rt.block_on(ks.get(handle))
.context("Failed to retrieve cert")?;
if c.output.path().is_some() {
let mut output = FileOrStdout::from(c.output)
.create_safe(config.force)?;
if let Some(file) = c.output {
let mut output = file.create_safe(config.force)?;
if !c.binary {
cert.armored().serialize(&mut output)
} else {
@ -432,9 +430,8 @@ pub fn dispatch_keyserver(mut config: Config, c: sq_cli::keyserver::Command)
let certs = rt.block_on(ks.search(addr))
.context("Failed to retrieve certs")?;
if c.output.path().is_some() {
let mut output = FileOrStdout::from(c.output)
.create_safe(config.force)?;
if let Some(file) = c.output {
let mut output = file.create_safe(config.force)?;
serialize_keyring(&mut output, &certs, c.binary)?;
} else {
let certs = if let Some((ca_filename, ca_userid)) = ca() {
@ -514,9 +511,8 @@ pub fn dispatch_wkd(mut config: Config, c: sq_cli::wkd::Command) -> Result<()> {
// ```
// But to keep the parallelism with `store export` and `keyserver get`,
// The output is armored if not `--binary` option is given.
if c.output.path().is_some() {
let mut output = FileOrStdout::from(c.output)
.create_safe(config.force)?;
if let Some(file) = c.output {
let mut output = file.create_safe(config.force)?;
serialize_keyring(&mut output, &certs, c.binary)?;
} else {
let certs = certify_downloads(
@ -587,9 +583,8 @@ pub fn dispatch_dane(mut config: Config, c: sq_cli::dane::Command) -> Result<()>
// Because it might be created a WkdServer struct, not
// doing it for now.
let certs = rt.block_on(dane::get(&email_address))?;
if c.output.path().is_some() {
let mut output = FileOrStdout::from(c.output)
.create_safe(config.force)?;
if let Some(file) = c.output {
let mut output = file.create_safe(config.force)?;
serialize_keyring(&mut output, &certs, c.binary)?;
} else {
let certs = certify_downloads(

View File

@ -4,6 +4,7 @@ use crate::sq_cli::types::NetworkPolicy;
use super::types::ClapData;
use super::types::FileOrCertStore;
use super::types::FileOrStdout;
#[derive(Parser, Debug)]
#[clap(
@ -64,11 +65,10 @@ pub struct GetCommand {
)]
pub binary: bool,
#[clap(
default_value_t = FileOrCertStore::default(),
help = FileOrCertStore::HELP,
long,
short,
value_name = FileOrCertStore::VALUE_NAME,
)]
pub output: FileOrCertStore,
pub output: Option<FileOrStdout>,
}

View File

@ -5,6 +5,7 @@ use crate::sq_cli::types::NetworkPolicy;
use super::types::ClapData;
use super::types::FileOrCertStore;
use super::types::FileOrStdin;
use super::types::FileOrStdout;
#[derive(Parser, Debug)]
#[clap(
@ -64,13 +65,12 @@ the usual way.
)]
pub struct GetCommand {
#[clap(
default_value_t = FileOrCertStore::default(),
help = FileOrCertStore::HELP,
long,
short,
value_name = FileOrCertStore::VALUE_NAME,
)]
pub output: FileOrCertStore,
pub output: Option<FileOrStdout>,
#[clap(
short = 'B',
long,

View File

@ -198,10 +198,11 @@ impl Display for FileOrStdin {
}
}
/// A type wrapping an optional PathBuf to use as stdout or file output
/// A type providing const strings for output to certstore by default
///
/// Use this if a CLI should allow output to a file and if unset output to
/// a cert store.
/// This struct is empty and solely used to provide strings to clap.
/// Use this in combination with a [`FileOrStdout`] if a CLI should allow output
/// to a file and if unset output to a cert store.
///
/// ## Examples
/// ```
@ -216,51 +217,17 @@ impl Display for FileOrStdin {
/// short,
/// value_name = FileOrCertStore::VALUE_NAME,
/// )]
/// pub output: Option<FileOrCertStore>,
/// pub output: Option<FileOrStdout>,
/// }
/// ```
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct FileOrCertStore(Option<PathBuf>);
pub struct FileOrCertStore{}
impl ClapData for FileOrCertStore {
const VALUE_NAME: &'static str = "FILE";
const HELP: &'static str
= "Writes to FILE instead of importing into the certificate store";
}
impl FileOrCertStore {
/// Consume self and return the inner PathBuf
pub fn into_inner(self) -> Option<PathBuf> {
self.0
}
/// Return a reference to the inner type
pub fn path(&self) -> Option<&PathBuf> {
self.0.as_ref()
}
}
impl Default for FileOrCertStore {
fn default() -> Self {
FileOrCertStore(None)
}
}
impl FromStr for FileOrCertStore {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
Ok(FileOrCertStore(Some(PathBuf::from(s))))
}
}
impl Display for FileOrCertStore {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
match &self.0 {
Some(path) => write!(f, "{}", path.display()),
None => write!(f, "-"),
}
}
= "Writes to FILE (or stdout when providing \"-\") instead of \
importing into the certificate store";
}
/// A type wrapping an optional PathBuf to use as stdout or file output
@ -378,12 +345,6 @@ impl Default for FileOrStdout {
}
}
impl From<FileOrCertStore> for FileOrStdout {
fn from(value: FileOrCertStore) -> Self {
FileOrStdout::new(value.into_inner())
}
}
impl From<PathBuf> for FileOrStdout {
fn from(value: PathBuf) -> Self {
if value == PathBuf::from("-") {

View File

@ -5,6 +5,7 @@ use crate::sq_cli::types::NetworkPolicy;
use super::types::ClapData;
use super::types::FileOrCertStore;
use super::types::FileOrStdin;
use super::types::FileOrStdout;
#[derive(Parser, Debug)]
#[clap(
@ -91,13 +92,12 @@ pub struct GetCommand {
)]
pub binary: bool,
#[clap(
default_value_t = FileOrCertStore::default(),
help = FileOrCertStore::HELP,
long,
short,
value_name = FileOrCertStore::VALUE_NAME,
)]
pub output: FileOrCertStore,
pub output: Option<FileOrStdout>,
}
#[derive(Debug, Args)]