Skip to content

Commit 3cfdc41

Browse files
committed
docs: update README and CHANGELOG with all fork improvements
README.md: - Update AnyOf section: now generates untagged enums (not broken flattened structs) - Add If/Then/Else section - Add Not schema section - Add JSON Schema 2020-12 Support section with keyword mapping table - Add External References section with API examples - Remove "Bounded numbers" from WIP (now fixed) CHANGELOG.adoc: - Add comprehensive unreleased section covering all 19 issues fixed - Document all new features: 2020-12 support, external refs, if/then/else, new APIs
1 parent ba4ffb1 commit 3cfdc41

2 files changed

Lines changed: 80 additions & 23 deletions

File tree

CHANGELOG.adoc

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,30 @@
1111

1212
// cargo-release: next header goes here (do not change this line)
1313

14-
== Unreleased changes (release date TBD)
15-
16-
https://github.com/oxidecomputer/typify/compare/v0.6.1\...HEAD[Full list of commits]
14+
== Unreleased changes (barbacane-dev fork)
15+
16+
=== Bug fixes
17+
* fix untagged enum variant ordering: Integer now comes before Number to prevent unreachable deserialization (#991)
18+
* generate `Default` impl for structs where all required fields have explicit defaults (#918)
19+
* generate `TryFrom` instead of `From` for bounded integer newtypes, enforcing min/max constraints (#986)
20+
* render integer `minimum`/`maximum` as integers (not floats) in doc comments (#843)
21+
* handle special characters in enum variant names (`=`, `>`, `≥`, etc.) without panicking (#948)
22+
* replace broken `anyOf` flattened struct with proper untagged enum generation (#414, #895, #710, #790)
23+
* replace `patternProperties` and `propertyNames` assertion panics with best-effort behavior (#882)
24+
* select smallest integer type for bounded ranges (e.g., `[1..32]` → `NonZeroU8`) (#975)
25+
* replace panics in `not` schema handling with graceful fallback to `serde_json::Value` (#954, #489, #435)
26+
* replace panics in `ref_key()` and `convert_reference()` with proper error returns
27+
28+
=== New features
29+
* JSON Schema `if`/`then`/`else` support via transformation to `oneOf` (#480)
30+
* JSON Schema 2020-12 and 2019-09 support via automatic normalization (#579)
31+
** `$defs`, `prefixItems`, `dependentRequired`, `dependentSchemas`, `unevaluatedProperties`, `$dynamicRef`
32+
* external `$ref` support: reference schemas in other files (#201, #933)
33+
* non-`$defs` internal `$ref` support: reference any JSON Pointer path (#828)
34+
* new API: `TypeSpace::add_schema_from_value()` — auto-detects and normalizes any JSON Schema draft
35+
* new API: `TypeSpace::add_schema_with_externals()` — handles multi-file schema bundles
36+
37+
https://github.com/barbacane-dev/typify/compare/v0.6.1\...HEAD[Full list of commits]
1738

1839
== 0.6.1 (released 2026-02-10)
1940

README.md

Lines changed: 56 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,11 @@ this generation is an area of active work.
9393

9494
### AnyOf
9595

96-
The `anyOf` construct is much trickier. If can be close to an `enum` (`oneOf`),
97-
but where no particular variant might be canonical or unique for particular
98-
data. While today we (imprecisely) model these as structs with optional,
99-
flattened members, this is one of the weaker areas of code generation.
100-
101-
Issues describing example schemas and desired output are welcome and helpful.
96+
The `anyOf` construct maps to a Rust `#[serde(untagged)]` enum, similar to
97+
`oneOf`. Typify runs the same enum detection pipeline (external, internal,
98+
adjacent, untagged tagging) for `anyOf` schemas. This correctly handles
99+
`anyOf` with primitive types (strings, integers), mixed object/primitive
100+
schemas, and overlapping object properties.
102101

103102
### AdditionalProperties
104103

@@ -123,6 +122,57 @@ named properties **and** a flattened map of additional properties by using a
123122
value for `additionalProperties` that is equivalent to `true` or absent with
124123
regard to validation, by using some e.g. `{}`.
125124

125+
### If / Then / Else
126+
127+
JSON Schema's `if`/`then`/`else` construct is transformed into a `oneOf`:
128+
the `then` branch becomes `allOf(if, then)` and the `else` branch becomes
129+
`allOf(not(if), else)`. The result is a Rust enum with variants for each
130+
branch.
131+
132+
### Not
133+
134+
The `not` construct is supported for schemas with enumerated values (creating
135+
a "deny list" newtype that rejects those values). For more complex `not`
136+
schemas (e.g., `not: { type: "object" }`), typify falls back to
137+
`serde_json::Value`.
138+
139+
### JSON Schema 2020-12 Support
140+
141+
Typify supports JSON Schema 2020-12 (and 2019-09) via automatic
142+
normalization. When a schema declares `"$schema":
143+
"https://json-schema.org/draft/2020-12/schema"`, the following keywords are
144+
transparently converted to their draft-07 equivalents before processing:
145+
146+
| 2020-12 keyword | Transformed to |
147+
|-----------------|---------------|
148+
| `$defs` | `definitions` |
149+
| `prefixItems` + `items` | `items` (array) + `additionalItems` |
150+
| `$ref` alongside other keywords | `allOf` wrapping |
151+
| `dependentRequired` | `dependencies` (array form) |
152+
| `dependentSchemas` | `dependencies` (schema form) |
153+
| `unevaluatedProperties` | `additionalProperties` (best-effort) |
154+
| `$dynamicRef` | `$ref` (best-effort) |
155+
156+
Use `add_schema_from_value()` instead of `add_root_schema()` to enable
157+
auto-detection and normalization.
158+
159+
### External References
160+
161+
Typify supports `$ref` pointing to external files (e.g.,
162+
`"$ref": "other-file.json#/definitions/Foo"`). External schemas are bundled
163+
into the root schema's definitions before processing.
164+
165+
Use `add_schema_with_externals()` to provide a map of external schemas:
166+
167+
```rust
168+
let mut externals = BTreeMap::new();
169+
externals.insert("types.json".to_string(), types_json_value);
170+
type_space.add_schema_with_externals(main_schema_value, externals)?;
171+
```
172+
173+
Non-standard internal references (e.g., `$ref: "#/properties/foo"`) are also
174+
automatically resolved.
175+
126176
## Rust -> Schema -> Rust
127177

128178
Schemas derived from Rust types may include an extension that provides
@@ -337,20 +387,6 @@ JSON schema can express a wide variety of types. Some of them are easy to model
337387
in Rust; others aren't. There's a lot of work to be done to handle esoteric
338388
types. Examples from users are very helpful in this regard.
339389

340-
### Bounded numbers
341-
342-
Bounded numbers aren't very well handled. Consider, for example, the schema:
343-
344-
```json
345-
{
346-
"type": "integer",
347-
"minimum": 1,
348-
"maximum": 6
349-
}
350-
```
351-
352-
The resulting types won't enforce those value constraints.
353-
354390
### Configurable dependencies
355391

356392
A string schema with `format` set to `uuid` will result in the `uuid::Uuid`

0 commit comments

Comments
 (0)