Brandon Piña
Brandon Piña

Reputation: 893

How to define custom char type that accepts a subset of the normal charset

I'm trying to define a custom type of char that only accepts values from A-Z. Right now i'm just using a plain char in my type:

struct Rotor {
    cipher: &'static str,
    notch: &'static [char],
    position: char, // Only valid values are A-Z
}

And here's a method that is invoked periodically on this struct

fn rotate(&mut self) {
        match self.position /* E0004 on this line */ { 
            'A'..='Y' => self.position = (self.position as u8 + 1) as char,
            'Z' => self.position = 'A',
        }
    }

the match statement in my rotate method is giving me compiler error E0004: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms

If I could have a custom char type that only had values A-Z possible that would eliminate this error. I've considered using the following pattern: const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ"; but I can't figure out how to get that to work with the struct definition

I know that if I just added a catch-all _ arm to this match statement it wouldn't be the end of the world but I would much prefer to not have to do that

Upvotes: 1

Views: 312

Answers (1)

Chayim Friedman
Chayim Friedman

Reputation: 71380

Rust does not support ranged integers (at least currently) and thus you cannot define your own character type and have the compiler enforce exhaustiveness with it. You have to use a wildcard. By the way, you can use the smaller and more efficient u8 if you only need A-Z.

You can use a newtype wrapper and have the constructor enforcing the validity of the value. This will not help with match, but will help to prevent bugs.

Upvotes: 3

Related Questions