tinystr icon indicating copy to clipboard operation
tinystr copied to clipboard

Recommendation for pattern matching

Open sffc opened this issue 3 years ago • 9 comments

On Rust Nightly, I got the following pattern match to work:

const FOO: TinyStr16 = tinystr16!("foo");
const BAR: TinyStr16 = tinystr16!("bar");
match tinystr_input {
    FOO => /* ... */,
    BAR => /* ... */,
    _ => /* ... */,
}

This is fine, but it would be nicer if I could write

match tinystr_input {
    tinystr16!("foo") => /* ... */,
    tinystr16!("bar") => /* ... */,
    _ => /* ... */,
}

Unfortunately, this doesn't seem to work right now.

Is the first example the best way to do pattern matching on TinyStr, or is there a better way?

sffc avatar Aug 23 '20 08:08 sffc

Deref it and match against string

Manishearth avatar Aug 23 '20 14:08 Manishearth

I would expect a string match to be slower than a TinyStr (primitive int) match. I haven't done benchmarks.

sffc avatar Aug 24 '20 05:08 sffc

oh, good point. Might be worth making a macro for matching then

Manishearth avatar Aug 24 '20 20:08 Manishearth

~4 times faster - https://github.com/zbraniecki/tinystr/wiki/Performance#partialeq

zbraniecki avatar Aug 24 '20 20:08 zbraniecki

I think the compiler has the option to do additional optimization when matches are used, so I don't know if PartialEq tells the whole story. I made a new benchmark to specifically test match statement behavior: #23

I have functions with a 15-leaf match, some with str and some with tinystr. Results for me on my Lenovo X1 Carbon:

String Length Match(&str) Match(tinystr)
4 64.4 ns 35.1 ns
8 58.2 ns 32.0 ns
16 46.7 ns 42.8 ns

So, matching on TinyStr is faster, but not greatly so, especially on TinyStr16.

sffc avatar Aug 26 '20 03:08 sffc

The solution for pattern matching is to just make a bunch of const TinyStrs, and then you can pass them on the left side of a match statement as the pattern. We should document this with an example.

sffc avatar Apr 11 '21 10:04 sffc

I wonder if tinystr16!() can be written as a const fn now that that's stable

if so it's possible TinyStr::new("en") => ... might work (?)

Manishearth avatar Apr 11 '21 16:04 Manishearth

The problem I previously had with that was const functions don't have a great answer for indexing into variable length strings. We could perhaps have a const function that takes [u8, 4], however.

sffc avatar Apr 11 '21 18:04 sffc

if so it's possible TinyStr::new("en") => ... might work (?)

Ah, this is still not allowed. I think a custom match macro is probably your best bet

There is the vesta crate, a new crate that makes it possible to do generic matches. It may be useful, unsure, but really we can just write our own macro.

Manishearth avatar Apr 11 '21 20:04 Manishearth