Skip to content

Exend list formats to include json #252

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 103 additions & 8 deletions src/cli_commands.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use clap::{Parser, Subcommand, ValueEnum};
use clap::{
Arg, ArgAction, ArgMatches, Args, Command, Error, FromArgMatches, Id, Parser, Subcommand,
ValueEnum,
};

#[derive(Parser)]
#[command(author, version, about, long_about = None)]
Expand Down Expand Up @@ -27,6 +30,102 @@ pub enum Mode {
Revert,
}

#[allow(non_camel_case_types)]
#[derive(Debug)]
pub enum ListFormat {
/// Format commands as table
simple,
/// Format commands as JSON
json,
/// Format commands as YAML
yaml,
}

impl FromArgMatches for ListFormat {
fn from_arg_matches(matches: &ArgMatches) -> Result<Self, Error> {
let mut matches = matches.clone();
Self::from_arg_matches_mut(&mut matches)
}

fn from_arg_matches_mut(matches: &mut ArgMatches) -> Result<Self, Error> {
match (
matches.get_flag("simple"),
matches.get_flag("json"),
matches.get_flag("yaml"),
) {
(_, false, false) => Ok(Self::simple),
(false, true, false) => Ok(Self::json),
(false, false, true) => Ok(Self::yaml),
(_, _, _) => Err(Error::raw(
clap::error::ErrorKind::ValueValidation,
"cannot specify more than one of 'simple', 'json', or 'yaml' at once",
)),
}
}

fn update_from_arg_matches(&mut self, matches: &ArgMatches) -> Result<(), Error> {
let mut matches = matches.clone();
self.update_from_arg_matches_mut(&mut matches)
}

fn update_from_arg_matches_mut(&mut self, matches: &mut ArgMatches) -> Result<(), Error> {
match (
matches.get_flag("simple"),
matches.get_flag("json"),
matches.get_flag("yaml"),
) {
(_, false, false) => {
*self = Self::simple;
Ok(())
}
(false, true, false) => {
*self = Self::json;
Ok(())
}
(false, false, true) => {
*self = Self::yaml;
Ok(())
}
(_, _, _) => Err(Error::raw(
clap::error::ErrorKind::ValueValidation,
"cannot specify more than one of 'simple', 'json', or 'yaml' at once",
)),
}
}
}

impl Args for ListFormat {
fn augment_args(cmd: Command) -> Command {
cmd.arg(
Arg::new("simple")
.short('s')
.long("simple")
.action(ArgAction::SetTrue)
.groups(["list"]),
)
.arg(
Arg::new("json")
.short('j')
.long("json")
.action(ArgAction::SetTrue)
.groups(["list"]),
)
.arg(
Arg::new("yaml")
.short('y')
.long("yaml")
.action(ArgAction::SetTrue)
.groups(["list"]),
)
}
fn augment_args_for_update(cmd: Command) -> Command {
Self::augment_args(cmd)
}
fn group_id() -> Option<clap::Id> {
Some(Id::from("list"))
}
}

#[derive(Subcommand)]
pub enum Commands {
/// Shows setting file paths
Expand Down Expand Up @@ -57,13 +156,9 @@ pub enum Commands {
#[arg(short = 'f', long)]
filter: Option<String>,

/// Return hoarded commands in structured format
#[arg(short = 'j', long)]
json: bool,

/// Return hoarded commands in a simplified table view
#[arg(short = 's', long)]
simple: bool,
/// Select which format to output commands. Default is "simple", which formats commands as a table
#[command(flatten)]
format: Option<ListFormat>,
},

/// Pick a command of the trove and print it
Expand Down
4 changes: 4 additions & 0 deletions src/command/trove.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ impl CommandTrove {
serde_yaml::to_string(&self).unwrap()
}

pub fn to_json(&self) -> String {
serde_json::to_string(&self).unwrap()
}

pub fn save_trove_file(&self, path: &Path) {
let s = self.to_yaml();
fs::write(path, s).expect("Unable to write config file");
Expand Down
37 changes: 20 additions & 17 deletions src/hoard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::path::{Path, PathBuf};
use std::str::FromStr;
use url::ParseError;

use crate::cli_commands::Mode;
use crate::cli_commands::{ListFormat, Mode};
use crate::command::hoard_command::HoardCommand;
use crate::command::trove::CommandTrove;
use crate::config::{compare_with_latest_version, HoardConfig};
Expand Down Expand Up @@ -70,13 +70,8 @@ impl Hoard {
description.clone(),
);
}
Commands::List {
filter,
json,
simple,
} => {
let commands =
self.list_commands(simple.to_owned(), json.to_owned(), filter.clone());
Commands::List { filter, format } => {
let commands = self.list_commands(format, filter.clone());
if let Some(c) = commands {
autocomplete_command = c;
}
Expand Down Expand Up @@ -165,19 +160,27 @@ impl Hoard {

fn list_commands(
&mut self,
is_simple: bool,
is_structured: bool,
format: &Option<ListFormat>,
filter: Option<String>,
) -> Option<String> {
if self.trove.is_empty() {
println!("No command hoarded.\nRun [ hoard new ] first to hoard a command.");
} else if is_simple {
self.trove.print_trove();
} else if is_structured {
// Return list of commands in json format, filtered by `filter`
let query_string: String = filter.unwrap_or_default();
let filtered_trove = query_trove(&self.trove, &query_string);
return Some(filtered_trove.to_yaml());
} else if let Some(format) = format {
match format {
ListFormat::simple => self.trove.print_trove(),
ListFormat::json => {
// Return list of commands in json format, filtered by `filter`
let query_string: String = filter.unwrap_or_default();
let filtered_trove = query_trove(&self.trove, &query_string);
return Some(filtered_trove.to_json());
}
ListFormat::yaml => {
// Return list of commands in yaml format, filtered by `filter`
let query_string: String = filter.unwrap_or_default();
let filtered_trove = query_trove(&self.trove, &query_string);
return Some(filtered_trove.to_yaml());
}
}
} else {
match commands_gui::run(&mut self.trove, self.config.as_ref().unwrap()) {
Ok(selected_command) => {
Expand Down