@@ -307,6 +307,69 @@ public CodegenModel fromModel(String name, Schema model) {
307
307
mdl .getComposedSchemas ().setOneOf (newOneOfs );
308
308
}
309
309
310
+ // Handle anyOf schemas similarly to oneOf
311
+ // This is pragmatic since Rust's untagged enum will deserialize to the first matching variant
312
+ if (mdl .getComposedSchemas () != null && mdl .getComposedSchemas ().getAnyOf () != null
313
+ && !mdl .getComposedSchemas ().getAnyOf ().isEmpty ()) {
314
+
315
+ List <CodegenProperty > newAnyOfs = mdl .getComposedSchemas ().getAnyOf ().stream ()
316
+ .map (CodegenProperty ::clone )
317
+ .collect (Collectors .toList ());
318
+ List <Schema > schemas = ModelUtils .getInterfaces (model );
319
+ if (newAnyOfs .size () != schemas .size ()) {
320
+ // For safety reasons, this should never happen unless there is an error in the code
321
+ throw new RuntimeException ("anyOf size does not match the model" );
322
+ }
323
+
324
+ Map <String , String > refsMapping = Optional .ofNullable (model .getDiscriminator ())
325
+ .map (Discriminator ::getMapping ).orElse (Collections .emptyMap ());
326
+
327
+ // Reverse mapped references to use as baseName for anyOf, but different keys may point to the same $ref.
328
+ // Thus, we group them by the value
329
+ Map <String , List <String >> mappedNamesByRef = refsMapping .entrySet ().stream ()
330
+ .collect (Collectors .groupingBy (Map .Entry ::getValue ,
331
+ Collectors .mapping (Map .Entry ::getKey , Collectors .toList ())
332
+ ));
333
+
334
+ for (int i = 0 ; i < newAnyOfs .size (); i ++) {
335
+ CodegenProperty anyOf = newAnyOfs .get (i );
336
+ Schema schema = schemas .get (i );
337
+
338
+ if (mappedNamesByRef .containsKey (schema .get$ref ())) {
339
+ // prefer mapped names if present
340
+ // remove mapping not in order not to reuse for the next occurrence of the ref
341
+ List <String > names = mappedNamesByRef .get (schema .get$ref ());
342
+ String mappedName = names .remove (0 );
343
+ anyOf .setBaseName (mappedName );
344
+ anyOf .setName (toModelName (mappedName ));
345
+ } else if (!org .apache .commons .lang3 .StringUtils .isEmpty (schema .get$ref ())) {
346
+ // use $ref if it's reference
347
+ String refName = ModelUtils .getSimpleRef (schema .get$ref ());
348
+ if (refName != null ) {
349
+ String modelName = toModelName (refName );
350
+ anyOf .setName (modelName );
351
+ anyOf .setBaseName (refName );
352
+ }
353
+ } else if (anyOf .isArray ) {
354
+ // If the type is an array, extend the name with the inner type to prevent name collisions
355
+ // in case multiple arrays with different types are defined. If the user has manually specified
356
+ // a name, use that name instead.
357
+ String collectionWithTypeName = toModelName (schema .getType ()) + anyOf .containerTypeMapped + anyOf .items .dataType ;
358
+ String anyOfName = Optional .ofNullable (schema .getTitle ()).orElse (collectionWithTypeName );
359
+ anyOf .setName (anyOfName );
360
+ }
361
+ else {
362
+ // In-placed type (primitive), because there is no mapping or ref for it.
363
+ // use camelized `title` if present, otherwise use `type`
364
+ String anyOfName = Optional .ofNullable (schema .getTitle ()).orElseGet (schema ::getType );
365
+ anyOf .setName (toModelName (anyOfName ));
366
+ }
367
+ }
368
+
369
+ // Set anyOf as oneOf for template processing since we want the same output
370
+ mdl .getComposedSchemas ().setOneOf (newAnyOfs );
371
+ }
372
+
310
373
return mdl ;
311
374
}
312
375
0 commit comments