oxidecomputer / oxidecomputer/typify
Non-required property with a `default` is not an `Option`
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 898
- Forks
- 114
- Avg merge
- 4h 18m
- Merged PRs (30d)
- 14
Description
Given
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Data Package",
"type": "object",
"properties": {
"encoding": {
"propertyOrder": 100,
"type": "string",
"default": "utf-8"
}
}
}
cargo-typify 0.0.13 outputs (among other items) this struct def:
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct DataPackage {
#[serde(default = "defaults::data_package_encoding")]
pub encoding: String,
}
Checking the README I saw the note:
Properties that are not in the
requiredset are typically represented as anOption<T>with the#[serde(default)]attribute applied. Non-required properties with types that already have a default value (such as aVec<T>) simply get the#[serde(default)]attribute (so you won't see e.g.Option<Vec<T>>).
My hunch is that the thinking was "During deserialization, such a struct field will surely be Some<T>, so just type it as T". That makes sense if one is only deserializing; OTOH it makes it impossible to manually instantiate a certain class of conforming struct: one which, when serialized, would lack the encoding property. I see two workarounds for myself:
- Specify a value for the
encodingfield, e.g., whatever the generateddefaults::data_package_encodingfunction returns. Consumers of the JSON documents I'm creating may infer that value anyway, given thedefaultin the JSON Schema. - Remove the
defaultfrom the schema I'm inputting into typify
In my particular situation I've sought to create JSON documents that lack this property since it happens to be somewhat misleading/a bad fit for my use case. But since consumers of my JSON might infer a value anyway, maybe I should just not claim that my JSON conforms to this schema. I'll probably do that no matter what.
Seems like two potential goals are in tension: Being able to construct any valid instance, vs. having deserialized structs be maximally ergonomic. If the former's more important to you, might it make sense to drop the special-casing of "non-required properties with defaults", and treat their typing the same as other non-required properties?
(caveat: This is my second week seriously writing Rust so thank you for your patience if I got anything wrong in this or other issues!)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the cargo-typify generation path and compare its output for a non-required property with a default against the README guidance and the JSON Schema example. Define whether generated types must represent both presence and omission, then add regression coverage for the resulting serialization and deserialization behavior.
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
- Mostly clear
- Newbie friendliness
- 32/100