[rust-dev] Pattern matching on std::os::args()

2014-04-20 Thread richo

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()

2014-04-20 Thread Geoffroy Couprie
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()

2014-04-20 Thread richo

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