oxidecomputer / oxidecomputer/typify

Extending type with patternProperties panics

Open
#882 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
898
Forks
114
Avg merge
4h 18m
Merged PRs (30d)
14

Description

I have a jsonschema that extends a type in $defs with patternProperties. It seems to be valid spec according to the jsonschema schema but trying to run in typify panics when it hits the "assert until we hit some examples in the wild" case.

The full schema is this one but a reduced example is

{
  "type": "object",
  "title": "demo",
  "$defs": {
    "Foo": {
      "type": "object",
      "properties": {
        "names": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "additionalProperties": true
    }
  },
  "properties": {
    "foos": {
      "patternProperties": {
        "^([^.]+)$": {
            "type": "string"
        }
      },
      "additionalProperties": false,
      "$ref": "#/$defs/Foo"
    }
  },
  "additionalProperties": false
}

Trying to generate rust types for this:

$ cargo typify demo.json 
The application panicked (crashed).
Message:  assertion failed: object_schema.pattern_properties.is_empty()
Location: /home/tpoliaw/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/typify-impl-0.4.3/src/merge.rs:1097

Backtrace omitted. Run with RUST_BACKTRACE=1 environment variable to display it.
Run with RUST_BACKTRACE=full to include source snippets.
The full backtrace:
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BACKTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                                ⋮ 7 frames hidden ⋮
   8: core::panicking::panic::h239804395728b21f
      at :
   9: typify_impl::merge::filter_prop::hcfcdca93086e2696
      at :
  10: core::ops::function::impls:: for &mut F>::call_mut::h65948c7c0444d08e
      at :
  11:  as core::iter::traits::iterator::Iterator>::try_fold::hace7ef08575e7b49
      at :
  12:  as alloc::vec::spec_from_iter::SpecFromIter>::from_iter::h7ea76529691f2a38
      at :
  13:  as core::iter::traits::collect::FromIterator<(K,V)>>::from_iter::h6c46cd13dbb1211f
      at :
  14: typify_impl::merge::merge_schema_object::h9489b2a77ecfa96f
      at :
  15: typify_impl::merge::try_merge_schema::hbc00f95ac2fd915b
      at :
  16: typify_impl::merge::try_merge_all::h4089b26e8429459d
      at :
  17: typify_impl::convert::::convert_schema_object::hd95336249f11be54
      at :
  18: typify_impl::convert::::convert_schema::h35f032f73776c3d1
      at :
  19: typify_impl::TypeSpace::id_for_schema::h9cfb5165927b154b
      at :
  20: typify_impl::structs::::struct_property::hf2ed4fd4ca71910d
      at :
  21: core::ops::function::impls:: for &mut F>::call_mut::hbb4ca9ea98a63834
      at :
  22:  as core::iter::traits::iterator::Iterator>::try_fold::h3dbbd5aade776e21
      at :
  23:  as alloc::vec::spec_from_iter::SpecFromIter>::from_iter::h650f7eeb960e78a3
      at :
  24: core::iter::adapters::try_process::hb44e15d357358101
      at :
  25: typify_impl::structs::::struct_members::h84819872195b99b8
      at :
  26: typify_impl::convert::::convert_object::h4647703ca96f3e93
      at :
  27: typify_impl::convert::::convert_schema_object::hd95336249f11be54
      at :
  28: typify_impl::convert::::convert_schema::h35f032f73776c3d1
      at :
  29: typify_impl::TypeSpace::convert_ref_type::h86911b0457188e5e
      at :
  30: typify_impl::TypeSpace::add_root_schema::hf55ea7f22c393dbf
      at :
  31: cargo_typify::convert::h42de6a2580ca5755
      at :
  32: cargo_typify::main::h7c7d68ad279a602e
      at :
  33: std::sys::backtrace::__rust_begin_short_backtrace::h794250a6be559321
      at :
  34: std::rt::lang_start::{{closure}}::h5a7c07a612017b6b
      at :
  35: std::rt::lang_start_internal::h31bbb7f936fd6b5d
      at :
  36: main
      at :
  37: __libc_start_main
      at :
  38: _start
      at :

Run with COLORBT_SHOW_HIDDEN=1 environment variable to disable frame filtering.
Run with RUST_BACKTRACE=full to include source snippets.

I'm not sure what the generate type should look like, possibly something like

struct DemoFoo {
    names: Vec<String>,
    #[serde(flatten)]
    pattern_properties: HashMap<DemoFooKey, String>,
}

where DemoFooKey uses the same approach as other uses of patternProperties with a regex in the deserialisation method.

Would this be something that is feasible to support?

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the reduced schema and run cargo typify demo.json to reproduce the panic, then read typify-impl/src/merge.rs around lines 1093-1097 and the related merge and conversion paths. Determine the intended generated representation for the $ref plus patternProperties case, and verify that generation no longer panics with a regression test covering the reduced example.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.