satay-codegen 0.4.1

Generate Rust client code from OpenAPI 3.1 documents
Documentation
use crate::model::{Union, UnionTagStyle, UnionVariant};

use super::super::{doc_attrs, ident, lit_str, rust_type};

pub(super) fn render_union(name: &str, description: Option<&str>, union: &Union) -> syn::ItemEnum {
    let name = ident(name);
    let docs = doc_attrs(description);
    let serde_tag_attr: syn::Attribute = if let Some(tag) = &union.tag
        && tag.style == UnionTagStyle::InternallyTagged
    {
        let property_name = lit_str(&tag.property_name);
        syn::parse_quote!(#[cfg_attr(feature = "serde", serde(tag = #property_name))])
    } else {
        syn::parse_quote!(#[cfg_attr(feature = "serde", serde(untagged))])
    };
    let variants = union
        .variants
        .iter()
        .map(render_union_variant)
        .collect::<Vec<_>>();

    syn::parse_quote!(
        #(#docs)*
        #[derive(Debug, Clone, PartialEq)]
        #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
        #serde_tag_attr
        pub enum #name {
            #(#variants),*
        }
    )
}

fn render_union_variant(variant: &UnionVariant) -> syn::Variant {
    let name = ident(&variant.rust_name);
    let ty = rust_type(&variant.ty);

    if let Some(tag_value) = &variant.tag_value {
        let tag_value = lit_str(tag_value);
        syn::parse_quote!(#[cfg_attr(feature = "serde", serde(rename = #tag_value))] #name(#ty))
    } else {
        syn::parse_quote!(#name(#ty))
    }
}