Skip to content

Commit

Permalink
impl(generator): Rust uses strings for enum values (#88)
Browse files Browse the repository at this point in the history
We decided to use strings for enum values, as the transport will be HTTP +
JSON. The generator creates some helper constants in a properly named module,
that prevents typos.
  • Loading branch information
coryan authored Nov 4, 2024
1 parent 202bdf6 commit c462bc5
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 21 deletions.
14 changes: 6 additions & 8 deletions generator/internal/genclient/language/internal/rust/rust.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,16 +163,14 @@ func (c *Codec) FQEnumName(e *genclient.Enum, _ *genclient.APIState) string {
return c.messageScopeName(e.Parent) + "::" + c.ToPascal(e.Name)
}

func (c *Codec) EnumValueName(e *genclient.EnumValue, state *genclient.APIState) string {
if e.Parent.Parent != nil {
return c.MessageName(e.Parent.Parent, state) + "_" + strcase.ToCamel(e.Name)
}
return c.ToPascal(e.Name)
func (c *Codec) EnumValueName(e *genclient.EnumValue, _ *genclient.APIState) string {
// The Protobuf naming convention is to use SCREAMING_SNAKE_CASE, we do not
// need to change anything for Rust
return EscapeKeyword(e.Name)
}

func (c *Codec) FQEnumValueName(v *genclient.EnumValue, _ *genclient.APIState) string {
// TODO(#76) - these will be `const` strings and therefore should be SNAKE_UPPERCASE.
return c.enumScopeName(v.Parent) + "::" + c.ToSnake(v.Name)
func (c *Codec) FQEnumValueName(v *genclient.EnumValue, state *genclient.APIState) string {
return fmt.Sprintf("%s::%s::%s", c.enumScopeName(v.Parent), c.ToSnake(v.Parent.Name), c.EnumValueName(v, state))
}

func (c *Codec) BodyAccessor(m *genclient.Method, state *genclient.APIState) string {
Expand Down
4 changes: 4 additions & 0 deletions generator/internal/genclient/templatedata.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,10 @@ func (e *enum) Name() string {
return e.c.EnumName(e.s, e.state)
}

func (e *enum) NameSnakeCase() string {
return e.c.ToSnake(e.c.EnumName(e.s, e.state))
}

func (e *enum) DocLines() []string {
ss := strings.Split(e.s.Documentation, "\n")
for i := range ss {
Expand Down
13 changes: 8 additions & 5 deletions generator/templates/rust/enum.mustache
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@

{{#DocLines}}
/// {{{.}}}
{{/DocLines}}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct {{Name}}(i32);
pub struct {{Name}}(String);

impl {{Name}} {
/// Useful constants to work with [{{Name}}]({{Name}})
pub mod {{NameSnakeCase}} {
{{#Values}}

{{#DocLines}}
/// {{{.}}}
{{/DocLines}}
pub const {{Name}}: {{EnumType}} = {{EnumType}}({{Number}});
pub const {{Name}}: &str = "{{Name}}";
{{/Values}}
}
}
20 changes: 12 additions & 8 deletions generator/testdata/rust/gclient/golden/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,31 +174,35 @@ pub struct SecretVersion {

/// Defines additional types related to SecretVersion
pub mod secret_version {

/// The state of a
/// [SecretVersion][google.cloud.secretmanager.v1.SecretVersion], indicating if
/// it can be accessed.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct State(i32);
pub struct State(String);

impl State {
/// Useful constants to work with [State](State)
pub mod state {

/// Not specified. This value is unused and invalid.
pub const SecretVersion_StateUnspecified: State = State(0);
pub const STATE_UNSPECIFIED: &str = "STATE_UNSPECIFIED";

/// The [SecretVersion][google.cloud.secretmanager.v1.SecretVersion] may be
/// accessed.
pub const SecretVersion_Enabled: State = State(1);
pub const ENABLED: &str = "ENABLED";

/// The [SecretVersion][google.cloud.secretmanager.v1.SecretVersion] may not
/// be accessed, but the secret data is still available and can be placed
/// back into the
/// [ENABLED][google.cloud.secretmanager.v1.SecretVersion.State.ENABLED]
/// state.
pub const SecretVersion_Disabled: State = State(2);
pub const DISABLED: &str = "DISABLED";

/// The [SecretVersion][google.cloud.secretmanager.v1.SecretVersion] is
/// destroyed and the secret data is no longer stored. A version may not
/// leave this state once entered.
pub const SecretVersion_Destroyed: State = State(3);
}}
pub const DESTROYED: &str = "DESTROYED";
}
}

/// A policy that defines the replication and encryption configuration of data.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
Expand Down

0 comments on commit c462bc5

Please sign in to comment.