You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs(rust): add OpenAPI spec links and cross-language comparison
- Added links to OpenAPI 3.1.0 spec for oneOf/anyOf definitions
- Added links to JSON Schema documentation
- Added comprehensive comparison of how different languages handle oneOf/anyOf
- Documented how Java, TypeScript, Python, Go, and C# handle these constructs
- Explained how each language deals with untagged union deserialization
- Added comparison table showing implementation approaches
Key findings:
- Most languages handle oneOf/anyOf at runtime with custom deserializers
- TypeScript uses native union types for both (no semantic difference)
- Only Rust and Python truly differentiate anyOf (OR) from oneOf (XOR)
- Java uses AbstractOpenApiSchema with TypeAdapters for both
- All implementations try types in order for untagged unions
Copy file name to clipboardExpand all lines: docs/rust-oneof-anyof-semantics.md
+59Lines changed: 59 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,6 +7,15 @@ The Rust OpenAPI generator properly implements the semantic differences between
7
7
-**oneOf (XOR)**: Exactly one of the schemas must validate
8
8
-**anyOf (OR)**: One or more of the schemas must validate
9
9
10
+
### OpenAPI Specification References
11
+
12
+
From the [OpenAPI 3.1.0 Specification](https://spec.openapis.org/oas/v3.1.0#schema-object):
13
+
14
+
-**[oneOf](https://spec.openapis.org/oas/v3.1.0#composition-and-inheritance-polymorphism)**: "Validates the value against exactly one of the subschemas"
15
+
-**[anyOf](https://spec.openapis.org/oas/v3.1.0#composition-and-inheritance-polymorphism)**: "Validates the value against any (one or more) of the subschemas"
16
+
17
+
These keywords come from [JSON Schema](https://json-schema.org/understanding-json-schema/reference/combining.html) and maintain the same semantics.
18
+
10
19
## Implementation Details
11
20
12
21
### oneOf - Untagged Enums
@@ -162,6 +171,56 @@ pub enum ShapeOneOf {
162
171
}
163
172
```
164
173
174
+
## How Other Languages Handle oneOf/anyOf
175
+
176
+
### Java (with Gson)
177
+
-**oneOf**: Uses `AbstractOpenApiSchema` base class with custom type adapters
178
+
-**anyOf**: Similar to oneOf but allows multiple matches in validation
179
+
-**Approach**: Runtime type checking with reflection, tries to deserialize into each type
180
+
-**Untagged Issue**: Handled via custom `TypeAdapter` that attempts each type sequentially
181
+
182
+
### TypeScript
183
+
-**oneOf**: Simple union types using `|` operator (e.g., `string | number | Person`)
184
+
-**anyOf**: Same as oneOf - TypeScript union types
185
+
-**Approach**: Type unions are natural in TypeScript, runtime validation depends on library
186
+
-**Untagged Issue**: Not an issue - TypeScript's structural typing handles this naturally
187
+
188
+
### Python (Pydantic)
189
+
-**oneOf**: Uses `Union` types with custom validation
190
+
-**anyOf**: Separate class with `actual_instance` that validates against multiple schemas
191
+
-**Approach**: Runtime validation with explicit checks for which schemas match
192
+
-**Untagged Issue**: Custom deserializer tries each type and keeps track of matches
193
+
194
+
### Go
195
+
-**oneOf**: Struct with pointer fields for each option, custom `UnmarshalJSON`
196
+
-**anyOf**: Similar structure but allows multiple fields to be non-nil
197
+
-**Approach**: All options as pointers, unmarshal attempts to populate each
198
+
-**Untagged Issue**: Custom unmarshaler tries each type, oneOf ensures only one succeeds
199
+
200
+
### C#
201
+
-**oneOf**: Uses inheritance with base class and custom JSON converters
202
+
-**anyOf**: Similar to oneOf but validation allows multiple matches
203
+
-**Approach**: Abstract base class with derived types, custom converters handle deserialization
204
+
-**Untagged Issue**: Custom converters attempt deserialization in order
0 commit comments