Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failed generation on enum struct with same property name #99

Open
bdeneux opened this issue Jul 2, 2024 · 0 comments
Open

Failed generation on enum struct with same property name #99

bdeneux opened this issue Jul 2, 2024 · 0 comments

Comments

@bdeneux
Copy link
Contributor

bdeneux commented Jul 2, 2024

Following a comment on my last PR (#98), I've encountered an issue when generating schema types from our smart contract JSON schema.

To illustrate the problem, consider the following Rust code snippet:

/// # Value
#[cw_serde]
#[serde(tag = "type")]
pub enum Value {
    /// # String
    String { value: String },
    /// # Number
    Number { value: i64 },
}
**Whole JSON Schema for example**

{
  "contract_name": "nested-enum-same-name",
  "contract_version": "0.0.1",
  "idl_version": "1.0.0",
  "instantiate": {
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "InstantiateMsg",
    "description": "Instantiate message",
    "type": "object",
    "additionalProperties": false
  },
  "execute": {
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "ExecuteMsg",
    "description": "Execute messages",
    "oneOf": [
      {
        "title": "Foo",
        "type": "object",
        "required": [
          "foo"
        ],
        "properties": {
          "foo": {
            "type": "object",
            "required": [
              "value"
            ],
            "properties": {
              "value": {
                "$ref": "#/definitions/Value"
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      }
    ],
    "definitions": {
      "Value": {
        "title": "Value",
        "oneOf": [
          {
            "title": "String",
            "type": "object",
            "required": [
              "type",
              "value"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "string"
                ]
              },
              "value": {
                "type": "string"
              }
            },
            "additionalProperties": false
          },
          {
            "title": "Number",
            "type": "object",
            "required": [
              "type",
              "value"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "number"
                ]
              },
              "value": {
                "type": "integer",
                "format": "int64"
              }
            },
            "additionalProperties": false
          }
        ]
      }
    }
  },
  "query": {
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "QueryMsg",
    "description": "Query messages",
    "oneOf": [
      {
        "title": "Bar",
        "type": "object",
        "required": [
          "bar"
        ],
        "properties": {
          "bar": {
            "type": "object",
            "required": [
              "foo"
            ],
            "properties": {
              "foo": {
                "type": "string"
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      }
    ]
  },
  "migrate": null,
  "sudo": null,
  "responses": {
    "bar": {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "title": "BarResponse",
      "type": "object",
      "required": [
        "foo"
      ],
      "properties": {
        "foo": {
          "description": "The foo value",
          "type": "string"
        }
      },
      "additionalProperties": false
    }
  },
  "description": "# nested-enum-same-same",
  "title": "nested-enum-same-same"
}

Internally tagged enum

In this code, we're using the serde tag #[serde(tag="type")] to transform the representation of our enum into an internally tagged format, as described in the serde documentation. This results in a generated JSON schema with an enum Type that can take string or number as a value.

Here's a snippet of the generated JSON schema:

<...>
       {
            "title": "String",
           <...>
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "string"
                ]
              },
              "value": {
                "type": "string"
              }
            },
          },
          {
            "title": "Number",
          <...>
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "number"
                ]
              },
              "value": {
                "type": "integer",
                "format": "int64"
              }
            },
          }

I've created a branch on a fork that includes a fix for merging multiple enums with the same name in the definition registry. This situation arises here because the possible values of the Type enum are defined in each definition of the Value enum. You can find the fix in this commit: d210cad.

Struct enum with same attribute name

Another issue arises because each enumeration struct variant contains a value property with a different type. When generating code with go-codegen, this leads to the following error:

duplicate definition `Value_Value` with differing implementations: different types [string] != [integer]

The issue arises due to a conflict in the type registration of Value_Value in the definition registry. Initially, Value_Value was registered as a string type. However, an attempt to register it again as an integer type has led to this problem.

For a more comprehensive understanding of the issue, you can refer to the original JSON schema that triggered this problem. It is available here. The corresponding representation in the Rust contract can be found here.

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

No branches or pull requests

1 participant