oxidecomputer / typify

compiler from JSON Schema into idiomatic Rust types
Apache License 2.0
401 stars 57 forks source link

Duplicate definitions for types not handled #638

Open wucke13 opened 1 month ago

wucke13 commented 1 month ago

Overview:

I have a big schema (https://www.omg.org/spec/SysML/20230201/SysML.json) that seems to refine types a lot, causing quite some warnings by typify. Please note that the schema uses https references to itself, so for it to work with this crate I processed it a little, changing all https $refs into local $refs. Find the edited json file attached below.

Cause:

The cause is code like this:

        #[serde(rename = "@type")]
        type_: String,
        #[serde(rename = "type")]
        type_: Vec<Identified>,

Error:

This yields the following three errors (in many many instances):

     --> /work/sysml-v2-sql/target/debug/build/sysml-v2-sql-fe9e4667a4b133c5/out/codegen.rs:13108:9
      |
13108 |         type_: Vec<Identified>,
      |         ^^^^^ used in a pattern more than once
error[E0124]: field `type_` is already declared
    --> /work/sysml-v2-sql/target/debug/build/sysml-v2-sql-fe9e4667a4b133c5/out/codegen.rs:1315:5
     |
1313 |     pub type_: String,
     |     ----------------- `type_` first declared here
1314 |     #[serde(rename = "type")]
1315 |     pub type_: Vec<Identified>,
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ field already declared
error[E0592]: duplicate definitions with name `type_`
      --> /work/sysml-v2-sql/target/debug/build/sysml-v2-sql-fe9e4667a4b133c5/out/codegen.rs:182906:9
       |
182894 | /         pub fn type_<T>(mut self, value: T) -> Self
182895 | |         where
182896 | |             T: std::convert::TryInto<String>,
182897 | |             T::Error: std::fmt::Display,
       | |________________________________________- other definition for `type_`
...
182906 | /         pub fn type_<T>(mut self, value: T) -> Self
182907 | |         where
182908 | |             T: std::convert::TryInto<Vec<super::Identified>>,
182909 | |             T::Error: std::fmt::Display,
       | |________________________________________^ duplicate definitions for `type_`

Files for reproduction:

use std::{env, fs, path::Path};

use typify::{TypeSpace, TypeSpaceSettings};

fn main() {
    let content = std::fs::read_to_string("SysML-processed.json").unwrap();
    let schema = serde_json::from_str::<schemars::schema::RootSchema>(&content).unwrap();

    let mut type_space = TypeSpace::new(TypeSpaceSettings::default().with_struct_builder(true));
    type_space.add_root_schema(schema).unwrap();

    let contents = format!(
        "{}\n{}",
        "use serde::{Deserialize, Serialize};",
        prettyplease::unparse(&syn::parse2::<syn::File>(type_space.to_stream()).unwrap())
    );

    let mut out_file = Path::new(&env::var("OUT_DIR").unwrap()).to_path_buf();
    out_file.push("codegen.rs");
    fs::write(out_file, contents).unwrap();
}