[rust-dev] Pattern matching on std::os::args()
o/ Rustlers, So, as an indirect result of the absence of pattern matching on unique vectors, I'm having a lot of trouble writing a sane CLI interface based on the results of os::args() The full code in a more readable format is available at here[1] So what I really want is something like: let args = os::args(); match args.as_slice() { [] = unreachable!(), [ref argv0] = println!(Called as: {}, argv0), [ref argv0, foo, ref argv2] = println!(Matched on foo), [ref argv0, bar, ref argv2] = println!(Matched on bar), [ref argv0, ref argv1, ref argv2] = println!(Called as: {} with: {}, {}, argv0, argv1, argv2), _ = fail!(OHSHI-), } Basically, I'm interested in matching my CLI on some subcommands, with a variable number of arguments. I got this *really close* to working with something closer to: let args = os::args(); match args.as_slice() { [] = unreachable!(), [ref argv0] = println!(Called as: {}, argv0), [ref argv0, ref argv1] = println!(Called as: {} with: {}, argv0, argv1), [ref argv0, ref argv1, ref argv2] = { println!(Called as: {} with: {}, {}, argv0, argv1, argv2); match argv1 { foo = println!(Matched on foo), bar = println!(Matched on bar), _ = println!(No match on `argv1`) } }, _ = fail!(OHSHI-), } But this still gets very upset because of trying to match a ~str against a 'static str My resulting two questions are: While I understand the virtues of memory/type safety, it seems that (naively) for the purposes of a string comparison to pattern match on, matching a string literal against a string variable that's in scope should more or less Just Work from the user perspective, I'm not asking for this to be solved at the language level, despite how nice that would be for people just picking this up, in the short term my assumption is that I'll wind up pulling this out into a module or library, how *should* I be attempting to do something like this? Is it actually supported? I've been working on rust-http over the last few days and I understand enough to see how I could build out macros to do what I want, but it seems like a lot of error prone indirection that isn't strictly necessary. Cheers richo [1]: https://gist.github.com/richo/11104624 -- richo pgpX_ZpS0foBt.pgp Description: PGP signature ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Pattern matching on std::os::args()
Hi, I encountered the same problem, and I wound up writing a library to solve it (instead of working on my original code): https://github.com/Geal/typedopts The basic idea is to define a Decoder that can work on command line options. Then you just need to add #[deriving(Decodable)] to a structure that represents your command line options, and the matching will be safe and easy. I chose to make the Decoder work on the results of getopts, but it is possible to work directly on os::args. There is another library that does the same thing here: https://github.com/wycats/hammer.rs On Sun, Apr 20, 2014 at 9:13 AM, richo ri...@psych0tik.net wrote: o/ Rustlers, So, as an indirect result of the absence of pattern matching on unique vectors, I'm having a lot of trouble writing a sane CLI interface based on the results of os::args() The full code in a more readable format is available at here[1] So what I really want is something like: let args = os::args(); match args.as_slice() { [] = unreachable!(), [ref argv0] = println!(Called as: {}, argv0), [ref argv0, foo, ref argv2] = println!(Matched on foo), [ref argv0, bar, ref argv2] = println!(Matched on bar), [ref argv0, ref argv1, ref argv2] = println!(Called as: {} with: {}, {}, argv0, argv1, argv2), _ = fail!(OHSHI-), } Basically, I'm interested in matching my CLI on some subcommands, with a variable number of arguments. I got this *really close* to working with something closer to: let args = os::args(); match args.as_slice() { [] = unreachable!(), [ref argv0] = println!(Called as: {}, argv0), [ref argv0, ref argv1] = println!(Called as: {} with: {}, argv0, argv1), [ref argv0, ref argv1, ref argv2] = { println!(Called as: {} with: {}, {}, argv0, argv1, argv2); match argv1 { foo = println!(Matched on foo), bar = println!(Matched on bar), _ = println!(No match on `argv1`) } }, _ = fail!(OHSHI-), } But this still gets very upset because of trying to match a ~str against a 'static str My resulting two questions are: While I understand the virtues of memory/type safety, it seems that (naively) for the purposes of a string comparison to pattern match on, matching a string literal against a string variable that's in scope should more or less Just Work from the user perspective, I'm not asking for this to be solved at the language level, despite how nice that would be for people just picking this up, in the short term my assumption is that I'll wind up pulling this out into a module or library, how *should* I be attempting to do something like this? Is it actually supported? I've been working on rust-http over the last few days and I understand enough to see how I could build out macros to do what I want, but it seems like a lot of error prone indirection that isn't strictly necessary. Cheers richo [1]: https://gist.github.com/richo/11104624 -- richo ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev Cheers, Geoffroy ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Pattern matching on std::os::args()
On 20/04/14 10:44 +0200, Geoffroy Couprie wrote: Hi, I encountered the same problem, and I wound up writing a library to solve it (instead of working on my original code): https://github.com/Geal/typedopts The basic idea is to define a Decoder that can work on command line options. Then you just need to add #[deriving(Decodable)] to a structure that represents your command line options, and the matching will be safe and easy. I chose to make the Decoder work on the results of getopts, but it is possible to work directly on os::args. There is another library that does the same thing here: https://github.com/wycats/hammer.rs Cheers, Geoffroy Thanks for the tips! So neither seems to solve my issue at face value. I'm just going through and fixing some ~[T] and ~str - StrBuf issues in hammer at the moment so I can play with it (PR incoming, if you're subbed wycats). My underlying issue is a bit more Why can't I do this totally plausible looking thing, albeit wrapped strongly in the Pattern matching on args is a generally useful thing context. I'll fiddle with both of these and see if I can get them to work for me. Thanks again! pgpW9JuQuD6xd.pgp Description: PGP signature ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev