oxidecomputer / oxidecomputer/typify

How to rename enum variants?

Open
#749 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
898
Forks
114
Avg merge
4h 18m
Merged PRs (30d)
14

Description

Hey,

I tried to use typify to create types from my json schema. Currently, I'm creating my types via build.rs.

Here you see the result, which is created:

///xx
///
/// <details><summary>JSON schema</summary>
///
/// ```json
///{
///  "description": "xx",
///  "type": "string",
///  "enum": [
///    "=",
///    "!=",
///    "in",
///    "out",
///    "<",
///    ">",
///    "<=",
///    ">=",
///    "contains"
///  ],
///  "example": "="
///}
/// ```
/// </details>
#[derive(
    ::serde::Deserialize,
    ::serde::Serialize,
    Clone,
    Copy,
    Debug,
    Eq,
    Hash,
    Ord,
    PartialEq,
    PartialOrd
)]
pub enum Operator {
    #[serde(rename = "=")]
    X,
    #[serde(rename = "!=")]
    X,
    #[serde(rename = "in")]
    In,
    #[serde(rename = "out")]
    Out,
    #[serde(rename = "<")]
    X,
    #[serde(rename = ">")]
    X,
    #[serde(rename = "<=")]
    X,
    #[serde(rename = ">=")]
    X,
    #[serde(rename = "contains")]
    Contains,
}

As you see, my enum (which I sadly cannot change) has values like "=", "!=" etc., which are invalid rust identifier. Therefor, typify will replace it with an capital X. The issue is now, that my enum have multiple variants which called X. Therefor, the following won't work as designed and by build fails:

impl ::std::fmt::Display
for CrmDiscountCustomerConditionsSelectionsItemConditionsItemOperator {
    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        match *self {
            Self::X => write!(f, "="),
            Self::X => write!(f, "!="),
            Self::In => write!(f, "in"),
            Self::Out => write!(f, "out"),
            Self::X => write!(f, "<"),
            Self::X => write!(f, ">"),
            Self::X => write!(f, "<="),
            Self::X => write!(f, ">="),
            Self::Contains => write!(f, "contains"),
        }
    }
}

How can I rename my enum variants? I tired the following:

    let mut settings = TypeSpaceSettings::default();
    settings.with_derive(String::from("PartialEq"));
    settings.with_derive(String::from("Debug"));
    settings.with_derive(String::from("Clone"));
    settings.with_patch(
        "Operator::=",
        TypeSpacePatch::default().with_rename("OperatorEq".to_owned()),
    );

    let mut type_space = TypeSpace::new(&settings);
    type_space.add_root_schema(schema).unwrap();

    let output = prettyplease::unparse(&syn::parse2::<syn::File>(type_space.to_stream()).unwrap());

    let mut out_file = std::path::Path::new(&out_dir).to_path_buf();
    out_file.push("schema.rs");
    std::fs::write(out_file, output).unwrap();

Thanks!

see: https://github.com/oxidecomputer/typify/blob/6ba620b76767a3ca64da9584144d3fce2a419a50/typify-impl/src/util.rs#L756

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read typify-impl/src/util.rs around line 756 and the build.rs settings using TypeSpacePatch::with_rename. Reproduce the schema generation shown in the issue; done means the generated Operator enum has unique valid Rust variant names and the project builds.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.