Skip to content

Conversation

quentinmit
Copy link

I found this useful in a parser situation, where I needed to control the serialization of the generated enum.

@jasta
Copy link

jasta commented Jan 12, 2023

More generally, we could just support passing along custom discriminant values as added in Rust 1.66 (see https://blog.rust-lang.org/2022/12/15/Rust-1.66.0.html#explicit-discriminants-on-enums-with-fields), such that:

#[derive(EnumKind)]
#[enum_kind(MessageKind)]
#[repr(u8)]
enum Message {
  A(usize) = 1,
  B { s: String } = 2,
  C = 3,
}

Would yield:

#[repr(u8)]
enum MessageKind {
  A = 1,
  B = 2,
  C = 3,
}

Which enables us to write idiomatic parser logic:

pub fn parse(message_type: u8, payload: &[u8]) -> Option<Message> {
  match message_type {
    t if t == MessageKind::A as u8 => { ... },
    t if t == MessageKind::B as u8 => { ... },
    t if t == MessageKind::C as u8 => { ... },
    _ => None,
  }
}

We could of course go further with enum-kinds and add a convenience method to map the discriminant back so we could drop all that t if t == ... business and the assumption of the u8 type. Something like MessageKind::try_from(discriminant: u8) -> Option<MessageKind> maybe. For now I'm implementing this manually without enum-kinds and using num_derive::FromPrimitive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants