Skip to content

A more ergonomic enumeration representation #276

@sfackler

Description

@sfackler

To deal with the "openness" of Protobuf enumeration types, Prost currently represents them in the message struct as i32 and generates a Rust enum that can convert to and from i32. This is a bit awkward to work with, though.

A better approach could be to use a newtype with associated constants. To use the Syntax enum as an example, it would look like this:

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ...)]
pub struct Syntax(i32);

impl Syntax {
    pub const PROTO2: Syntax = Syntax(0);
    pub const PROTO3: Syntax = Syntax(1);

    // alternatively the field could just be public
    pub fn from_raw(raw: i32) -> Syntax {
        Syntax(raw)
    }

    pub fn as_raw(self) -> i32 {
        self.0
    }
}

This approach has a couple of advantages:

  • It can be embedded directly in the message struct.
  • It's more type safe since you normally won't have to interact with the raw i32 value.
  • You can still use it roughly like a Rust enum, and do things like match on the variants:
match syntax {
    Syntax::PROTO2 => { ... }
    Syntax::PROTO3 => { ... }
    syntax => panic!("unknown syntax variant {}", syntax.as_raw()),
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions