Skip to content
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

Take positional arguments out of arguments enum #72

Merged
merged 1 commit into from
Dec 19, 2023

Conversation

tertsdiepraam
Copy link
Member

@tertsdiepraam tertsdiepraam commented Dec 14, 2023

Closes #70

This is a big change in how positional arguments are handled in this library.

This implements the third option in #70. This means that positional arguments are no longer declared in the Arguments enum, but are returned separately from the parse method. This allows utils to implement their own handling. This flexibility is necessary and the result is usually not much more verbose than current implementations. What's left to future PRs is to explore how this can become even more convenient.

Here's something that's not possible with the behaviour on main (ignoring some error handling):

// cp
let (s, files) = Settings::default().parse(args_os());

let (sources, destination) = if s.no_target_directory {
    // TODO: assert that there are two files and return them
} else if let Some(dest) = s.target_directory {
    (files, dest)
} else {
    // TODO make proper error
    let dest = files.pop().unwrap();
    (files, dest)
}

Before

#[derive(Arguments)]
enum Arg {
   #[arg("-a")]
   Foo,
   #[arg("FILES", ..)]
   Files,
}

#[derive(Default)]
struct Settings {
   foo: bool,
   files: Vec<PathBuf>,
}

impl Options<Arg> for Settings {
   fn apply(&mut self, arg: Arg) {
       match self {
           Arg::Foo => self.foo = true,
           Arg::Files(f) => self.files = f,
       }
   }
}

fn main() {
    let s = Settings::default().parse(args_os());
    println!("{:?}", s.files);
}

After

#[derive(Arguments)]
enum Arg {
   #[arg("-a")]
   Foo,
}

struct Settings {
   foo: bool,
}

impl Options<Arg> for Settings {
   fn apply(&mut self, arg: Arg) {
       match self {
           Arg::Foo => self.foo = true,
       }
   }
}

fn main() {
    let (s, files) = Settings::default().parse(args_os());
    println!("{:?}", files);
}

@tertsdiepraam tertsdiepraam marked this pull request as ready for review December 14, 2023 12:10
@tertsdiepraam tertsdiepraam force-pushed the positional-redo branch 2 times, most recently from 60a6370 to ecce4c0 Compare December 16, 2023 10:33
@tertsdiepraam tertsdiepraam merged commit b1cb263 into uutils:main Dec 19, 2023
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Positional arguments redo
1 participant