Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support enum modelAsString #769

Merged
merged 2 commits into from
May 27, 2022
Merged

Conversation

johnbatty
Copy link
Contributor

@johnbatty johnbatty commented May 26, 2022

Add support for enum modelAsString attribute.

Fixes #768

If the modelAsString field in the spec is true, then generated enums have an additional UnknownValue(String) field that captures the string value if none of the other enum values match.

Simplified example:

    pub enum Status {
        Active,
        Inactive,
        UnknownValue(String),
    }

This cannot be done using standard serde attributes, so I have had to implement custom serializer/deserializers.

A more detailed example of the new code generated for the example given in the original issue:

pub mod hardware_profile {
    use super::*;
...
    #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
    #[serde(remote = "VmSize")]
    pub enum VmSize {
        #[serde(rename = "Basic_A0")]
        BasicA0,
        #[serde(rename = "Basic_A1")]
        BasicA1,
        #[serde(rename = "Basic_A2")]
        BasicA2,
...
        #[serde(rename = "Standard_NV6")]
        StandardNv6,
        #[serde(rename = "Standard_NV12")]
        StandardNv12,
        #[serde(rename = "Standard_NV24")]
        StandardNv24,
        #[serde(skip_deserializing)]
        UnknownValue(String),
    }
    impl FromStr for VmSize {
        type Err = value::Error;
        fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
            Self::deserialize(s.into_deserializer())
        }
    }
    impl<'de> Deserialize<'de> for VmSize {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: Deserializer<'de>,
        {
            let s = String::deserialize(deserializer)?;
            let deserialized = Self::from_str(&s).unwrap_or(Self::UnknownValue(s));
            Ok(deserialized)
        }
    }
    impl Serialize for VmSize {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: Serializer,
        {
            match self {
                Self::BasicA0 => serializer.serialize_unit_variant("VmSize", 0u32, "Basic_A0"),
                Self::BasicA1 => serializer.serialize_unit_variant("VmSize", 1u32, "Basic_A1"),
                Self::BasicA2 => serializer.serialize_unit_variant("VmSize", 2u32, "Basic_A2"),
...
                Self::StandardNv6 => serializer.serialize_unit_variant("VmSize", 163u32, "Standard_NV6"),
                Self::StandardNv12 => serializer.serialize_unit_variant("VmSize", 164u32, "Standard_NV12"),
                Self::StandardNv24 => serializer.serialize_unit_variant("VmSize", 165u32, "Standard_NV24"),
                Self::UnknownValue(s) => serializer.serialize_str(s.as_str()),
            }
        }
    }
}

@johnbatty johnbatty force-pushed the model-as-string-enum branch 2 times, most recently from 72f4e91 to e290b8f Compare May 27, 2022 07:40
@johnbatty johnbatty force-pushed the model-as-string-enum branch from e290b8f to d794509 Compare May 27, 2022 10:42
@cataggar cataggar added this to the services 0.4.0 milestone May 27, 2022
Copy link
Member

@cataggar cataggar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! I just confirmed that cargo run --package azure_mgmt_compute --example vm_list works for me with this change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

add AutoRust support for x-ms-enum modelAsString
2 participants