( schema: JSONSchema7, parentTypeName: string, jsonPropName: string, ctx: RustCodegenCtx, )
| 285 | } |
| 286 | |
| 287 | function tryEmitRustUnion( |
| 288 | schema: JSONSchema7, |
| 289 | parentTypeName: string, |
| 290 | jsonPropName: string, |
| 291 | ctx: RustCodegenCtx, |
| 292 | ): string | null { |
| 293 | const variants = getUnionVariants(schema); |
| 294 | if (!variants) return null; |
| 295 | |
| 296 | const nonNull = variants.filter((variant) => variant.type !== "null"); |
| 297 | if (nonNull.length <= 1) return null; |
| 298 | |
| 299 | const enumName = |
| 300 | (typeof schema.title === "string" && schema.title) || |
| 301 | parentTypeName + toPascalCase(jsonPropName); |
| 302 | |
| 303 | const resolvedVariants: RustUnionVariant[] = []; |
| 304 | for (let i = 0; i < nonNull.length; i++) { |
| 305 | const variant = nonNull[i]; |
| 306 | if (variant.$ref && typeof variant.$ref === "string") { |
| 307 | const resolved = resolveRef(variant.$ref, ctx.definitions); |
| 308 | if (resolved && !isObjectSchema(resolved)) return null; |
| 309 | resolvedVariants.push({ |
| 310 | schema: (resolved ?? variant) as JSONSchema7, |
| 311 | typeName: rustRefTypeName(variant.$ref, ctx.definitions), |
| 312 | }); |
| 313 | continue; |
| 314 | } |
| 315 | |
| 316 | const resolved = |
| 317 | resolveObjectSchema(variant, ctx.definitions) ?? |
| 318 | resolveSchema(variant, ctx.definitions) ?? |
| 319 | variant; |
| 320 | if (!isObjectSchema(resolved)) return null; |
| 321 | const discriminatorValue = Object.values(resolved.properties ?? {}).find( |
| 322 | (prop) => typeof prop === "object" && (prop as JSONSchema7).const !== undefined, |
| 323 | ) as JSONSchema7 | undefined; |
| 324 | const typeName = |
| 325 | (typeof resolved.title === "string" && resolved.title) || |
| 326 | (discriminatorValue?.const !== undefined |
| 327 | ? `${enumName}${toPascalCase(String(discriminatorValue.const))}` |
| 328 | : `${enumName}Variant${i + 1}`); |
| 329 | |
| 330 | resolvedVariants.push({ |
| 331 | schema: resolved as JSONSchema7, |
| 332 | typeName, |
| 333 | }); |
| 334 | } |
| 335 | |
| 336 | const discriminator = findRustDiscriminator(resolvedVariants); |
| 337 | const isAllowedUnionType = ctx.allowedUnionTypeNames.has(enumName); |
| 338 | if (discriminator) { |
| 339 | if ( |
| 340 | ctx.unionDiscriminatorProperties && |
| 341 | !ctx.unionDiscriminatorProperties.has(discriminator) && |
| 342 | !isAllowedUnionType |
| 343 | ) { |
| 344 | return null; |
no test coverage detected
searching dependent graphs…