oxidecomputer / oxidecomputer/typify

Specifying default value for an object should use object's existing default field values

Open
#662 1 comment 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

Let's say I have the following object definition in my schema:

"SeparatorConfig": {
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "lineThickness": {
      "type": "integer",
      "default": 1
    },
    "lineColor": {
      "type": [
        "string",
        "null"
      ],
      "default": "#B2000000"
    }
  }
},

So SeparatorConfig has two properties, both of which have default values.

Elsewhere in another object I have a field of type SeparatorConfig, and I'd like to make the entire field optional such that it defaults to an object with the correct default field values as defined above.

I could in theory do the following:

"separator": {
  "$ref": "#/definitions/SeparatorConfig",
  "default": {}
},

However the resulting generated code which produces this default value is:

super::SeparatorConfig {
  line_color: Default::default(),
  line_thickness: Default::default(),
}

Which produces:

{
  "line_color": null,
  "line_thickness": 0
}

Rather than the desired default:

{
  "line_color": "#B2000000",
  "line_thickness": 1
}

A better implementation for creating the default SeparatorConfig struct would be to use the existing builders you already generate:

builder::SeparatorConfig::default().try_into().expect("default should be valid")

We would also have to use the builder functions for defaults which specify only some properties:

"separator": {
  "$ref": "#/definitions/SeparatorConfig",
  "default": { "lineThickness": 5 }
},

Could produce:

builder::SeparatorConfig::default()
  .line_thickness(5_i64)
  .try_into()
  .expect("default should be valid")

rather than the current:

super::SeparatorConfig {
  line_color: Default::default(),
  line_thickness: 5_i64,
}

Overall this would make specifying default values for objects throughout a schema significantly easier.

The current alternatives are to either specify all the default field values at every level, duplicating a lot of default values (error prone), or not specifying defaults in the schema and manually constructing default structs in code when properties are None (cumbersome).

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 tracing the generated Rust for object defaults and the existing builder generation and conversion paths. Compare empty and partially specified defaults with the SeparatorConfig examples; done means nested field defaults are preserved and explicitly supplied properties override them while generated values remain valid.

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
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.