make printing less complicated and refactor cli
i made printing less complicated by making printing both the name and the url with the seperator the default option and using both those flags at the same time should do the same thing as just printing without any flags. i also refactored commands into their own module folder with each command getting their own file module.
This commit is contained in:
parent
df86523df2
commit
82e8f68862
10 changed files with 261 additions and 162 deletions
61
.vscode/launch.json
vendored
61
.vscode/launch.json
vendored
|
@ -1,15 +1,62 @@
|
||||||
{
|
{
|
||||||
// Use IntelliSense to learn about possible attributes.
|
// Use IntelliSense to learn about possible attributes.
|
||||||
// Hover to view descriptions of existing attributes.
|
// Hover to view descriptions of existing attributes.
|
||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"type": "lldb",
|
"type": "lldb",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"name": "run meowy-cli",
|
"name": "meowy-cli (Print)",
|
||||||
"program": "${workspaceFolder}/target/debug/meowy-cli",
|
"program": "${workspaceFolder}/target/debug/meowy-cli",
|
||||||
"args": ["print"],
|
"args": [
|
||||||
|
"print"
|
||||||
|
],
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"sourceMap": {},
|
||||||
|
"sourceLanguages": [
|
||||||
|
"rust"
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "meowy-cli (Print) json",
|
||||||
|
"program": "${workspaceFolder}/target/debug/meowy-cli",
|
||||||
|
"args": [
|
||||||
|
"print",
|
||||||
|
"--json"
|
||||||
|
],
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"sourceMap": {},
|
||||||
|
"sourceLanguages": [
|
||||||
|
"rust"
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "meowy-cli (Print) only url",
|
||||||
|
"program": "${workspaceFolder}/target/debug/meowy-cli",
|
||||||
|
"args": [
|
||||||
|
"print",
|
||||||
|
"--url"
|
||||||
|
],
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"sourceMap": {},
|
||||||
|
"sourceLanguages": [
|
||||||
|
"rust"
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "meowy-cli (Print) only name",
|
||||||
|
"program": "${workspaceFolder}/target/debug/meowy-cli",
|
||||||
|
"args": [
|
||||||
|
"print",
|
||||||
|
"--name"
|
||||||
|
],
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
"sourceMap": {},
|
"sourceMap": {},
|
||||||
"sourceLanguages": [
|
"sourceLanguages": [
|
||||||
|
|
|
@ -9,7 +9,7 @@ serde_json = "1.0"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
|
||||||
[dependencies.clap]
|
[dependencies.clap]
|
||||||
version = "4"
|
version = "4"
|
||||||
features = ["derive"]
|
features = ["derive"]
|
||||||
|
|
||||||
[dependencies.shared]
|
[dependencies.shared]
|
||||||
|
@ -18,6 +18,7 @@ path = "../shared"
|
||||||
[dependencies.simple_logger]
|
[dependencies.simple_logger]
|
||||||
version = "4"
|
version = "4"
|
||||||
default-features = false
|
default-features = false
|
||||||
|
features = ["stderr"]
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "meowy-cli"
|
name = "meowy-cli"
|
||||||
|
|
|
@ -5,6 +5,12 @@ use clap::{arg, command, Args, Parser, Subcommand};
|
||||||
pub(crate) struct Arguments {
|
pub(crate) struct Arguments {
|
||||||
#[arg(help = "the path to the names.json file", long, short)]
|
#[arg(help = "the path to the names.json file", long, short)]
|
||||||
pub(crate) path: Option<String>,
|
pub(crate) path: Option<String>,
|
||||||
|
#[arg(
|
||||||
|
long,
|
||||||
|
short,
|
||||||
|
help = "a seperator string to seperate the url from the name. defaults to : with a space after that."
|
||||||
|
)]
|
||||||
|
pub(crate) seperator: Option<String>,
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
pub(crate) command: Commands,
|
pub(crate) command: Commands,
|
||||||
}
|
}
|
||||||
|
@ -17,20 +23,11 @@ pub(crate) enum Commands {
|
||||||
filter: Option<String>,
|
filter: Option<String>,
|
||||||
#[command(flatten)]
|
#[command(flatten)]
|
||||||
group: PrintGroup,
|
group: PrintGroup,
|
||||||
#[arg(
|
|
||||||
long,
|
|
||||||
short,
|
|
||||||
help = "a seperator character to seperate the url from the name. defaults to ,",
|
|
||||||
requires = "url",
|
|
||||||
requires = "name"
|
|
||||||
)]
|
|
||||||
seperator: Option<char>,
|
|
||||||
#[arg(
|
#[arg(
|
||||||
long,
|
long,
|
||||||
short,
|
short,
|
||||||
conflicts_with = "url",
|
conflicts_with = "url",
|
||||||
conflicts_with = "name",
|
conflicts_with = "name",
|
||||||
conflicts_with = "seperator",
|
|
||||||
help = "print the data out as a json string"
|
help = "print the data out as a json string"
|
||||||
)]
|
)]
|
||||||
json: bool,
|
json: bool,
|
||||||
|
|
|
@ -1,141 +0,0 @@
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use shared::errors::ErrorStatus;
|
|
||||||
use shared::names;
|
|
||||||
use shared::{errors::Error, names::Site};
|
|
||||||
|
|
||||||
use crate::arguments::PrintGroup;
|
|
||||||
|
|
||||||
fn group_printing(seperator: &Option<char>, site: &Site, group: &PrintGroup) {
|
|
||||||
let mut string = String::new();
|
|
||||||
let delimiter = seperator.unwrap_or(',');
|
|
||||||
|
|
||||||
if group.url {
|
|
||||||
string += &site.url;
|
|
||||||
}
|
|
||||||
|
|
||||||
if group.name {
|
|
||||||
if !string.is_empty() {
|
|
||||||
string += &format!(
|
|
||||||
"{}{}",
|
|
||||||
delimiter,
|
|
||||||
site.name.as_ref().unwrap_or(&"None".into())
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
string += &site.name.as_ref().unwrap_or(&"None".into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log::info!("{}", string);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn json_printing(site: &Site) -> Result<(), Error> {
|
|
||||||
match serde_json::to_string(&site) {
|
|
||||||
Ok(json) => {
|
|
||||||
log::info!("{}", json);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
Err(err) => Err(Error {
|
|
||||||
status: ErrorStatus::ParsingError,
|
|
||||||
data: err.to_string(),
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn filter_site(
|
|
||||||
site: &Site,
|
|
||||||
json: bool,
|
|
||||||
seperator: &Option<char>,
|
|
||||||
group: &PrintGroup,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
if json {
|
|
||||||
json_printing(site)?;
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
if !group.url && !group.name {
|
|
||||||
log::info!("{:?}", site);
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(group_printing(seperator, site, group));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn print(
|
|
||||||
path: &Path,
|
|
||||||
filter: &Option<String>,
|
|
||||||
group: &PrintGroup,
|
|
||||||
seperator: &Option<char>,
|
|
||||||
json: bool,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
let names_file = names::read_names_file(path)?;
|
|
||||||
let mut names = names::load_names(names_file)?;
|
|
||||||
|
|
||||||
if let Some(filter) = filter {
|
|
||||||
names.retain(|f| &f.url == filter);
|
|
||||||
if names.len() == 0 {
|
|
||||||
return Err(Error {
|
|
||||||
status: ErrorStatus::NotFoundError,
|
|
||||||
data: "this url was not found in names.json".into(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return filter_site(&names[0], json, seperator, group);
|
|
||||||
}
|
|
||||||
|
|
||||||
for site in names {
|
|
||||||
if json {
|
|
||||||
json_printing(&site)?;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if !group.url && !group.name {
|
|
||||||
log::info!("{:?}", site);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
group_printing(seperator, &site, group);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn add(path: &Path, url: &String, name: &Option<String>) -> Result<(), Error> {
|
|
||||||
let names_file = names::read_names_file(path)?;
|
|
||||||
let mut names = names::load_names(names_file)?;
|
|
||||||
|
|
||||||
if names.iter().any(|site| site.url.contains(url)) {
|
|
||||||
return Err(Error {
|
|
||||||
status: ErrorStatus::AlreadyExistsError,
|
|
||||||
data:
|
|
||||||
"this url already exists in names.json. you can't have more then 1 of the same url."
|
|
||||||
.into(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let site = Site {
|
|
||||||
url: url.to_string(),
|
|
||||||
name: name.to_owned(),
|
|
||||||
};
|
|
||||||
log::debug!("adding {:?} to {}", site, path.display());
|
|
||||||
names.push(site.clone());
|
|
||||||
let json = serde_json::to_string(&names).unwrap();
|
|
||||||
std::fs::write(path, json).unwrap();
|
|
||||||
log::info!("added {:?} to names.json", site);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn remove(path: &Path, url: &String) -> Result<(), Error> {
|
|
||||||
let names_file = names::read_names_file(path)?;
|
|
||||||
let mut names = names::load_names(names_file)?;
|
|
||||||
|
|
||||||
names.retain(|site| {
|
|
||||||
if &site.url == url {
|
|
||||||
log::info!("removing {:?} from names.json", site);
|
|
||||||
}
|
|
||||||
&site.url != url
|
|
||||||
});
|
|
||||||
let json = serde_json::to_string(&names).unwrap();
|
|
||||||
std::fs::write(path, json).unwrap();
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
43
cli/src/commands/add.rs
Normal file
43
cli/src/commands/add.rs
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
use shared::{
|
||||||
|
errors::{Error, ErrorStatus},
|
||||||
|
names::{self, Site},
|
||||||
|
};
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use crate::commands::utils::{site_string, PrintOptions};
|
||||||
|
|
||||||
|
pub(crate) fn add(
|
||||||
|
path: &Path,
|
||||||
|
url: &String,
|
||||||
|
name: &Option<String>,
|
||||||
|
seperator: &String,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let names_file = names::read_names_file(path)?;
|
||||||
|
let mut names = names::load_names(names_file)?;
|
||||||
|
|
||||||
|
if names.iter().any(|site| site.url.contains(url)) {
|
||||||
|
return Err(Error {
|
||||||
|
status: ErrorStatus::AlreadyExistsError,
|
||||||
|
data:
|
||||||
|
"this url already exists in names.json. you can't have more then 1 of the same url."
|
||||||
|
.into(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let site = Site {
|
||||||
|
url: url.to_string(),
|
||||||
|
name: name.to_owned(),
|
||||||
|
};
|
||||||
|
|
||||||
|
log::debug!("adding {:?} to {}", site, path.display());
|
||||||
|
names.push(site.clone());
|
||||||
|
|
||||||
|
let json = serde_json::to_string(&names).unwrap();
|
||||||
|
std::fs::write(path, json).unwrap();
|
||||||
|
println!(
|
||||||
|
"added {} to names.json",
|
||||||
|
site_string(&site, PrintOptions::All, seperator)
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
8
cli/src/commands/mod.rs
Normal file
8
cli/src/commands/mod.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
mod add;
|
||||||
|
mod print;
|
||||||
|
mod remove;
|
||||||
|
mod utils;
|
||||||
|
|
||||||
|
pub(crate) use add::add;
|
||||||
|
pub(crate) use print::print;
|
||||||
|
pub(crate) use remove::remove;
|
88
cli/src/commands/print.rs
Normal file
88
cli/src/commands/print.rs
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
use crate::{arguments::PrintGroup, commands::utils::site_string};
|
||||||
|
use shared::{
|
||||||
|
errors::{Error, ErrorStatus},
|
||||||
|
names::{self, Site},
|
||||||
|
};
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use super::utils::PrintOptions;
|
||||||
|
|
||||||
|
pub(crate) fn print(
|
||||||
|
path: &Path,
|
||||||
|
filter: &Option<String>,
|
||||||
|
group: &PrintGroup,
|
||||||
|
seperator: &String,
|
||||||
|
json: bool,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let names_file = names::read_names_file(path)?;
|
||||||
|
let mut names = names::load_names(names_file)?;
|
||||||
|
|
||||||
|
if let Some(filter) = filter {
|
||||||
|
names.retain(|f| &f.url == filter);
|
||||||
|
if names.len() == 0 {
|
||||||
|
return Err(Error {
|
||||||
|
status: ErrorStatus::NotFoundError,
|
||||||
|
data: "this url was not found in names.json".into(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return filter_site(&names[0], json, seperator, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
for site in names {
|
||||||
|
if json {
|
||||||
|
json_printing(&site)?;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
printing(seperator, &site, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn filter_site(
|
||||||
|
site: &Site,
|
||||||
|
json: bool,
|
||||||
|
seperator: &String,
|
||||||
|
group: &PrintGroup,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
if json {
|
||||||
|
json_printing(site)?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(printing(seperator, site, group));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn json_printing(site: &Site) -> Result<(), Error> {
|
||||||
|
match serde_json::to_string(&site) {
|
||||||
|
Ok(json) => {
|
||||||
|
println!("{}", json);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(err) => Err(Error {
|
||||||
|
status: ErrorStatus::ParsingError,
|
||||||
|
data: err.to_string(),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn printing(seperator: &String, site: &Site, group: &PrintGroup) {
|
||||||
|
let string = site_string(site, print_group_to_options(group), seperator);
|
||||||
|
|
||||||
|
println!("{}", string);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_group_to_options(group: &PrintGroup) -> PrintOptions {
|
||||||
|
match group {
|
||||||
|
PrintGroup {
|
||||||
|
url: true,
|
||||||
|
name: false,
|
||||||
|
} => PrintOptions::Url,
|
||||||
|
PrintGroup {
|
||||||
|
url: false,
|
||||||
|
name: true,
|
||||||
|
} => PrintOptions::Name,
|
||||||
|
_ => PrintOptions::All,
|
||||||
|
}
|
||||||
|
}
|
23
cli/src/commands/remove.rs
Normal file
23
cli/src/commands/remove.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
use shared::{errors::Error, names};
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use crate::commands::utils::{site_string, PrintOptions};
|
||||||
|
|
||||||
|
pub(crate) fn remove(path: &Path, url: &String, seperator: &String) -> Result<(), Error> {
|
||||||
|
let names_file = names::read_names_file(path)?;
|
||||||
|
let mut names = names::load_names(names_file)?;
|
||||||
|
|
||||||
|
names.retain(|site| {
|
||||||
|
if &site.url == url {
|
||||||
|
println!(
|
||||||
|
"removing {} from names.json",
|
||||||
|
site_string(&site, PrintOptions::All, seperator)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
&site.url != url
|
||||||
|
});
|
||||||
|
let json = serde_json::to_string(&names).unwrap();
|
||||||
|
std::fs::write(path, json).unwrap();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
28
cli/src/commands/utils.rs
Normal file
28
cli/src/commands/utils.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
use shared::names::Site;
|
||||||
|
|
||||||
|
pub(super) enum PrintOptions {
|
||||||
|
Url,
|
||||||
|
Name,
|
||||||
|
All,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn site_string(site: &Site, options: PrintOptions, seperator: &String) -> String {
|
||||||
|
let mut string = String::new();
|
||||||
|
|
||||||
|
if matches!(options, PrintOptions::Url) || matches!(options, PrintOptions::All) {
|
||||||
|
string += &site.url;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(name) = &site.name {
|
||||||
|
if matches!(options, PrintOptions::Url) {
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
if !string.is_empty() {
|
||||||
|
string += &format!("{}{}", seperator, name)
|
||||||
|
} else {
|
||||||
|
string += name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
use std::path::Path;
|
|
||||||
use arguments::{Arguments, Commands};
|
use arguments::{Arguments, Commands};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use commands::{add, print, remove};
|
use commands::{add, print, remove};
|
||||||
use shared::{directories, errors::Error};
|
use shared::{directories, errors::Error};
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
mod arguments;
|
mod arguments;
|
||||||
mod commands;
|
mod commands;
|
||||||
|
@ -13,6 +13,7 @@ fn main() -> Result<(), Error> {
|
||||||
|
|
||||||
let default_path = directories::get_names_path()?;
|
let default_path = directories::get_names_path()?;
|
||||||
let args = Arguments::parse();
|
let args = Arguments::parse();
|
||||||
|
let seperator = args.seperator.unwrap_or(": ".into());
|
||||||
|
|
||||||
let path = match &args.path {
|
let path = match &args.path {
|
||||||
Some(path) => Path::new(path),
|
Some(path) => Path::new(path),
|
||||||
|
@ -20,9 +21,13 @@ fn main() -> Result<(), Error> {
|
||||||
};
|
};
|
||||||
|
|
||||||
match &args.command {
|
match &args.command {
|
||||||
Commands::Print { filter, group, seperator, json, } => print(path, filter, group, seperator, *json)?,
|
Commands::Print {
|
||||||
Commands::Add { url, name } => add(path, url, name)?,
|
filter,
|
||||||
Commands::Remove { url } => remove(path, url)?,
|
group,
|
||||||
|
json,
|
||||||
|
} => print(path, filter, group, &seperator, *json)?,
|
||||||
|
Commands::Add { url, name } => add(path, url, name, &seperator)?,
|
||||||
|
Commands::Remove { url } => remove(path, url, &seperator)?,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Reference in a new issue