diff --git a/README.md b/README.md index 5025c22..7119bb7 100644 --- a/README.md +++ b/README.md @@ -41,16 +41,16 @@ For more information on these traits, see their respective documentation: Below is a minimal example of a full CLI application using this library. ```rust -use uutils_args::{Arguments, Initial, Options}; +use uutils_args::{Arguments, Options}; #[derive(Arguments)] enum Arg { // The doc strings below will be part of the `--help` text // First we define a simple flag: - /// Do not transform input text to uppercase - #[arg("-n", "--no-caps")] - NoCaps, - + /// Transform input text to uppercase + #[arg("-c", "--caps")] + Caps, + // This option takes a value: /// Add exclamation marks to output #[arg("-e N", "--exclaim=N")] @@ -62,10 +62,8 @@ enum Arg { Text(String), } -#[derive(Initial)] +#[derive(Default)] struct Settings { - // We can change the default value with the field attribute. - #[initial(true)] caps: bool, exclamation_marks: u8, text: String, @@ -76,7 +74,7 @@ struct Settings { impl Options for Settings { fn apply(&mut self, arg: Arg) { match arg { - Arg::NoCaps => self.caps = false, + Arg::Caps => self.caps = true, Arg::ExclamationMarks(n) => self.exclamation_marks += n, Arg::Text(s) => { if self.text.is_empty() { @@ -91,7 +89,7 @@ impl Options for Settings { } fn run(args: &'static [&'static str]) -> String { - let s = Settings::parse(args); + let s = Settings::default().parse(args); let mut output = if s.caps { s.text.to_uppercase() } else { @@ -104,24 +102,20 @@ fn run(args: &'static [&'static str]) -> String { } // The first argument is the binary name. In this example it's ignored. -assert_eq!(run(&["shout", "hello"]), "HELLO"); -assert_eq!(run(&["shout", "-e3", "hello"]), "HELLO!!!"); -assert_eq!(run(&["shout", "-e", "3", "hello"]), "HELLO!!!"); -assert_eq!(run(&["shout", "--no-caps", "hello"]), "hello"); -assert_eq!(run(&["shout", "-e3", "-n", "hello"]), "hello!!!"); -assert_eq!(run(&["shout", "-e3", "hello", "world"]), "HELLO WORLD!!!"); +assert_eq!(run(&["shout", "hello"]), "hello"); +assert_eq!(run(&["shout", "-e3", "hello"]), "hello!!!"); +assert_eq!(run(&["shout", "-e", "3", "hello"]), "hello!!!"); +assert_eq!(run(&["shout", "--caps", "hello"]), "HELLO"); +assert_eq!(run(&["shout", "-e3", "-c", "hello"]), "HELLO!!!"); +assert_eq!(run(&["shout", "-e3", "-c", "hello", "world"]), "HELLO WORLD!!!"); ``` -## Additional functionality +## Value parsing -To make it easier to implement [`Arguments`] and [`Options`], there are -two additional traits: - -- [`Initial`] is an alternative to the [`Default`] trait from the standard - library, with a richer derive macro. -- [`Value`] allows for easy parsing from `OsStr` to any type - implementing [`Value`]. This crate also provides a derive macro for - this trait. +To make it easier to implement [`Arguments`] and [`Options`], there is the +[`Value`] trait, which allows for easy parsing from `OsStr` to any type +implementing [`Value`]. This crate also provides a derive macro for +this trait. ## Examples diff --git a/derive/src/initial.rs b/derive/src/initial.rs deleted file mode 100644 index ced4032..0000000 --- a/derive/src/initial.rs +++ /dev/null @@ -1,136 +0,0 @@ -// For the full copyright and license information, please view the LICENSE -// file that was distributed with this source code. - -use syn::{ - parse::{Parse, ParseStream}, - parse_macro_input, Data, DeriveInput, Fields, Token, -}; - -use proc_macro::TokenStream; -use quote::quote; -use syn::{punctuated::Punctuated, Attribute, Expr, LitStr}; - -mod kw { - syn::custom_keyword!(env); -} - -enum InitialArg { - Expr(Expr), - Env(String), -} - -#[derive(Default)] -struct InitialField { - expr: Option, - env: Option, -} - -impl Parse for InitialArg { - fn parse(input: ParseStream) -> syn::Result { - if input.peek(kw::env) && input.peek2(Token![=]) { - input.parse::()?; - input.parse::()?; - Ok(InitialArg::Env(input.parse::()?.value())) - } else { - Ok(InitialArg::Expr(input.parse::()?)) - } - } -} - -impl InitialField { - fn from_attribute(attribute: &Attribute) -> syn::Result { - let mut _self = Self::default(); - - let args = - attribute.parse_args_with(Punctuated::::parse_terminated)?; - - for arg in args { - match arg { - InitialArg::Expr(e) => { - if _self.expr.is_some() { - panic!("Can only specify one initial expression") - } - _self.expr = Some(e); - } - InitialArg::Env(s) => { - if _self.expr.is_some() { - panic!("Can only specify one env variable") - } - _self.env = Some(s); - } - } - } - - Ok(_self) - } - - fn into_expr(self) -> proc_macro2::TokenStream { - let mut default_value = match self.expr { - Some(val) => quote!(#val), - None => quote!(::core::default::Default::default()), - }; - - if let Some(env_var) = self.env { - default_value = quote!( - ::std::env::var_os(#env_var) - .and_then(|v| ::uutils_args::Value::from_value(&v).ok()) - .unwrap_or(#default_value) - ); - } - - default_value - } -} - -pub fn initial(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); - - let name = input.ident; - let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); - - let function_body = match input.data { - Data::Struct(data) => initial_struct(data), - _ => panic!("Initial derive macro can only be used on structs"), - }; - - quote!( - impl #impl_generics Initial for #name #ty_generics #where_clause { - fn initial() -> Self { - #function_body - } - } - ) - .into() -} - -fn initial_struct(data: syn::DataStruct) -> proc_macro2::TokenStream { - let Fields::Named(fields) = data.fields else { - panic!("Fields must be named"); - }; - - // The key of this map is a literal pattern and the value - // is whatever code needs to be run when that pattern is encountered. - let mut defaults = Vec::new(); - for field in fields.named { - let ident = field.ident; - let field = parse_field_attr(&field.attrs); - let default_value = field.into_expr(); - - defaults.push(quote!(#ident: #default_value)); - } - - quote!( - Self { - #(#defaults),* - } - ) -} - -fn parse_field_attr(attrs: &[Attribute]) -> InitialField { - for attr in attrs { - if attr.path().is_ident("initial") { - return InitialField::from_attribute(attr).expect("Failed to parse initial attribute"); - } - } - InitialField::default() -} diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 7383602..fc463bf 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -6,7 +6,6 @@ mod attributes; mod flags; mod help; mod help_parser; -mod initial; use argument::{ free_handling, long_handling, parse_argument, parse_arguments_attr, positional_handling, @@ -19,11 +18,6 @@ use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, Data::Enum, DeriveInput}; -#[proc_macro_derive(Initial, attributes(initial))] -pub fn initial(input: TokenStream) -> TokenStream { - initial::initial(input) -} - #[proc_macro_derive(Arguments, attributes(arg, arguments))] pub fn arguments(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); diff --git a/examples/deprecated.rs b/examples/deprecated.rs index ad92a42..3e68ba2 100644 --- a/examples/deprecated.rs +++ b/examples/deprecated.rs @@ -1,4 +1,4 @@ -use uutils_args::{Arguments, Initial, Options}; +use uutils_args::{Arguments, Options}; fn parse_minus(s: &str) -> Option<&str> { let num = s.strip_prefix('-')?; @@ -27,7 +27,7 @@ enum Arg { Plus(isize), } -#[derive(Initial)] +#[derive(Default)] struct Settings { n1: usize, n2: isize, @@ -43,8 +43,8 @@ impl Options for Settings { } fn main() { - assert_eq!(Settings::parse(["test", "-10"]).n1, 10usize); - assert!(Settings::try_parse(["test", "--10"]).is_err()); - assert_eq!(Settings::parse(["test", "+10"]).n2, 10isize); - assert_eq!(Settings::parse(["test", "+-10"]).n2, -10isize); + assert_eq!(Settings::default().parse(["test", "-10"]).n1, 10usize); + assert!(Settings::default().try_parse(["test", "--10"]).is_err()); + assert_eq!(Settings::default().parse(["test", "+10"]).n2, 10isize); + assert_eq!(Settings::default().parse(["test", "+-10"]).n2, -10isize); } diff --git a/examples/hello_world.rs b/examples/hello_world.rs index 5d95993..66137b4 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -1,4 +1,4 @@ -use uutils_args::{Arguments, Initial, Options}; +use uutils_args::{Arguments, Options}; #[derive(Arguments)] #[arguments(file = "examples/hello_world_help.md")] @@ -20,10 +20,8 @@ enum Arg { Hidden, } -#[derive(Initial)] struct Settings { name: String, - #[initial(1)] count: u8, } @@ -38,7 +36,12 @@ impl Options for Settings { } fn main() -> Result<(), uutils_args::Error> { - let settings = Settings::parse(std::env::args_os()); + let settings = Settings { + name: String::new(), + count: 1, + } + .parse(std::env::args_os()); + for _ in 0..settings.count { println!("Hello, {}!", settings.name); } diff --git a/src/lib.rs b/src/lib.rs index 72321c8..c9e2ee0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -160,21 +160,6 @@ impl ArgumentIter { } } -/// An alternative for the [`Default`] trait, with a more feature -/// packed derive macro. -/// -/// The `Initial` trait is used by `Options` to construct the initial -/// state of the options before any arguments are parsed. -/// -/// The [derive macro](derive@Initial) supports setting the initial -/// value per field and parsing the initial values from environment -/// variables. Otherwise, it will be equivalent to the derive macro -/// for the [`Default`] trait. -pub trait Initial: Sized { - /// Create the initial state of `Self` - fn initial() -> Self; -} - /// Defines the app settings by consuming [`Arguments`]. /// /// When implementing this trait, only two things need to be provided: @@ -184,35 +169,34 @@ pub trait Initial: Sized { /// type onto the options. /// /// By default, the [`Options::parse`] method will -/// 1. create a new instance of `Self` using [`Initial::initial`], -/// 2. repeatedly call [`ArgumentIter::next_arg`] and call [`Options::apply`] +/// 1. repeatedly call [`ArgumentIter::next_arg`] and call [`Options::apply`] /// on the result until the arguments are exhausted, -/// 3. and finally call [`Arguments::check_missing`]. -pub trait Options: Sized + Initial { +/// 2. and finally call [`Arguments::check_missing`] to check whether all +/// required arguments were given. +pub trait Options: Sized { /// Apply a single argument to the options. fn apply(&mut self, arg: Arg); - /// Parse an iterator of arguments into - fn parse(args: I) -> Self + /// Parse an iterator of arguments into the options + fn parse(self, args: I) -> Self where I: IntoIterator + 'static, I::Item: Into, { - exit_if_err(Self::try_parse(args), Arg::EXIT_CODE) + exit_if_err(self.try_parse(args), Arg::EXIT_CODE) } - fn try_parse(args: I) -> Result + fn try_parse(mut self, args: I) -> Result where I: IntoIterator + 'static, I::Item: Into, { - let mut _self = Self::initial(); let mut iter = Arg::parse(args); while let Some(arg) = iter.next_arg()? { - _self.apply(arg); + self.apply(arg); } Arg::check_missing(iter.positional_idx)?; - Ok(_self) + Ok(self) } } diff --git a/tests/coreutils/b2sum.rs b/tests/coreutils/b2sum.rs index d32a183..0fcfc81 100644 --- a/tests/coreutils/b2sum.rs +++ b/tests/coreutils/b2sum.rs @@ -1,5 +1,5 @@ use std::path::{Path, PathBuf}; -use uutils_args::{Arguments, Initial, Options}; +use uutils_args::{Arguments, Options}; #[derive(Clone, Arguments)] enum Arg { @@ -39,7 +39,7 @@ enum CheckOutput { Status, } -#[derive(Initial)] +#[derive(Default)] struct Settings { binary: bool, check: bool, @@ -67,48 +67,66 @@ impl Options for Settings { #[test] fn binary() { - assert!(!Settings::parse(["b2sum"]).binary); - assert!(!Settings::parse(["b2sum", "--text"]).binary); - assert!(!Settings::parse(["b2sum", "-t"]).binary); - assert!(!Settings::parse(["b2sum", "--binary", "--text"]).binary); - assert!(!Settings::parse(["b2sum", "-b", "-t"]).binary); + assert!(!Settings::default().parse(["b2sum"]).binary); + assert!(!Settings::default().parse(["b2sum", "--text"]).binary); + assert!(!Settings::default().parse(["b2sum", "-t"]).binary); + assert!( + !Settings::default() + .parse(["b2sum", "--binary", "--text"]) + .binary + ); + assert!(!Settings::default().parse(["b2sum", "-b", "-t"]).binary); - assert!(Settings::parse(["b2sum", "--binary"]).binary); - assert!(Settings::parse(["b2sum", "-b"]).binary); - assert!(Settings::parse(["b2sum", "--text", "--binary"]).binary); - assert!(Settings::parse(["b2sum", "-t", "-b"]).binary); + assert!(Settings::default().parse(["b2sum", "--binary"]).binary); + assert!(Settings::default().parse(["b2sum", "-b"]).binary); + assert!( + Settings::default() + .parse(["b2sum", "--text", "--binary"]) + .binary + ); + assert!(Settings::default().parse(["b2sum", "-t", "-b"]).binary); } #[test] fn check_output() { assert_eq!( - Settings::parse(["b2sum", "--warn"]).check_output, + Settings::default().parse(["b2sum", "--warn"]).check_output, CheckOutput::Warn ); assert_eq!( - Settings::parse(["b2sum", "--quiet"]).check_output, + Settings::default().parse(["b2sum", "--quiet"]).check_output, CheckOutput::Quiet ); assert_eq!( - Settings::parse(["b2sum", "--status"]).check_output, + Settings::default() + .parse(["b2sum", "--status"]) + .check_output, CheckOutput::Status ); assert_eq!( - Settings::parse(["b2sum", "--status", "--warn"]).check_output, + Settings::default() + .parse(["b2sum", "--status", "--warn"]) + .check_output, CheckOutput::Warn ); assert_eq!( - Settings::parse(["b2sum", "--status", "--warn"]).check_output, + Settings::default() + .parse(["b2sum", "--status", "--warn"]) + .check_output, CheckOutput::Warn ); assert_eq!( - Settings::parse(["b2sum", "--warn", "--quiet"]).check_output, + Settings::default() + .parse(["b2sum", "--warn", "--quiet"]) + .check_output, CheckOutput::Quiet ); assert_eq!( - Settings::parse(["b2sum", "--quiet", "--status"]).check_output, + Settings::default() + .parse(["b2sum", "--quiet", "--status"]) + .check_output, CheckOutput::Status ); } @@ -116,7 +134,7 @@ fn check_output() { #[test] fn files() { assert_eq!( - Settings::parse(["b2sum", "foo", "bar"]).files, + Settings::default().parse(["b2sum", "foo", "bar"]).files, vec![Path::new("foo"), Path::new("bar")] ); } diff --git a/tests/coreutils/base32.rs b/tests/coreutils/base32.rs index 6681daf..3ec67ad 100644 --- a/tests/coreutils/base32.rs +++ b/tests/coreutils/base32.rs @@ -1,6 +1,6 @@ use std::path::PathBuf; -use uutils_args::{Arguments, Initial, Options}; +use uutils_args::{Arguments, Options}; #[derive(Clone, Arguments)] enum Arg { @@ -17,15 +17,24 @@ enum Arg { File(PathBuf), } -#[derive(Initial)] struct Settings { decode: bool, ignore_garbage: bool, - #[initial(Some(76))] wrap: Option, file: Option, } +impl Default for Settings { + fn default() -> Self { + Self { + wrap: Some(76), + decode: Default::default(), + ignore_garbage: Default::default(), + file: Default::default(), + } + } +} + impl Options for Settings { fn apply(&mut self, arg: Arg) { match arg { @@ -40,8 +49,14 @@ impl Options for Settings { #[test] fn wrap() { - assert_eq!(Settings::parse(["base32"]).wrap, Some(76)); - assert_eq!(Settings::parse(["base32", "-w0"]).wrap, None); - assert_eq!(Settings::parse(["base32", "-w100"]).wrap, Some(100)); - assert_eq!(Settings::parse(["base32", "--wrap=100"]).wrap, Some(100)); + assert_eq!(Settings::default().parse(["base32"]).wrap, Some(76)); + assert_eq!(Settings::default().parse(["base32", "-w0"]).wrap, None); + assert_eq!( + Settings::default().parse(["base32", "-w100"]).wrap, + Some(100) + ); + assert_eq!( + Settings::default().parse(["base32", "--wrap=100"]).wrap, + Some(100) + ); } diff --git a/tests/coreutils/basename.rs b/tests/coreutils/basename.rs index 404ad60..7ceaa33 100644 --- a/tests/coreutils/basename.rs +++ b/tests/coreutils/basename.rs @@ -1,4 +1,4 @@ -use uutils_args::{Arguments, Initial, Options}; +use uutils_args::{Arguments, Options}; #[derive(Clone, Arguments)] enum Arg { @@ -15,7 +15,7 @@ enum Arg { Names(Vec), } -#[derive(Initial)] +#[derive(Default)] struct Settings { multiple: bool, suffix: String, @@ -38,7 +38,7 @@ impl Options for Settings { } fn parse(args: &'static [&'static str]) -> Settings { - let mut settings = Settings::parse(args); + let mut settings = Settings::default().parse(args); if !settings.multiple { assert_eq!(settings.names.len(), 2); settings.suffix = settings.names.pop().unwrap(); diff --git a/tests/coreutils/cat.rs b/tests/coreutils/cat.rs index 5932f6c..b809b91 100644 --- a/tests/coreutils/cat.rs +++ b/tests/coreutils/cat.rs @@ -1,6 +1,6 @@ use std::path::PathBuf; -use uutils_args::{Arguments, Initial, Options}; +use uutils_args::{Arguments, Options}; #[derive(Default)] enum NumberingMode { @@ -43,7 +43,7 @@ enum Arg { File(PathBuf), } -#[derive(Initial)] +#[derive(Default)] struct Settings { show_tabs: bool, show_ends: bool, @@ -82,27 +82,27 @@ impl Options for Settings { #[test] fn show() { - let s = Settings::parse(["cat", "-v"]); + let s = Settings::default().parse(["cat", "-v"]); assert!(!s.show_ends && !s.show_tabs && s.show_nonprinting); - let s = Settings::parse(["cat", "-E"]); + let s = Settings::default().parse(["cat", "-E"]); assert!(s.show_ends && !s.show_tabs && !s.show_nonprinting); - let s = Settings::parse(["cat", "-T"]); + let s = Settings::default().parse(["cat", "-T"]); assert!(!s.show_ends && s.show_tabs && !s.show_nonprinting); - let s = Settings::parse(["cat", "-e"]); + let s = Settings::default().parse(["cat", "-e"]); assert!(s.show_ends && !s.show_tabs && s.show_nonprinting); - let s = Settings::parse(["cat", "-t"]); + let s = Settings::default().parse(["cat", "-t"]); assert!(!s.show_ends && s.show_tabs && s.show_nonprinting); - let s = Settings::parse(["cat", "-A"]); + let s = Settings::default().parse(["cat", "-A"]); assert!(s.show_ends && s.show_tabs && s.show_nonprinting); - let s = Settings::parse(["cat", "-te"]); + let s = Settings::default().parse(["cat", "-te"]); assert!(s.show_ends && s.show_tabs && s.show_nonprinting); - let s = Settings::parse(["cat", "-vET"]); + let s = Settings::default().parse(["cat", "-vET"]); assert!(s.show_ends && s.show_tabs && s.show_nonprinting); } diff --git a/tests/coreutils/dd.rs b/tests/coreutils/dd.rs index ebac8f0..6d9c28a 100644 --- a/tests/coreutils/dd.rs +++ b/tests/coreutils/dd.rs @@ -1,7 +1,7 @@ // spell-checker:ignore noxfer infile outfile iseek oseek conv iflag oflag iflags oflags use std::path::PathBuf; -use uutils_args::{Arguments, Initial, Options, Value}; +use uutils_args::{Arguments, Options, Value}; #[derive(Value, Debug, PartialEq, Eq)] enum StatusLevel { @@ -56,13 +56,11 @@ enum Arg { Oflag(String), } -#[derive(Initial, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq)] struct Settings { infile: Option, outfile: Option, - #[initial(512)] ibs: usize, - #[initial(512)] obs: usize, skip: u64, seek: u64, @@ -74,6 +72,25 @@ struct Settings { status: Option, } +impl Default for Settings { + fn default() -> Self { + Self { + ibs: 512, + obs: 512, + infile: Default::default(), + outfile: Default::default(), + skip: Default::default(), + seek: Default::default(), + count: Default::default(), + _iconv: Default::default(), + _iflags: Default::default(), + _oconv: Default::default(), + _oflags: Default::default(), + status: Default::default(), + } + } +} + impl Options for Settings { fn apply(&mut self, arg: Arg) { match arg { @@ -99,16 +116,19 @@ impl Options for Settings { #[test] fn empty() { - assert_eq!(Settings::try_parse(["dd"]).unwrap(), Settings::initial()) + assert_eq!( + Settings::default().try_parse(["dd"]).unwrap(), + Settings::default() + ) } #[test] fn infile() { assert_eq!( - Settings::try_parse(["dd", "if=hello"]).unwrap(), + Settings::default().try_parse(["dd", "if=hello"]).unwrap(), Settings { infile: Some(PathBuf::from("hello")), - ..Settings::initial() + ..Settings::default() } ) } @@ -116,10 +136,10 @@ fn infile() { #[test] fn outfile() { assert_eq!( - Settings::try_parse(["dd", "of=hello"]).unwrap(), + Settings::default().try_parse(["dd", "of=hello"]).unwrap(), Settings { outfile: Some(PathBuf::from("hello")), - ..Settings::initial() + ..Settings::default() } ) } @@ -127,35 +147,39 @@ fn outfile() { #[test] fn bs() { assert_eq!( - Settings::try_parse(["dd", "ibs=1"]).unwrap(), + Settings::default().try_parse(["dd", "ibs=1"]).unwrap(), Settings { ibs: 1, obs: 512, - ..Settings::initial() + ..Settings::default() } ); assert_eq!( - Settings::try_parse(["dd", "obs=1"]).unwrap(), + Settings::default().try_parse(["dd", "obs=1"]).unwrap(), Settings { ibs: 512, obs: 1, - ..Settings::initial() + ..Settings::default() } ); assert_eq!( - Settings::try_parse(["dd", "ibs=10", "obs=1"]).unwrap(), + Settings::default() + .try_parse(["dd", "ibs=10", "obs=1"]) + .unwrap(), Settings { ibs: 10, obs: 1, - ..Settings::initial() + ..Settings::default() } ); assert_eq!( - Settings::try_parse(["dd", "ibs=10", "bs=1"]).unwrap(), + Settings::default() + .try_parse(["dd", "ibs=10", "bs=1"]) + .unwrap(), Settings { ibs: 1, obs: 1, - ..Settings::initial() + ..Settings::default() } ) } diff --git a/tests/coreutils/echo.rs b/tests/coreutils/echo.rs index 2cc1753..69f482e 100644 --- a/tests/coreutils/echo.rs +++ b/tests/coreutils/echo.rs @@ -1,5 +1,5 @@ use std::ffi::OsString; -use uutils_args::{Arguments, Initial, Options}; +use uutils_args::{Arguments, Options}; #[derive(Arguments)] #[arguments(parse_echo_style)] @@ -20,7 +20,7 @@ enum Arg { String(Vec), } -#[derive(Initial)] +#[derive(Default)] struct Settings { trailing_newline: bool, escape: bool, @@ -43,16 +43,16 @@ impl Options for Settings { #[test] fn double_hyphen() { - let s = Settings::parse(["echo", "--"]); + let s = Settings::default().parse(["echo", "--"]); assert_eq!(s.strings, vec![OsString::from("--")]); - let s = Settings::parse(["echo", "--", "-n"]); + let s = Settings::default().parse(["echo", "--", "-n"]); assert_eq!(s.strings, vec![OsString::from("--"), OsString::from("-n")]); } #[test] #[ignore] fn nonexistent_options_are_values() { - let s = Settings::parse(["echo", "-f"]); + let s = Settings::default().parse(["echo", "-f"]); assert_eq!(s.strings, vec![OsString::from("-f")]); } diff --git a/tests/coreutils/head.rs b/tests/coreutils/head.rs index abe8ad4..40f3e81 100644 --- a/tests/coreutils/head.rs +++ b/tests/coreutils/head.rs @@ -1,6 +1,6 @@ use std::{ffi::OsString, path::PathBuf}; -use uutils_args::{Arguments, Initial, Options, Value}; +use uutils_args::{Arguments, Options, Value}; // This format is way to specific to implement using a library. Basically, any // deviation should be return `None` to indicate that we're not using the @@ -179,7 +179,7 @@ pub enum Mode { Lines, } -#[derive(Initial)] +#[derive(Default)] struct Settings { mode: Mode, number: SigNum, @@ -215,7 +215,7 @@ where { match parse_deprecated(iter.clone()) { Some(s) => Ok(s), - None => Settings::try_parse(iter), + None => Settings::default().try_parse(iter), } } diff --git a/tests/coreutils/ls.rs b/tests/coreutils/ls.rs index 75f3a9f..4e3e6de 100644 --- a/tests/coreutils/ls.rs +++ b/tests/coreutils/ls.rs @@ -1,5 +1,5 @@ use std::path::PathBuf; -use uutils_args::{Arguments, Initial, Options, Value}; +use uutils_args::{Arguments, Options, Value}; #[derive(Default, Debug, PartialEq, Eq, Value)] enum Format { @@ -302,7 +302,7 @@ fn default_terminal_size() -> u16 { 80 } -#[derive(Initial, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq)] struct Settings { format: Format, files: Vec, @@ -322,20 +322,49 @@ struct Settings { long_numeric_uid_gid: bool, // alloc_size: bool, // block_size: Option, - #[initial(default_terminal_size())] width: u16, quoting_style: QuotingStyle, indicator_style: IndicatorStyle, // time_style: TimeStyle, context: bool, group_directories_first: bool, - #[initial('\n')] eol: char, which_files: Files, ignore_backups: bool, hide_control_chars: bool, } +impl Default for Settings { + fn default() -> Self { + Self { + eol: '\n', + width: default_terminal_size(), + format: Default::default(), + files: Default::default(), + sort: Default::default(), + recursive: Default::default(), + reverse: Default::default(), + dereference: Default::default(), + ignore_patterns: Default::default(), + directory: Default::default(), + time: Default::default(), + inode: Default::default(), + color: Default::default(), + long_author: Default::default(), + long_no_group: Default::default(), + long_no_owner: Default::default(), + long_numeric_uid_gid: Default::default(), + quoting_style: Default::default(), + indicator_style: Default::default(), + context: Default::default(), + group_directories_first: Default::default(), + which_files: Default::default(), + ignore_backups: Default::default(), + hide_control_chars: Default::default(), + } + } +} + impl Options for Settings { fn apply(&mut self, arg: Arg) { match arg { @@ -401,7 +430,7 @@ impl Options for Settings { #[test] fn default() { assert_eq!( - Settings::parse(["ls"]), + Settings::default().parse(["ls"]), Settings { format: Format::Columns, files: Vec::new(), @@ -433,87 +462,87 @@ fn default() { #[test] fn color() { - let s = Settings::parse(["ls", "--color"]); + let s = Settings::default().parse(["ls", "--color"]); assert!(s.color); - let s = Settings::parse(["ls", "--color=always"]); + let s = Settings::default().parse(["ls", "--color=always"]); assert!(s.color); - let s = Settings::parse(["ls", "--color=never"]); + let s = Settings::default().parse(["ls", "--color=never"]); assert!(!s.color); } #[test] fn format() { - let s = Settings::parse(["ls", "-l"]); + let s = Settings::default().parse(["ls", "-l"]); assert_eq!(s.format, Format::Long); - let s = Settings::parse(["ls", "-m"]); + let s = Settings::default().parse(["ls", "-m"]); assert_eq!(s.format, Format::Commas); - let s = Settings::parse(["ls", "--format=across"]); + let s = Settings::default().parse(["ls", "--format=across"]); assert_eq!(s.format, Format::Across); - let s = Settings::parse(["ls", "--format=acr"]); + let s = Settings::default().parse(["ls", "--format=acr"]); assert_eq!(s.format, Format::Across); - let s = Settings::parse(["ls", "-o"]); + let s = Settings::default().parse(["ls", "-o"]); assert_eq!(s.format, Format::Long); assert!(s.long_no_group && !s.long_no_owner && !s.long_numeric_uid_gid); - let s = Settings::parse(["ls", "-g"]); + let s = Settings::default().parse(["ls", "-g"]); assert_eq!(s.format, Format::Long); assert!(!s.long_no_group && s.long_no_owner && !s.long_numeric_uid_gid); - let s = Settings::parse(["ls", "-n"]); + let s = Settings::default().parse(["ls", "-n"]); assert_eq!(s.format, Format::Long); assert!(!s.long_no_group && !s.long_no_owner && s.long_numeric_uid_gid); - let s = Settings::parse(["ls", "-og"]); + let s = Settings::default().parse(["ls", "-og"]); assert_eq!(s.format, Format::Long); assert!(s.long_no_group && s.long_no_owner && !s.long_numeric_uid_gid); - let s = Settings::parse(["ls", "-on"]); + let s = Settings::default().parse(["ls", "-on"]); assert_eq!(s.format, Format::Long); assert!(s.long_no_group && !s.long_no_owner && s.long_numeric_uid_gid); - let s = Settings::parse(["ls", "-onCl"]); + let s = Settings::default().parse(["ls", "-onCl"]); assert_eq!(s.format, Format::Long); assert!(s.long_no_group && !s.long_no_owner && s.long_numeric_uid_gid); } #[test] fn time() { - let s = Settings::parse(["ls", "--time=access"]); + let s = Settings::default().parse(["ls", "--time=access"]); assert_eq!(s.time, Time::Access); - let s = Settings::parse(["ls", "--time=a"]); + let s = Settings::default().parse(["ls", "--time=a"]); assert_eq!(s.time, Time::Access); } #[test] fn classify() { - let s = Settings::parse(["ls", "--indicator-style=classify"]); + let s = Settings::default().parse(["ls", "--indicator-style=classify"]); assert_eq!(s.indicator_style, IndicatorStyle::Classify); - let s = Settings::parse(["ls", "--classify"]); + let s = Settings::default().parse(["ls", "--classify"]); assert_eq!(s.indicator_style, IndicatorStyle::Classify); - let s = Settings::parse(["ls", "--classify=always"]); + let s = Settings::default().parse(["ls", "--classify=always"]); assert_eq!(s.indicator_style, IndicatorStyle::Classify); - let s = Settings::parse(["ls", "--classify=none"]); + let s = Settings::default().parse(["ls", "--classify=none"]); assert_eq!(s.indicator_style, IndicatorStyle::None); - let s = Settings::parse(["ls", "-F"]); + let s = Settings::default().parse(["ls", "-F"]); assert_eq!(s.indicator_style, IndicatorStyle::Classify); } #[test] fn sort() { - let s = Settings::parse(["ls", "--sort=time"]); + let s = Settings::default().parse(["ls", "--sort=time"]); assert_eq!(s.sort, Sort::Time); - let s = Settings::parse(["ls", "-X"]); + let s = Settings::default().parse(["ls", "-X"]); assert_eq!(s.sort, Sort::Extension); } diff --git a/tests/coreutils/mktemp.rs b/tests/coreutils/mktemp.rs index ad18b74..c713eef 100644 --- a/tests/coreutils/mktemp.rs +++ b/tests/coreutils/mktemp.rs @@ -1,6 +1,6 @@ use std::path::{Path, PathBuf}; -use uutils_args::{Arguments, Initial, Options}; +use uutils_args::{Arguments, Options}; #[derive(Clone, Arguments)] enum Arg { @@ -26,7 +26,7 @@ enum Arg { Template(String), } -#[derive(Default, Initial)] +#[derive(Default)] struct Settings { directory: bool, dry_run: bool, @@ -53,35 +53,35 @@ impl Options for Settings { #[test] fn suffix() { - let s = Settings::parse(["mktemp", "--suffix=hello"]); + let s = Settings::default().parse(["mktemp", "--suffix=hello"]); assert_eq!(s.suffix.unwrap(), "hello"); - let s = Settings::parse(["mktemp", "--suffix="]); + let s = Settings::default().parse(["mktemp", "--suffix="]); assert_eq!(s.suffix.unwrap(), ""); - let s = Settings::parse(["mktemp", "--suffix="]); + let s = Settings::default().parse(["mktemp", "--suffix="]); assert_eq!(s.suffix.unwrap(), ""); - let s = Settings::parse(["mktemp"]); + let s = Settings::default().parse(["mktemp"]); assert_eq!(s.suffix, None); } #[test] fn tmpdir() { - let s = Settings::parse(["mktemp", "--tmpdir"]); + let s = Settings::default().parse(["mktemp", "--tmpdir"]); assert_eq!(s.tmp_dir.unwrap(), Path::new(".")); - let s = Settings::parse(["mktemp", "--tmpdir="]); + let s = Settings::default().parse(["mktemp", "--tmpdir="]); assert_eq!(s.tmp_dir.unwrap(), Path::new("")); - let s = Settings::parse(["mktemp", "-p", "foo"]); + let s = Settings::default().parse(["mktemp", "-p", "foo"]); assert_eq!(s.tmp_dir.unwrap(), Path::new("foo")); - let s = Settings::parse(["mktemp", "-pfoo"]); + let s = Settings::default().parse(["mktemp", "-pfoo"]); assert_eq!(s.tmp_dir.unwrap(), Path::new("foo")); - let s = Settings::parse(["mktemp", "-p", ""]); + let s = Settings::default().parse(["mktemp", "-p", ""]); assert_eq!(s.tmp_dir.unwrap(), Path::new("")); - assert!(Settings::try_parse(["mktemp", "-p"]).is_err()); + assert!(Settings::default().try_parse(["mktemp", "-p"]).is_err()); } diff --git a/tests/coreutils/tail.rs b/tests/coreutils/tail.rs index c23ba7b..31cfda9 100644 --- a/tests/coreutils/tail.rs +++ b/tests/coreutils/tail.rs @@ -1,6 +1,6 @@ use std::{ffi::OsString, path::PathBuf}; -use uutils_args::{Arguments, Initial, Options, Value}; +use uutils_args::{Arguments, Options, Value}; // This format is way to specific to implement using a library. Basically, any // deviation should be return `None` to indicate that we're not using the @@ -100,7 +100,7 @@ where mode, follow, inputs: vec![input.into().into()], - ..Settings::initial() + ..Settings::default() }) } @@ -228,7 +228,7 @@ pub enum Mode { Lines, } -#[derive(Initial)] +#[derive(Default)] struct Settings { follow: Option, max_unchanged_stats: u32, @@ -280,7 +280,7 @@ where { match parse_deprecated(iter.clone()) { Some(s) => Ok(s), - None => Settings::try_parse(iter), + None => Settings::default().try_parse(iter), } } diff --git a/tests/coreutils/uniq.rs b/tests/coreutils/uniq.rs index bf94e76..b8eb7e4 100644 --- a/tests/coreutils/uniq.rs +++ b/tests/coreutils/uniq.rs @@ -50,7 +50,7 @@ enum Delimiters { Both, } -#[derive(Initial)] +#[derive(Default)] struct Settings { repeats_only: bool, uniques_only: bool, diff --git a/tests/defaults.rs b/tests/defaults.rs deleted file mode 100644 index 76a6511..0000000 --- a/tests/defaults.rs +++ /dev/null @@ -1,55 +0,0 @@ -use uutils_args::{Arguments, Initial, Options}; - -#[test] -fn true_default() { - #[derive(Arguments)] - enum Arg { - #[arg("--foo")] - Foo, - } - - #[derive(Initial)] - struct Settings { - #[initial(true)] - foo: bool, - } - - impl Options for Settings { - fn apply(&mut self, Arg::Foo: Arg) { - self.foo = false; - } - } - - assert!(Settings::parse(["test"]).foo); - assert!(!Settings::parse(["test", "--foo"]).foo); -} - -#[test] -fn env_var_string() { - #[derive(Arguments)] - enum Arg { - #[arg("--foo=MSG")] - Foo(String), - } - - #[derive(Initial)] - struct Settings { - #[initial(env = "FOO")] - foo: String, - } - - impl Options for Settings { - fn apply(&mut self, Arg::Foo(x): Arg) { - self.foo = x; - } - } - - std::env::set_var("FOO", "one"); - assert_eq!(Settings::parse(["test"]).foo, "one"); - - std::env::set_var("FOO", "two"); - assert_eq!(Settings::parse(["test"]).foo, "two"); - - std::env::remove_var("FOO"); - assert_eq!(Settings::parse(["test"]).foo, ""); -} diff --git a/tests/flags.rs b/tests/flags.rs index 2a6b808..1c4bd64 100644 --- a/tests/flags.rs +++ b/tests/flags.rs @@ -1,4 +1,4 @@ -use uutils_args::{Arguments, Initial, Options}; +use uutils_args::{Arguments, Options}; #[test] fn one_flag() { @@ -8,7 +8,7 @@ fn one_flag() { Foo, } - #[derive(Initial)] + #[derive(Default)] struct Settings { foo: bool, } @@ -21,7 +21,7 @@ fn one_flag() { } } - let settings = Settings::parse(["test", "-f"]); + let settings = Settings::default().parse(["test", "-f"]); assert!(settings.foo); } @@ -35,7 +35,7 @@ fn two_flags() { B, } - #[derive(Initial, PartialEq, Eq, Debug)] + #[derive(Default, PartialEq, Eq, Debug)] struct Settings { a: bool, b: bool, @@ -51,16 +51,19 @@ fn two_flags() { } assert_eq!( - Settings::parse(["test", "-a"]), + Settings::default().parse(["test", "-a"]), Settings { a: true, b: false } ); - assert_eq!(Settings::parse(["test"]), Settings { a: false, b: false }); assert_eq!( - Settings::parse(["test", "-b"]), + Settings::default().parse(["test"]), + Settings { a: false, b: false } + ); + assert_eq!( + Settings::default().parse(["test", "-b"]), Settings { a: false, b: true } ); assert_eq!( - Settings::parse(["test", "-a", "-b"]), + Settings::default().parse(["test", "-a", "-b"]), Settings { a: true, b: true } ); } @@ -73,7 +76,7 @@ fn long_and_short_flag() { Foo, } - #[derive(Initial)] + #[derive(Default)] struct Settings { foo: bool, } @@ -84,9 +87,9 @@ fn long_and_short_flag() { } } - assert!(!Settings::parse(["test"]).foo); - assert!(Settings::parse(["test", "--foo"]).foo); - assert!(Settings::parse(["test", "-f"]).foo); + assert!(!Settings::default().parse(["test"]).foo); + assert!(Settings::default().parse(["test", "--foo"]).foo); + assert!(Settings::default().parse(["test", "-f"]).foo); } #[test] @@ -97,7 +100,7 @@ fn short_alias() { Foo, } - #[derive(Initial)] + #[derive(Default)] struct Settings { foo: bool, } @@ -108,7 +111,7 @@ fn short_alias() { } } - assert!(Settings::parse(["test", "-b"]).foo); + assert!(Settings::default().parse(["test", "-b"]).foo); } #[test] @@ -119,7 +122,7 @@ fn long_alias() { Foo, } - #[derive(Initial)] + #[derive(Default)] struct Settings { foo: bool, } @@ -130,7 +133,7 @@ fn long_alias() { } } - assert!(Settings::parse(["test", "--bar"]).foo); + assert!(Settings::default().parse(["test", "--bar"]).foo); } #[test] @@ -143,7 +146,7 @@ fn short_and_long_alias() { Bar, } - #[derive(Initial, PartialEq, Eq, Debug)] + #[derive(Default, PartialEq, Eq, Debug)] struct Settings { foo: bool, bar: bool, @@ -168,10 +171,10 @@ fn short_and_long_alias() { bar: true, }; - assert_eq!(Settings::parse(["test", "--bar"]), foo_true); - assert_eq!(Settings::parse(["test", "-b"]), foo_true); - assert_eq!(Settings::parse(["test", "--foo"]), bar_true); - assert_eq!(Settings::parse(["test", "-f"]), bar_true); + assert_eq!(Settings::default().parse(["test", "--bar"]), foo_true); + assert_eq!(Settings::default().parse(["test", "-b"]), foo_true); + assert_eq!(Settings::default().parse(["test", "--foo"]), bar_true); + assert_eq!(Settings::default().parse(["test", "-f"]), bar_true); } #[test] @@ -186,7 +189,7 @@ fn xyz_map_to_abc() { Z, } - #[derive(Initial, PartialEq, Eq, Debug)] + #[derive(Default, PartialEq, Eq, Debug)] struct Settings { a: bool, b: bool, @@ -214,7 +217,7 @@ fn xyz_map_to_abc() { } assert_eq!( - Settings::parse(["test", "-x"]), + Settings::default().parse(["test", "-x"]), Settings { a: true, b: true, @@ -223,7 +226,7 @@ fn xyz_map_to_abc() { ); assert_eq!( - Settings::parse(["test", "-y"]), + Settings::default().parse(["test", "-y"]), Settings { a: false, b: true, @@ -232,7 +235,7 @@ fn xyz_map_to_abc() { ); assert_eq!( - Settings::parse(["test", "-xy"]), + Settings::default().parse(["test", "-xy"]), Settings { a: true, b: true, @@ -241,7 +244,7 @@ fn xyz_map_to_abc() { ); assert_eq!( - Settings::parse(["test", "-z"]), + Settings::default().parse(["test", "-z"]), Settings { a: true, b: true, @@ -260,7 +263,7 @@ fn non_rust_ident() { Super, } - #[derive(Initial, PartialEq, Eq, Debug)] + #[derive(Default, PartialEq, Eq, Debug)] struct Settings { a: bool, b: bool, @@ -276,7 +279,7 @@ fn non_rust_ident() { } assert_eq!( - Settings::parse(["test", "--foo-bar", "--super"]), + Settings::default().parse(["test", "--foo-bar", "--super"]), Settings { a: true, b: true } ) } @@ -288,7 +291,7 @@ fn number_flag() { #[arg("-1")] One, } - #[derive(Initial, PartialEq, Eq, Debug)] + #[derive(Default, PartialEq, Eq, Debug)] struct Settings { one: bool, } @@ -299,7 +302,7 @@ fn number_flag() { } } - assert!(Settings::parse(["test", "-1"]).one) + assert!(Settings::default().parse(["test", "-1"]).one) } #[test] @@ -312,7 +315,7 @@ fn false_bool() { B, } - #[derive(Initial)] + #[derive(Default)] struct Settings { foo: bool, } @@ -326,12 +329,12 @@ fn false_bool() { } } - assert!(Settings::parse(["test", "-a"]).foo); - assert!(!Settings::parse(["test", "-b"]).foo); - assert!(!Settings::parse(["test", "-ab"]).foo); - assert!(Settings::parse(["test", "-ba"]).foo); - assert!(!Settings::parse(["test", "-a", "-b"]).foo); - assert!(Settings::parse(["test", "-b", "-a"]).foo); + assert!(Settings::default().parse(["test", "-a"]).foo); + assert!(!Settings::default().parse(["test", "-b"]).foo); + assert!(!Settings::default().parse(["test", "-ab"]).foo); + assert!(Settings::default().parse(["test", "-ba"]).foo); + assert!(!Settings::default().parse(["test", "-a", "-b"]).foo); + assert!(Settings::default().parse(["test", "-b", "-a"]).foo); } #[test] @@ -342,7 +345,7 @@ fn verbosity() { Verbosity, } - #[derive(Initial)] + #[derive(Default)] struct Settings { verbosity: u8, } @@ -353,9 +356,9 @@ fn verbosity() { } } - assert_eq!(Settings::parse(["test", "-v"]).verbosity, 1); - assert_eq!(Settings::parse(["test", "-vv"]).verbosity, 2); - assert_eq!(Settings::parse(["test", "-vvv"]).verbosity, 3); + assert_eq!(Settings::default().parse(["test", "-v"]).verbosity, 1); + assert_eq!(Settings::default().parse(["test", "-vv"]).verbosity, 2); + assert_eq!(Settings::default().parse(["test", "-vvv"]).verbosity, 3); } #[test] @@ -370,7 +373,7 @@ fn infer_long_args() { Author, } - #[derive(Initial)] + #[derive(Default)] struct Settings { all: bool, almost_all: bool, @@ -387,10 +390,10 @@ fn infer_long_args() { } } - assert!(Settings::parse(["test", "--all"]).all); - assert!(Settings::parse(["test", "--alm"]).almost_all); - assert!(Settings::parse(["test", "--au"]).author); - assert!(Settings::try_parse(["test", "--a"]).is_err()); + assert!(Settings::default().parse(["test", "--all"]).all); + assert!(Settings::default().parse(["test", "--alm"]).almost_all); + assert!(Settings::default().parse(["test", "--au"]).author); + assert!(Settings::default().try_parse(["test", "--a"]).is_err()); } #[test] @@ -413,7 +416,7 @@ fn enum_flag() { Baz, } - #[derive(Initial)] + #[derive(Default)] struct Settings { foo: SomeEnum, } @@ -428,7 +431,13 @@ fn enum_flag() { } } - assert_eq!(Settings::parse(["test"]).foo, SomeEnum::Foo); - assert_eq!(Settings::parse(["test", "--bar"]).foo, SomeEnum::Bar); - assert_eq!(Settings::parse(["test", "--baz"]).foo, SomeEnum::Baz,); + assert_eq!(Settings::default().parse(["test"]).foo, SomeEnum::Foo); + assert_eq!( + Settings::default().parse(["test", "--bar"]).foo, + SomeEnum::Bar + ); + assert_eq!( + Settings::default().parse(["test", "--baz"]).foo, + SomeEnum::Baz, + ); } diff --git a/tests/options.rs b/tests/options.rs index ba02512..729a107 100644 --- a/tests/options.rs +++ b/tests/options.rs @@ -1,6 +1,6 @@ use std::ffi::OsStr; -use uutils_args::{Arguments, Initial, Options, Value, ValueResult}; +use uutils_args::{Arguments, Options, Value, ValueResult}; #[test] fn string_option() { @@ -10,7 +10,7 @@ fn string_option() { Message(String), } - #[derive(Initial)] + #[derive(Default)] struct Settings { message: String, } @@ -22,7 +22,9 @@ fn string_option() { } assert_eq!( - Settings::parse(["test", "--message=hello"]).message, + Settings::default() + .parse(["test", "--message=hello"]) + .message, "hello" ); } @@ -46,7 +48,7 @@ fn enum_option() { Format(Format), } - #[derive(Initial)] + #[derive(Default)] struct Settings { format: Format, } @@ -58,12 +60,14 @@ fn enum_option() { } assert_eq!( - Settings::parse(["test", "--format=bar"]).format, + Settings::default().parse(["test", "--format=bar"]).format, Format::Bar ); assert_eq!( - Settings::parse(["test", "--format", "baz"]).format, + Settings::default() + .parse(["test", "--format", "baz"]) + .format, Format::Baz ); } @@ -85,7 +89,7 @@ fn enum_option_with_fields() { Indent(Indent), } - #[derive(Initial)] + #[derive(Default)] struct Settings { indent: Indent, } @@ -97,11 +101,11 @@ fn enum_option_with_fields() { } assert_eq!( - Settings::parse(["test", "-i=thin"]).indent, + Settings::default().parse(["test", "-i=thin"]).indent, Indent::Spaces(4) ); assert_eq!( - Settings::parse(["test", "-i=wide"]).indent, + Settings::default().parse(["test", "-i=wide"]).indent, Indent::Spaces(8) ); } @@ -134,7 +138,7 @@ fn enum_with_complex_from_value() { Indent(Indent), } - #[derive(Initial)] + #[derive(Default)] struct Settings { indent: Indent, } @@ -145,8 +149,14 @@ fn enum_with_complex_from_value() { } } - assert_eq!(Settings::parse(["test", "-i=tabs"]).indent, Indent::Tabs); - assert_eq!(Settings::parse(["test", "-i=4"]).indent, Indent::Spaces(4)); + assert_eq!( + Settings::default().parse(["test", "-i=tabs"]).indent, + Indent::Tabs + ); + assert_eq!( + Settings::default().parse(["test", "-i=4"]).indent, + Indent::Spaces(4) + ); } #[test] @@ -168,9 +178,8 @@ fn color() { Color(Option), } - #[derive(Initial)] + #[derive(Default)] struct Settings { - #[initial(Color::Auto)] color: Color, } @@ -181,20 +190,29 @@ fn color() { } assert_eq!( - Settings::parse(["test", "--color=yes"]).color, + Settings::default().parse(["test", "--color=yes"]).color, Color::Always ); assert_eq!( - Settings::parse(["test", "--color=always"]).color, + Settings::default().parse(["test", "--color=always"]).color, Color::Always ); - assert_eq!(Settings::parse(["test", "--color=no"]).color, Color::Never); assert_eq!( - Settings::parse(["test", "--color=never"]).color, + Settings::default().parse(["test", "--color=no"]).color, Color::Never ); - assert_eq!(Settings::parse(["test", "--color=auto"]).color, Color::Auto); - assert_eq!(Settings::parse(["test", "--color"]).color, Color::Always) + assert_eq!( + Settings::default().parse(["test", "--color=never"]).color, + Color::Never + ); + assert_eq!( + Settings::default().parse(["test", "--color=auto"]).color, + Color::Auto + ); + assert_eq!( + Settings::default().parse(["test", "--color"]).color, + Color::Always + ) } #[test] @@ -209,7 +227,7 @@ fn actions() { Receive, } - #[derive(Initial)] + #[derive(Default)] struct Settings { last_message: String, send: bool, @@ -229,7 +247,7 @@ fn actions() { } } - let settings = Settings::parse(["test", "-m=Hello", "-m=World", "--send"]); + let settings = Settings::default().parse(["test", "-m=Hello", "-m=World", "--send"]); assert_eq!(settings.messages, vec!["Hello", "World"]); assert_eq!(settings.last_message, "World"); assert!(settings.send); @@ -243,7 +261,7 @@ fn width() { Width(u64), } - #[derive(Initial)] + #[derive(Default)] struct Settings { width: Option, } @@ -257,8 +275,8 @@ fn width() { } } - assert_eq!(Settings::parse(["test", "-w=0"]).width, None); - assert_eq!(Settings::parse(["test", "-w=1"]).width, Some(1)); + assert_eq!(Settings::default().parse(["test", "-w=0"]).width, None); + assert_eq!(Settings::default().parse(["test", "-w=1"]).width, Some(1)); } #[test] @@ -287,7 +305,7 @@ fn integers() { I128(i128), } - #[derive(Initial)] + #[derive(Default)] struct Settings { n: i128, } @@ -309,17 +327,17 @@ fn integers() { } } - assert_eq!(Settings::parse(["test", "--u8=5"]).n, 5); - assert_eq!(Settings::parse(["test", "--u16=5"]).n, 5); - assert_eq!(Settings::parse(["test", "--u32=5"]).n, 5); - assert_eq!(Settings::parse(["test", "--u64=5"]).n, 5); - assert_eq!(Settings::parse(["test", "--u128=5"]).n, 5); + assert_eq!(Settings::default().parse(["test", "--u8=5"]).n, 5); + assert_eq!(Settings::default().parse(["test", "--u16=5"]).n, 5); + assert_eq!(Settings::default().parse(["test", "--u32=5"]).n, 5); + assert_eq!(Settings::default().parse(["test", "--u64=5"]).n, 5); + assert_eq!(Settings::default().parse(["test", "--u128=5"]).n, 5); - assert_eq!(Settings::parse(["test", "--i8=5"]).n, 5); - assert_eq!(Settings::parse(["test", "--i16=5"]).n, 5); - assert_eq!(Settings::parse(["test", "--i32=5"]).n, 5); - assert_eq!(Settings::parse(["test", "--i64=5"]).n, 5); - assert_eq!(Settings::parse(["test", "--i128=5"]).n, 5); + assert_eq!(Settings::default().parse(["test", "--i8=5"]).n, 5); + assert_eq!(Settings::default().parse(["test", "--i16=5"]).n, 5); + assert_eq!(Settings::default().parse(["test", "--i32=5"]).n, 5); + assert_eq!(Settings::default().parse(["test", "--i64=5"]).n, 5); + assert_eq!(Settings::default().parse(["test", "--i128=5"]).n, 5); } #[test] @@ -344,7 +362,7 @@ fn ls_classify() { Classify(When), } - #[derive(Initial)] + #[derive(Default)] struct Settings { classify: When, } @@ -355,17 +373,22 @@ fn ls_classify() { } } - assert_eq!(Settings::parse(["test"]).classify, When::Auto); + assert_eq!(Settings::default().parse(["test"]).classify, When::Auto); assert_eq!( - Settings::parse(["test", "--classify=never"]).classify, + Settings::default() + .parse(["test", "--classify=never"]) + .classify, When::Never, ); assert_eq!( - Settings::parse(["test", "--classify"]).classify, + Settings::default().parse(["test", "--classify"]).classify, When::Always, ); - assert_eq!(Settings::parse(["test", "-F"]).classify, When::Always,); - assert!(Settings::try_parse(["test", "-Falways"]).is_err()); + assert_eq!( + Settings::default().parse(["test", "-F"]).classify, + When::Always, + ); + assert!(Settings::default().try_parse(["test", "-Falways"]).is_err()); } #[test] @@ -379,7 +402,7 @@ fn mktemp_tmpdir() { TmpDir(String), } - #[derive(Initial)] + #[derive(Default)] struct Settings { tmpdir: Option, } @@ -390,16 +413,16 @@ fn mktemp_tmpdir() { } } - let settings = Settings::parse(["test", "-p", "X"]); + let settings = Settings::default().parse(["test", "-p", "X"]); assert_eq!(settings.tmpdir.unwrap(), "X"); - let settings = Settings::parse(["test", "--tmpdir=X"]); + let settings = Settings::default().parse(["test", "--tmpdir=X"]); assert_eq!(settings.tmpdir.unwrap(), "X"); - let settings = Settings::parse(["test", "--tmpdir"]); + let settings = Settings::default().parse(["test", "--tmpdir"]); assert_eq!(settings.tmpdir.unwrap(), "/tmp"); - assert!(Settings::try_parse(["test", "-p"]).is_err()); + assert!(Settings::default().try_parse(["test", "-p"]).is_err()); } #[test] @@ -452,7 +475,7 @@ fn deprecated() { Plus(isize), } - #[derive(Initial)] + #[derive(Default)] struct Settings { n1: usize, n2: isize, @@ -467,8 +490,8 @@ fn deprecated() { } } - assert_eq!(Settings::parse(["test", "-10"]).n1, 10usize); - assert!(Settings::try_parse(["test", "--10"]).is_err()); - assert_eq!(Settings::parse(["test", "+10"]).n2, 10isize); - assert_eq!(Settings::parse(["test", "+-10"]).n2, -10isize); + assert_eq!(Settings::default().parse(["test", "-10"]).n1, 10usize); + assert!(Settings::default().try_parse(["test", "--10"]).is_err()); + assert_eq!(Settings::default().parse(["test", "+10"]).n2, 10isize); + assert_eq!(Settings::default().parse(["test", "+-10"]).n2, -10isize); } diff --git a/tests/positionals.rs b/tests/positionals.rs index 04f187c..02eb1d4 100644 --- a/tests/positionals.rs +++ b/tests/positionals.rs @@ -1,4 +1,4 @@ -use uutils_args::{Arguments, Initial, Options}; +use uutils_args::{Arguments, Options}; #[test] fn one_positional() { @@ -8,7 +8,7 @@ fn one_positional() { File1(String), } - #[derive(Initial)] + #[derive(Default)] struct Settings { file1: String, } @@ -19,10 +19,10 @@ fn one_positional() { } } - let settings = Settings::parse(["test", "foo"]); + let settings = Settings::default().parse(["test", "foo"]); assert_eq!(settings.file1, "foo"); - assert!(Settings::try_parse(["test"]).is_err()); + assert!(Settings::default().try_parse(["test"]).is_err()); } #[test] @@ -35,7 +35,7 @@ fn two_positionals() { Bar(String), } - #[derive(Initial)] + #[derive(Default)] struct Settings { foo: String, bar: String, @@ -50,11 +50,11 @@ fn two_positionals() { } } - let settings = Settings::parse(["test", "a", "b"]); + let settings = Settings::default().parse(["test", "a", "b"]); assert_eq!(settings.foo, "a"); assert_eq!(settings.bar, "b"); - assert!(Settings::try_parse(["test"]).is_err()); + assert!(Settings::default().try_parse(["test"]).is_err()); } #[test] @@ -65,7 +65,7 @@ fn optional_positional() { Foo(String), } - #[derive(Initial)] + #[derive(Default)] struct Settings { foo: Option, } @@ -76,9 +76,9 @@ fn optional_positional() { } } - let settings = Settings::parse(["test"]); + let settings = Settings::default().parse(["test"]); assert_eq!(settings.foo, None); - let settings = Settings::parse(["test", "bar"]); + let settings = Settings::default().parse(["test", "bar"]); assert_eq!(settings.foo.unwrap(), "bar"); } @@ -90,7 +90,7 @@ fn collect_positional() { Foo(String), } - #[derive(Initial)] + #[derive(Default)] struct Settings { foo: Vec, } @@ -101,9 +101,9 @@ fn collect_positional() { } } - let settings = Settings::parse(["test", "a", "b", "c"]); + let settings = Settings::default().parse(["test", "a", "b", "c"]); assert_eq!(settings.foo, vec!["a", "b", "c"]); - let settings = Settings::parse(["test"]); + let settings = Settings::default().parse(["test"]); assert_eq!(settings.foo, Vec::::new()); } @@ -115,7 +115,7 @@ fn last1() { Foo(Vec), } - #[derive(Initial)] + #[derive(Default)] struct Settings { foo: Vec, } @@ -126,7 +126,7 @@ fn last1() { } } - let settings = Settings::parse(["test", "a", "-b", "c"]); + let settings = Settings::default().parse(["test", "a", "-b", "c"]); assert_eq!(settings.foo, vec!["a", "-b", "c"]); } @@ -141,7 +141,7 @@ fn last2() { Foo(Vec), } - #[derive(Initial)] + #[derive(Default)] struct Settings { foo: Vec, } @@ -155,9 +155,9 @@ fn last2() { } } - let settings = Settings::parse(["test", "-a"]); + let settings = Settings::default().parse(["test", "-a"]); assert_eq!(settings.foo, Vec::::new()); - let settings = Settings::parse(["test", "--", "-a"]); + let settings = Settings::default().parse(["test", "--", "-a"]); assert_eq!(settings.foo, vec!["-a"]); }