oxidecomputer / oxidecomputer/typify

patternProperties?

Open
#522 3 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

Hello:

Cool project! I started implementing it into a sort of repo-management-type software I'm working on. However, typify didn't quite do what I expected, and looking into it, doesn't seem to support JSON Schema's patternProperties. I'm using YAML, where for example, I have a file like this:

variables:
  BRANCH_GROUP_A: main
  BRANCH_GROUP_B: feature/beta
  SOMETHINGELSE: "123"
repos:
  thing:
    branch: hotfix/BUG-1234
    commit: HEAD
  some-code:
    branch: ${BRANCH_GROUP_A}
    commit: HEAD
  doesnt-matter:
    branch: ${BRANCH_GROUP_A}
    commit: 7f9329dc0741a4eeea209497f4e03513454e7606
  meta-star:
    branch: ${BRANCH_GROUP_B}
    commit: da9063bdfbe130f424ba487f167da68e0ce90e7d

I could argue for the repos section to convert that to a list instead of an object and add an extra "name: xyz" field, but that just adds more boilerplate, but variables definitely doesn't make much sense to do anything other than the current format.

So the JSON schema looks like this:

{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "https://example.com/snapshot.json",
    "title": "snapshot",
    "description": "Schema for SNAPSHOT",
    "type": "object",
    "properties": {
        "variables": {
            "type": "object",
            "patternProperties": {
                "^[A-Z_]+$": {
                    "$comment": "Variable names uppercase and underscores only, value any string",
                    "type": "string"
                }
            },
            "additionalProperties": false,
            "minProperties": 1,
            "uniqueItems": true
        },
        "repos": {
            "type": "object",
            "patternProperties": {
                "^[a-z_-]+$": {
                    "$comment": "Repo names lowercase only, object types",
                    "type": "object",
                    "properties": {
                        "branch": { "type": "string" },
                        "commit": { "type": "string" }
                    },
                    "required": ["branch", "commit"]
                }
            },
            "additionalProperties": false,
            "minProperties": 1,
            "uniqueItems": true
        }
    },
    "required": ["repos"],
    "additionalProperties": false
}

I integrated typify with build.rs, but get the same results with cargo typify ./snapshot.json, small example (which I believe is correct?):

let str_snapshot_content = std::fs::read_to_string("./test_snapshot.yaml").unwrap();
let test = serde_yaml::from_str::<snapshot::Snapshot>(&str_snapshot_content).unwrap();

And panicking at the second line, as I now expect, since it doesn't know what to look for:

thread 'main' panicked at src/main.rs:68:72:
called `Result::unwrap()` on an `Err` value: Error("variables: unknown field `BRANCH_GROUP_A`, there are no fields", line: 2, column: 3)

Also, various unused variable warnings in the generated code file:

warning: unused variable: `value`
   --> <snip>/out/gen_schema_types.rs:254:17
    |
254 |                 value: SnapshotRepos,
    |                 ^^^^^ help: if this is intentional, prefix it with an underscore: `_value`
    |
    = note: `#[warn(unused_variables)]` on by default

Anyway, I didn't see an existing issue for this, so figured I'd open one! Thanks!

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 by reproducing the failure with snapshot.json, build.rs, src/main.rs, and test_snapshot.yaml, then inspect the generated out/gen_schema_types.rs around the reported warning. Trace how patternProperties is represented for variables and repos and how serde_yaml deserializes the generated types. Done means the example deserializes successfully and the reported unused-variable warnings are addressed.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.