-
Notifications
You must be signed in to change notification settings - Fork 5
Description
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.