oxidecomputer / typify

compiler from JSON Schema into idiomatic Rust types
Apache License 2.0
423 stars 58 forks source link

`schemars` with `preserve_order` feature prevents compilation #553

Closed aryan-mann closed 6 months ago

aryan-mann commented 6 months ago

Hii, thanks a lot for working on typify, super super useful!! I was using Tauri v2 with LanceDB and ran into the following issue.

If you use set the preserve_order feature on in the schemars library; typify-impl fails to compile. Seems like it's due to some functions expecting BTree's but schemars switches Map to IndexMap over here @ schemars/src/lib.rs

Tauri v2 has preserve_order enabled for schemars which prevents using any package that depends on typify (like LanceDB)

Minimal Reproduction

  1. Create new project
  2. Add typify = "0.0.16"
  3. Add schemars = { version = "0.8.16", features = ["preserve_order"] } to Cargo.toml
  4. Try cargo build
Full Compilation Error

   Compiling typify-impl v0.0.16
error[E0308]: mismatched types
    --> /Users/ari/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typify-impl-0.0.16/src/convert.rs:1238:47
     |
1238 |         if all_mutually_exclusive(subschemas, &self.definitions) {
     |            ----------------------             ^^^^^^^^^^^^^^^^^ expected `&IndexMap<..., ...>`, found `&BTreeMap<..., ...>`
     |            |
     |            arguments to this function are incorrect
     |
     = note: expected reference `&indexmap::map::IndexMap`
                found reference `&BTreeMap`
note: function defined here
    --> /Users/ari/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typify-impl-0.0.16/src/util.rs:45:15
     |
45   | pub(crate) fn all_mutually_exclusive(
     |               ^^^^^^^^^^^^^^^^^^^^^^
46   |     subschemas: &[Schema],
47   |     definitions: &schemars::Map,
     |     -------------------------------------------

error[E0599]: no method named `first_key_value` found for reference `&indexmap::map::IndexMap` in the current scope
   --> /Users/ari/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typify-impl-0.0.16/src/enums.rs:173:69
    |
173 | ...rop_type) = properties.first_key_value().unwrap();
    |                           ^^^^^^^^^^^^^^^ help: there is a method with a similar name: `get_key_value`

error[E0308]: arguments to this function are incorrect
    --> /Users/ari/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typify-impl-0.0.16/src/merge.rs:1216:20
     |
1216 |                 && roughly_properties(&aa.properties, &bb.properties)
     |                    ^^^^^^^^^^^^^^^^^^
     |
note: expected `&BTreeMap<..., ...>`, found `&IndexMap<..., ...>`
    --> /Users/ari/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typify-impl-0.0.16/src/merge.rs:1216:39
     |
1216 |                 && roughly_properties(&aa.properties, &bb.properties)
     |                                       ^^^^^^^^^^^^^^
     = note: expected reference `&BTreeMap`
                found reference `&indexmap::map::IndexMap`
note: expected `&BTreeMap<..., ...>`, found `&IndexMap<..., ...>`
    --> /Users/ari/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typify-impl-0.0.16/src/merge.rs:1216:55
     |
1216 |                 && roughly_properties(&aa.properties, &bb.properties)
     |                                                       ^^^^^^^^^^^^^^
     = note: expected reference `&BTreeMap`
                found reference `&indexmap::map::IndexMap`
note: function defined here
    --> /Users/ari/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typify-impl-0.0.16/src/merge.rs:1227:4
     |
1227 | fn roughly_properties(a: &BTreeMap, b: &BTreeMap) -...
     |    ^^^^^^^^^^^^^^^^^^ ----------------------------  ----------------------------

error[E0308]: arguments to this function are incorrect
    --> /Users/ari/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typify-impl-0.0.16/src/merge.rs:1217:20
     |
1217 | ...   && roughly_properties(&aa.pattern_properties, &bb.pattern_properties)
     |          ^^^^^^^^^^^^^^^^^^
     |
note: expected `&BTreeMap<..., ...>`, found `&IndexMap<..., ...>`
    --> /Users/ari/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typify-impl-0.0.16/src/merge.rs:1217:39
     |
1217 | ...   && roughly_properties(&aa.pattern_properties, &bb.pattern_properties)
     |                             ^^^^^^^^^^^^^^^^^^^^^^
     = note: expected reference `&BTreeMap`
                found reference `&indexmap::map::IndexMap`
note: expected `&BTreeMap<..., ...>`, found `&IndexMap<..., ...>`
    --> /Users/ari/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typify-impl-0.0.16/src/merge.rs:1217:63
     |
1217 | ...&aa.pattern_properties, &bb.pattern_properties)
     |                            ^^^^^^^^^^^^^^^^^^^^^^
     = note: expected reference `&BTreeMap`
                found reference `&indexmap::map::IndexMap`
note: function defined here
    --> /Users/ari/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typify-impl-0.0.16/src/merge.rs:1227:4
     |
1227 | fn roughly_properties(a: &BTreeMap, b: &BTreeMap) -...
     |    ^^^^^^^^^^^^^^^^^^ ----------------------------  ----------------------------

error[E0599]: the method `get` exists for reference `&IndexMap`, but its trait bounds were not satisfied
   --> /Users/ari/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typify-impl-0.0.16/src/util.rs:556:27
    |
556 |         }) => definitions.get(&ref_key(ref_name)).unwrap(),
    |                           ^^^ method cannot be called on `&IndexMap` due to unsatisfied trait bounds
    |
   ::: /Users/ari/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typify-impl-0.0.16/src/lib.rs:176:1
    |
176 | pub(crate) enum RefKey {
    | ---------------------- doesn't satisfy `RefKey: Hash`
    |
    = note: the following trait bounds were not satisfied:
            `RefKey: Hash`
help: consider annotating `RefKey` with `#[derive(Hash)]`
   --> /Users/ari/.cargo/registry/src/index.crates.io-6f17d22bba15001f/typify-impl-0.0.16/src/lib.rs:176:1
    |
176 + #[derive(Hash)]
177 | pub(crate) enum RefKey {
    |

Some errors have detailed explanations: E0308, E0599.
For more information about an error, try `rustc --explain E0308`.
error: could not compile `typify-impl` (lib) due to 5 previous errors

ahl commented 6 months ago

Thanks for this; should be a pretty straightforward fix to properly use schemars::Map. If you're interested in picking this up please let me know.

ahl commented 6 months ago

Fixed by https://github.com/oxidecomputer/typify/commit/31ec4c504cb82582c65b97509b45bbc568247910