oxidecomputer / typify

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

Panic in `all_mutually_exclusive` -> `resolve` (circleci config schema) #679

Open vpoverennov opened 1 week ago

vpoverennov commented 1 week ago

Hitting a panic in all_mutually_exclusive -> resolve util.rs:566

not yet implemented
stack backtrace:

   3: typify_impl::util::resolve
             at typify-impl\src\util.rs:566
   4: typify_impl::util::all_mutually_exclusive::closure$1

  20: typify_impl::util::all_mutually_exclusive
             at typify-impl\src\util.rs:51
  21: typify_impl::TypeSpace::convert_any_of
             at typify-impl\src\convert.rs:1397
  22: typify_impl::TypeSpace::convert_schema_object
             at typify-impl\src\convert.rs:498
  23: typify_impl::TypeSpace::convert_schema
             at typify-impl\src\convert.rs:37
  24: typify_impl::TypeSpace::convert_ref_type
             at typify-impl\src\lib.rs:594
  25: typify_impl::TypeSpace::add_ref_types_impl<alloc::vec::Vec<tuple$<enum2$<typify_impl::RefKey>,enum2$<schemars::schema::Schema> >,alloc::alloc::Global> >
             at typify-impl\src\lib.rs:565
  26: typify_impl::TypeSpace::add_root_schema

minimal repro:

{
  "definitions": {
    "a": {
      "description": "a"
    },
    "b": {
      "anyOf": [
        {
          "$ref": "#/definitions/a",
          "enum": ["A"]
        },
        {
          "$ref": "#/definitions/a",
          "enum": ["B"]
        }
      ]
    }
  }
}

extracted minimal repro from circleci json schema (src)

ahl commented 1 day ago

First: 100% this is a bug in typify.

We've seen this sort of construction in a few other JSON schema (e.g. #299) and OpenAPI documents (a bit like https://github.com/oxidecomputer/progenitor/issues/591). Rather than having a flat list of definitions, this schema groups them into categories:

$ pbpaste | jq '.definitions.builtinSteps | keys'
[
  "configuration",
  "documentation"
]
$ pbpaste | jq '.definitions.builtinSteps.configuration | keys'
[
  "add_ssh_keys",
  "attach_workspace",
  "checkout",
  "deploy",
  "persist_to_workspace",
  "restore_cache",
  "run",
  "save_cache",
  "setup_remote_docker",
  "store_artifacts",
  "store_test_results",
  "unless",
  "when"
]
$ pbpaste | jq '.definitions.builtinSteps.documentation | keys'
[
  "add_ssh_keys",
  "attach_workspace",
  "checkout",
  "deploy",
  "persist_to_workspace",
  "restore_cache",
  "run",
  "save_cache",
  "setup_remote_docker",
  "store_artifacts",
  "store_test_results",
  "unless",
  "when"
]

Unforunately there isn't a simple workaround; see #579.