Skip to content

Commit 06221aa

Browse files
pquentinAnaethelion
authored andcommitted
Add OpenAPI mapping to internal variants (#5767)
* Add OpenAPI mapping to internal variants * Handle errors and avoid nested code * Rename mapping to disc_mapping for clarity * Sort disc_mapping by keys --------- Co-authored-by: Laurent Saint-Félix <laurent.saintfelix@elastic.co> (cherry picked from commit 9b82894)
1 parent a6d713e commit 06221aa

File tree

4 files changed

+557
-23
lines changed

4 files changed

+557
-23
lines changed

compiler-rs/clients_schema_to_openapi/src/schemas.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,10 +404,56 @@ impl<'a> TypesAndComponents<'a> {
404404
// TODO: typed-keys: add an extension to identify it?
405405
}
406406
Some(TypeAliasVariants::InternalTag(tag)) => {
407-
// TODO: add tag.default_tag as an extension
407+
// outputs a map of discriminator values to schema references
408+
// e.g. { "type1": "#/components/schemas/Type1", "type2": "#/components/schemas/Type2" }
409+
let mut disc_mapping = IndexMap::new();
410+
let ValueOf::UnionOf(union) = &alias.typ else {
411+
bail!("InternalTag type alias {} does not wrap a union", alias.base.name);
412+
};
413+
// Extract union members and build mapping
414+
for item in &union.items {
415+
let ValueOf::InstanceOf(instance) = item else {
416+
bail!(
417+
"InternalTag union member in type alias {} is not an instance_of",
418+
alias.base.name
419+
);
420+
};
421+
422+
match self.model.get_type(&instance.typ) {
423+
Ok(TypeDefinition::Interface(variant_itf)) => {
424+
// Find the discriminator property in the variant
425+
let Some(disc_prop) = variant_itf.properties.iter().find(|p| p.name == tag.tag) else {
426+
bail!(
427+
"InternalTag union member in type alias {} does not have discriminator property {}",
428+
alias.base.name,
429+
tag.tag
430+
);
431+
};
432+
433+
// Extract the literal value
434+
let ValueOf::LiteralValue(literal) = &disc_prop.typ else {
435+
bail!(
436+
"InternalTag union member in type alias {} has non-literal discriminator property {}",
437+
alias.base.name,
438+
tag.tag
439+
);
440+
};
441+
let discriminator_value = literal.value.to_string();
442+
let schema_ref = format!("#/components/schemas/{}", instance.typ.schema_name());
443+
disc_mapping.insert(discriminator_value, schema_ref);
444+
}
445+
_ => bail!(
446+
"InternalTag union member in type alias {} is not an interface",
447+
alias.base.name
448+
),
449+
}
450+
}
451+
disc_mapping.sort_unstable_keys();
452+
408453
schema.schema_data.discriminator = Some(Discriminator {
409454
property_name: tag.tag.clone(),
410-
mapping: Default::default(),
455+
mapping: disc_mapping,
456+
// TODO: add tag.default_tag as an extension
411457
extensions: Default::default(),
412458
});
413459
}
15.3 KB
Binary file not shown.

0 commit comments

Comments
 (0)