oxidecomputer / oxidecomputer/typify

Attributes with same name as type cause name conflicts

Open
#801 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Sample JSON schema:

{
    "$defs": {
      "FirstType": {
        "properties": {
          "first": {
            "title": "First",
            "type": "string"
          }
        },
        "required": [
          "first"
        ],
        "title": "FirstType",
        "type": "object"
      },
      "SecondType": {
        "properties": {
          "second": {
            "title": "Second",
            "type": "string"
          }
        },
        "required": [
          "second"
        ],
        "title": "SecondType",
        "type": "object"
      }
    },
    "properties": {
      "test": {
        "anyOf": [
          {
            "$ref": "#/$defs/FirstType"
          },
          {
            "$ref": "#/$defs/SecondType"
          },
          {
            "type": "null"
          }
        ],
        "title": "Test"
      }
    },
    "required": [
      "test"
    ],
    "title": "Test",
    "type": "object"
  }

This is the JSON schema of this simple class structure (sample code in Python):

import json
from pydantic import BaseModel

class FirstType(BaseModel):
    first: str

class SecondType(BaseModel):
    second: str

class Test(BaseModel):
    test: FirstType | SecondType | None

test_json = Test.model_json_schema()

print(json.dumps(test_json, indent=2))

This results in the following generated schema from using typify. I have only included the important parts:

pub struct Test {
    pub test: Test,
}
impl ::std::convert::From<&Test> for Test {
    fn from(value: &Test) -> Self {
        value.clone()
    }
}
impl Test {
    pub fn builder() -> builder::Test {
        Default::default()
    }
}
pub enum Test {
    Variant0(FirstType),
    Variant1(SecondType),
    Variant2,
}
impl ::std::convert::From<&Self> for Test {
    fn from(value: &Test) -> Self {
        value.clone()
    }
}
impl ::std::convert::From<FirstType> for Test {
    fn from(value: FirstType) -> Self {
        Self::Variant0(value)
    }
}
impl ::std::convert::From<SecondType> for Test {
    fn from(value: SecondType) -> Self {
        Self::Variant1(value)
    }
}

Obviously, you can't have an enum and a struct with the same name (enum Test and struct Test).

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

Start by reproducing the issue with the Python Pydantic schema and inspect the code-generation path that produces the shown Rust types. Trace how names are assigned to the generated struct and enum, then add regression coverage for this schema. Done means the generated Rust no longer declares conflicting types and remains valid.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.