How to refine parsing of associated value in enum variant?

I'm using parse_display to handle both Display and FromStr for an enum. One of the enum variants, F(u8), represents function keys and I want to ensure the value is between 1 and 12 inclusive. I'm using #[display("f{0}")] for display formatting, but when parsing, I want to validate that the integer following "f" is in the correct range. Here's a snippet of my enum for context:

#[derive(Hash, Eq, PartialEq, From, Clone, Debug, Display, FromStr)]
#[display(style = "lowercase")]
enum KeyCode {
    // ... other variants ...
    #[display("f{0}")]
    F(u8),
    // ... other variants ...
}

How can I do this? It would be cool if I could just pass a lambda/closure to the macro that returns true or false (or a specific error) and that would be evaluated when parsing, and if it returns false then the parsing would fail.

I thought about the concept of "refinement types" from something like F*, that would work great here, but I'm not sure if refinement types are supported in Rust (through some crate).

Thanks for the help!

Having only skimmed the docs, it looks like the crate offers two solutions:

  1. #[from_str(regex = "1[12]|[1-9]")]
  2. #from_str(new = "...")], and specify a constructor function that returns Result.
1 Like

Nice solutions!
For the regex, do you mean 1[0-2]|[1-9], or how does your solution match 10? (Sorry if this is a dumb question, not that experienced with regex)

Yeah, my mistake, of course 0 needs to be there.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.