summaryrefslogtreecommitdiffstats
path: root/sq
diff options
context:
space:
mode:
authorLars Wirzenius <liw@sequoia-pgp.org>2022-07-19 15:02:20 +0300
committerLars Wirzenius <liw@sequoia-pgp.org>2022-07-20 19:33:36 +0300
commitf912db582870e27e5f2d6240d30c9fd776915397 (patch)
tree7e6f818890fdb3930077e4119ce1c6b0aa0ce574 /sq
parenta0d49abc93ea17573e550b9614e18f58095c95c9 (diff)
sq: add JSON support for sq wkd url/direct-url
The JSON is the same same for both subcommands on the assumption that if someone is consuming JSON, they will pick the field relevant to them in any case. For someone consuming the default output format, they choose by using the right subcommand and don't have to parse the output. Sponsored-by: NLnet Foundation; NGI Assure
Diffstat (limited to 'sq')
-rw-r--r--sq/src/commands/net.rs94
1 files changed, 86 insertions, 8 deletions
diff --git a/sq/src/commands/net.rs b/sq/src/commands/net.rs
index f7a93bed..5d6e235a 100644
--- a/sq/src/commands/net.rs
+++ b/sq/src/commands/net.rs
@@ -24,6 +24,8 @@ use net::{
use crate::{
Config,
+ OutputFormat,
+ OutputVersion,
open_or_stdin,
serialize_keyring,
};
@@ -99,16 +101,24 @@ pub fn dispatch_wkd(config: Config, c: WkdCommand) -> Result<()> {
match c.subcommand {
WkdSubcommands::Url(c) => {
- let email_address = c.email_address;
- let wkd_url = wkd::Url::from(email_address)?;
- let url = wkd_url.to_url(None)?;
- println!("{}", url);
+ let output = wkd_output::WkdUrl::new(None, &c.email_address)?;
+ match config.output_format {
+ OutputFormat::HumanReadable => println!("{}", output.advanced_url()),
+ OutputFormat::Json => {
+ serde_json::to_writer_pretty(std::io::stdout(), &output)?;
+ println!();
+ }
+ }
},
WkdSubcommands::DirectUrl(c) => {
- let email_address = c.email_address;
- let wkd_url = wkd::Url::from(email_address)?;
- let url = wkd_url.to_url(wkd::Variant::Direct)?;
- println!("{}", url);
+ let output = wkd_output::WkdUrl::new(None, &c.email_address)?;
+ match config.output_format {
+ OutputFormat::HumanReadable => println!("{}", output.direct_url()),
+ OutputFormat::Json => {
+ serde_json::to_writer_pretty(std::io::stdout(), &output)?;
+ println!();
+ }
+ }
},
WkdSubcommands::Get(c) => {
// Check that the policy allows https.
@@ -168,3 +178,71 @@ pub fn dispatch_wkd(config: Config, c: WkdCommand) -> Result<()> {
Ok(())
}
+
+// Model output as a data type that can be serialized.
+mod wkd_output {
+ use super::{wkd, OutputVersion, Result};
+ use anyhow::anyhow;
+ use serde::Serialize;
+
+ #[derive(Debug, Serialize)]
+ #[serde(untagged)]
+ pub(super) enum WkdUrl {
+ V0(WkdUrlV0),
+ }
+
+ impl WkdUrl {
+ const DEFAULT_VERSION: OutputVersion = OutputVersion::new(0, 0, 0);
+
+ pub(super) fn new(wanted: Option<OutputVersion>, email: &str) -> Result<Self> {
+ let wkd_url = wkd::Url::from(email)?;
+ let advanced_url = wkd_url.to_url(None)?.to_string();
+ let direct_url = wkd_url.to_url(wkd::Variant::Direct)?.to_string();
+
+ match wanted {
+ None => Self::new(Some(Self::DEFAULT_VERSION), email),
+ Some(wanted) if WkdUrlV0::V.is_acceptable_for(wanted) => Ok(Self::V0(WkdUrlV0::new(advanced_url, direct_url))),
+ Some(wanted) => Err(anyhow!("version not supported: {}", wanted)),
+ }
+ }
+
+ pub(super) fn advanced_url(&self) -> &str {
+ match self {
+ Self::V0(url) => url.advanced_url(),
+ }
+ }
+
+ pub(super) fn direct_url(&self) -> &str {
+ match self {
+ Self::V0(url) => url.direct_url(),
+ }
+ }
+ }
+
+ #[derive(Debug, Serialize)]
+ pub(super) struct WkdUrlV0 {
+ sq_output_version: OutputVersion,
+ advanced_url: String,
+ direct_url: String,
+ }
+
+ impl WkdUrlV0 {
+ const V: OutputVersion = OutputVersion::new(0, 0, 0);
+
+ fn new(advanced_url: String, direct_url: String) -> Self {
+ Self {
+ sq_output_version: Self::V,
+ advanced_url,
+ direct_url,
+ }
+ }
+
+ pub(super) fn advanced_url(&self) -> &str {
+ &self.advanced_url
+ }
+
+ pub(super) fn direct_url(&self) -> &str {
+ &self.direct_url
+ }
+ }
+}