How to implement a range pattern for custom types?

Hello,
Using range pattern of primitive types like numbers and char in a match's arm is available by default. How do I construct a range pattern of a custom type and use it with start..=end in a match's arm like with the primitive types? e.g. for below struct. Thanks.

struct Person { name: String, age: u8, male: bool }

For std::ops::RangeInclusive to implement the std::iter::Iterator trait, you'd have to implement std::iter::Step for your struct, which is currently still nightly.

2 Likes

Thank you, I am not mentioning only about the RangeInclusive case, what I mean is how to implement the overall range pattern for that notional struct Person. Thanks.

This applies to all range operators you can iterate. The very least your struct has to fulfil in order for you to be able to construct a range from it is to implement PartialOrd.

Range patterns are not an extensible feature in Rust at the moment; as far as I’m aware not even with experimental features. They only support char and number types (I’d assume that means all the sizes of i… and u… types, and floats.)

See also: E0029 - Error codes index

What you get in return is that range patterns get full compiler support for exhaustive checking etc.

Regarding your concrete example… it’s not quite clear for me what a range for a Person struct should even mean.

But …say… if you want to match the age of a person against a range, you could still do that manually like

match person {
    Person { age: 12..=18, .. } => …,
    _ => …,
}

If you want more concise patterns, in principle macros could also help, e.g.

macro_rules! person_age {
    ($a:pat) => { Person { age: $a, .. } }
}

though the power of pattern is ultimately limited without guards. Good news: there’s an accepted RFC to add guards to patterns! With that, macros in patterns can become much more powerful, too.

4 Likes

Thank you. I just wondering if range pattern can be applied to any other data type other than its default number & character. I tried to find out whether it can be but not success. The Person is just a hypothetical user-defined type to ease the conversation.