diff --git a/doc/src/04020-module-tag.md b/doc/src/04020-module-tag.md index 9e644efd..08c66ecf 100644 --- a/doc/src/04020-module-tag.md +++ b/doc/src/04020-module-tag.md @@ -2,6 +2,8 @@ The Tagging module. +A valid tag matches the regex `[a-zA-Z][0-9a-zA-Z]*`. + ### Description diff --git a/imag-bookmark/src/ui.rs b/imag-bookmark/src/ui.rs index 76b883de..0b142574 100644 --- a/imag-bookmark/src/ui.rs +++ b/imag-bookmark/src/ui.rs @@ -20,6 +20,7 @@ use clap::{Arg, App, SubCommand}; use libimagentrytag::ui::tag_add_arg; +use libimagutil::cli_validators::*; pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { app @@ -41,6 +42,7 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .required(true) .multiple(true) .value_name("URL") + .validator(is_url) .help("Add this URL, multiple possible")) .arg(tag_add_arg()) ) @@ -63,6 +65,7 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .required(true) .multiple(true) .value_name("URL") + .validator(is_url) .help("Remove these urls, regex supported")) ) diff --git a/imag-ref/Cargo.toml b/imag-ref/Cargo.toml index da41fdcf..221615a2 100644 --- a/imag-ref/Cargo.toml +++ b/imag-ref/Cargo.toml @@ -27,3 +27,6 @@ path = "../libimaginteraction" [dependencies.libimagentrylist] path = "../libimagentrylist" +[dependencies.libimagutil] +path = "../libimagutil" + diff --git a/imag-ref/src/main.rs b/imag-ref/src/main.rs index 1d3a5a13..f7212b46 100644 --- a/imag-ref/src/main.rs +++ b/imag-ref/src/main.rs @@ -28,6 +28,7 @@ extern crate libimagref; extern crate libimagerror; extern crate libimagentrylist; extern crate libimaginteraction; +extern crate libimagutil; mod ui; use ui::build_ui; diff --git a/imag-ref/src/ui.rs b/imag-ref/src/ui.rs index 8fc952d0..5c4685e2 100644 --- a/imag-ref/src/ui.rs +++ b/imag-ref/src/ui.rs @@ -19,6 +19,8 @@ use clap::{Arg, App, SubCommand}; +use libimagutil::cli_validators::is_existing_path; + pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { app .subcommand(SubCommand::with_name("add") @@ -30,6 +32,7 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .takes_value(true) .required(true) .help("The path of the file") + .validator(is_existing_path) .value_name("PATH")) .arg(Arg::with_name("track-content") .long("content-hash") diff --git a/libimagentrytag/src/ui.rs b/libimagentrytag/src/ui.rs index 066f06da..dad4c87e 100644 --- a/libimagentrytag/src/ui.rs +++ b/libimagentrytag/src/ui.rs @@ -21,6 +21,8 @@ use clap::{Arg, ArgMatches, App, SubCommand}; use tag::Tag; +use libimagutil::cli_validators::is_tag; + /// Generates a `clap::SubCommand` to be integrated in the commandline-ui builder for building a /// "tags --add foo --remove bar" subcommand to do tagging action. pub fn tag_subcommand<'a, 'b>() -> App<'a, 'b> { @@ -39,6 +41,7 @@ pub fn tag_add_arg<'a, 'b>() -> Arg<'a, 'b> { .takes_value(true) .value_name("tags") .multiple(true) + .validator(is_tag) .help("Add tags, seperated by comma or by specifying multiple times") } @@ -49,6 +52,7 @@ pub fn tag_remove_arg<'a, 'b>() -> Arg<'a, 'b> { .takes_value(true) .value_name("tags") .multiple(true) + .validator(is_tag) .help("Remove tags, seperated by comma or by specifying multiple times") } @@ -76,6 +80,7 @@ pub fn tag_argument<'a, 'b>() -> Arg<'a, 'b> { .long("tags") .takes_value(true) .multiple(true) + .validator(is_tag) .help("Add or remove tags, prefixed by '+' (for adding) or '-' (for removing)") } diff --git a/libimagutil/Cargo.toml b/libimagutil/Cargo.toml index 87be5306..61dd88e7 100644 --- a/libimagutil/Cargo.toml +++ b/libimagutil/Cargo.toml @@ -4,6 +4,8 @@ version = "0.2.0" authors = ["Matthias Beyer "] [dependencies] +url = "1.1" +boolinator = "2.4.0" lazy_static = "0.1.15" log = "0.3" regex = "0.1" diff --git a/libimagutil/src/cli_validators.rs b/libimagutil/src/cli_validators.rs new file mode 100644 index 00000000..068d5834 --- /dev/null +++ b/libimagutil/src/cli_validators.rs @@ -0,0 +1,39 @@ +//! Functions to be used for clap::Arg::validator() +//! to validate arguments + +use std::path::PathBuf; +use boolinator::Boolinator; + +pub fn is_existing_path(s: String) -> Result<(), String> { + PathBuf::from(s.clone()).exists().as_result((), format!("Not a File or Directory: {}", s)) +} + +pub fn is_file(s: String) -> Result<(), String> { + PathBuf::from(s.clone()).is_file().as_result((), format!("Not a File: {}", s)) +} + +pub fn is_directory(s: String) -> Result<(), String> { + PathBuf::from(s.clone()).is_dir().as_result((), format!("Not a Directory: {}", s)) +} + +pub fn is_integer(s: String) -> Result<(), String> { + use std::str::FromStr; + + let i : Result = FromStr::from_str(&s); + i.map(|_| ()).map_err(|_| format!("Not an integer: {}", s)) +} + +pub fn is_url(s: String) -> Result<(), String> { + use url::Url; + Url::parse(&s).map(|_| ()).map_err(|_| format!("Not a URL: {}", s)) +} + +pub fn is_tag(s: String) -> Result<(), String> { + use regex::Regex; + lazy_static! { static ref TAG_RE : Regex = Regex::new("[:alpha:][:word:]*").unwrap(); } + + TAG_RE + .is_match(&s) + .as_result((), format!("Not a valid Tag: '{}' - Valid is [a-zA-Z][0-9a-zA-Z]*", s)) +} + diff --git a/libimagutil/src/lib.rs b/libimagutil/src/lib.rs index adf0ac78..dc7876ad 100644 --- a/libimagutil/src/lib.rs +++ b/libimagutil/src/lib.rs @@ -35,9 +35,12 @@ #[macro_use] extern crate lazy_static; #[macro_use] extern crate log; extern crate regex; +extern crate url; +extern crate boolinator; extern crate tempfile; #[macro_use] mod log_result; +pub mod cli_validators; pub mod debug_result; pub mod edit; pub mod info_result;