// Copyright 2024, 2025 New Vector Ltd.
// Copyright 2023, 2024 The Matrix.org Foundation C.I.C.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
// Please see LICENSE files in the repository root for full details.

#![allow(clippy::doc_markdown)]

//! Enums from the "JSON Object Signing and Encryption" IANA registry
//! See <https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml>

// Do not edit this file manually

/// JSON Web Signature "alg" parameter
///
/// Source: <http://www.iana.org/assignments/jose/web-signature-encryption-algorithms.csv>
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
pub enum JsonWebSignatureAlg {
    /// HMAC using SHA-256
    Hs256,

    /// HMAC using SHA-384
    Hs384,

    /// HMAC using SHA-512
    Hs512,

    /// RSASSA-PKCS1-v1_5 using SHA-256
    Rs256,

    /// RSASSA-PKCS1-v1_5 using SHA-384
    Rs384,

    /// RSASSA-PKCS1-v1_5 using SHA-512
    Rs512,

    /// ECDSA using P-256 and SHA-256
    Es256,

    /// ECDSA using P-384 and SHA-384
    Es384,

    /// ECDSA using P-521 and SHA-512
    Es512,

    /// RSASSA-PSS using SHA-256 and MGF1 with SHA-256
    Ps256,

    /// RSASSA-PSS using SHA-384 and MGF1 with SHA-384
    Ps384,

    /// RSASSA-PSS using SHA-512 and MGF1 with SHA-512
    Ps512,

    /// No digital signature or MAC performed
    None,

    /// EdDSA signature algorithms
    EdDsa,

    /// ECDSA using secp256k1 curve and SHA-256
    Es256K,

    /// EdDSA using Ed25519 curve
    Ed25519,

    /// EdDSA using Ed448 curve
    Ed448,

    /// An unknown value.
    Unknown(String),
}

impl core::fmt::Display for JsonWebSignatureAlg {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            Self::Hs256 => write!(f, "HS256"),
            Self::Hs384 => write!(f, "HS384"),
            Self::Hs512 => write!(f, "HS512"),
            Self::Rs256 => write!(f, "RS256"),
            Self::Rs384 => write!(f, "RS384"),
            Self::Rs512 => write!(f, "RS512"),
            Self::Es256 => write!(f, "ES256"),
            Self::Es384 => write!(f, "ES384"),
            Self::Es512 => write!(f, "ES512"),
            Self::Ps256 => write!(f, "PS256"),
            Self::Ps384 => write!(f, "PS384"),
            Self::Ps512 => write!(f, "PS512"),
            Self::None => write!(f, "none"),
            Self::EdDsa => write!(f, "EdDSA"),
            Self::Es256K => write!(f, "ES256K"),
            Self::Ed25519 => write!(f, "Ed25519"),
            Self::Ed448 => write!(f, "Ed448"),
            Self::Unknown(value) => write!(f, "{value}"),
        }
    }
}

impl core::str::FromStr for JsonWebSignatureAlg {
    type Err = core::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "HS256" => Ok(Self::Hs256),
            "HS384" => Ok(Self::Hs384),
            "HS512" => Ok(Self::Hs512),
            "RS256" => Ok(Self::Rs256),
            "RS384" => Ok(Self::Rs384),
            "RS512" => Ok(Self::Rs512),
            "ES256" => Ok(Self::Es256),
            "ES384" => Ok(Self::Es384),
            "ES512" => Ok(Self::Es512),
            "PS256" => Ok(Self::Ps256),
            "PS384" => Ok(Self::Ps384),
            "PS512" => Ok(Self::Ps512),
            "none" => Ok(Self::None),
            "EdDSA" => Ok(Self::EdDsa),
            "ES256K" => Ok(Self::Es256K),
            "Ed25519" => Ok(Self::Ed25519),
            "Ed448" => Ok(Self::Ed448),
            value => Ok(Self::Unknown(value.to_owned())),
        }
    }
}

impl<'de> serde::Deserialize<'de> for JsonWebSignatureAlg {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::de::Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
    }
}

impl serde::Serialize for JsonWebSignatureAlg {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::ser::Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl schemars::JsonSchema for JsonWebSignatureAlg {
    fn schema_name() -> String {
        "JsonWebSignatureAlg".to_owned()
    }

    fn json_schema(_gen: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema {
        let enums = vec![
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"HMAC using SHA-256".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("HS256".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"HMAC using SHA-384".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("HS384".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"HMAC using SHA-512".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("HS512".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"RSASSA-PKCS1-v1_5 using SHA-256".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("RS256".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"RSASSA-PKCS1-v1_5 using SHA-384".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("RS384".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"RSASSA-PKCS1-v1_5 using SHA-512".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("RS512".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"ECDSA using P-256 and SHA-256".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("ES256".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"ECDSA using P-384 and SHA-384".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("ES384".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"ECDSA using P-521 and SHA-512".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("ES512".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"RSASSA-PSS using SHA-256 and MGF1 with SHA-256".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("PS256".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"RSASSA-PSS using SHA-384 and MGF1 with SHA-384".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("PS384".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"RSASSA-PSS using SHA-512 and MGF1 with SHA-512".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("PS512".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"No digital signature or MAC performed".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("none".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"EdDSA signature algorithms".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("EdDSA".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"ECDSA using secp256k1 curve and SHA-256".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("ES256K".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"EdDSA using Ed25519 curve".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("Ed25519".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"EdDSA using Ed448 curve".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("Ed448".into()),
                ..Default::default()
            }
            .into(),
        ];

        let description = r#"JSON Web Signature "alg" parameter"#;
        schemars::schema::SchemaObject {
            metadata: Some(Box::new(schemars::schema::Metadata {
                description: Some(description.to_owned()),
                ..Default::default()
            })),
            subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
                any_of: Some(enums),
                ..Default::default()
            })),
            ..Default::default()
        }
        .into()
    }
}

/// JSON Web Encryption "alg" parameter
///
/// Source: <http://www.iana.org/assignments/jose/web-signature-encryption-algorithms.csv>
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
pub enum JsonWebEncryptionAlg {
    /// RSAES-PKCS1-v1_5
    Rsa15,

    /// RSAES OAEP using default parameters
    RsaOaep,

    /// RSAES OAEP using SHA-256 and MGF1 with SHA-256
    RsaOaep256,

    /// AES Key Wrap using 128-bit key
    A128Kw,

    /// AES Key Wrap using 192-bit key
    A192Kw,

    /// AES Key Wrap using 256-bit key
    A256Kw,

    /// Direct use of a shared symmetric key
    Dir,

    /// ECDH-ES using Concat KDF
    EcdhEs,

    /// ECDH-ES using Concat KDF and "A128KW" wrapping
    EcdhEsA128Kw,

    /// ECDH-ES using Concat KDF and "A192KW" wrapping
    EcdhEsA192Kw,

    /// ECDH-ES using Concat KDF and "A256KW" wrapping
    EcdhEsA256Kw,

    /// Key wrapping with AES GCM using 128-bit key
    A128Gcmkw,

    /// Key wrapping with AES GCM using 192-bit key
    A192Gcmkw,

    /// Key wrapping with AES GCM using 256-bit key
    A256Gcmkw,

    /// PBES2 with HMAC SHA-256 and "A128KW" wrapping
    Pbes2Hs256A128Kw,

    /// PBES2 with HMAC SHA-384 and "A192KW" wrapping
    Pbes2Hs384A192Kw,

    /// PBES2 with HMAC SHA-512 and "A256KW" wrapping
    Pbes2Hs512A256Kw,

    /// RSA-OAEP using SHA-384 and MGF1 with SHA-384
    RsaOaep384,

    /// RSA-OAEP using SHA-512 and MGF1 with SHA-512
    RsaOaep512,

    /// An unknown value.
    Unknown(String),
}

impl core::fmt::Display for JsonWebEncryptionAlg {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            Self::Rsa15 => write!(f, "RSA1_5"),
            Self::RsaOaep => write!(f, "RSA-OAEP"),
            Self::RsaOaep256 => write!(f, "RSA-OAEP-256"),
            Self::A128Kw => write!(f, "A128KW"),
            Self::A192Kw => write!(f, "A192KW"),
            Self::A256Kw => write!(f, "A256KW"),
            Self::Dir => write!(f, "dir"),
            Self::EcdhEs => write!(f, "ECDH-ES"),
            Self::EcdhEsA128Kw => write!(f, "ECDH-ES+A128KW"),
            Self::EcdhEsA192Kw => write!(f, "ECDH-ES+A192KW"),
            Self::EcdhEsA256Kw => write!(f, "ECDH-ES+A256KW"),
            Self::A128Gcmkw => write!(f, "A128GCMKW"),
            Self::A192Gcmkw => write!(f, "A192GCMKW"),
            Self::A256Gcmkw => write!(f, "A256GCMKW"),
            Self::Pbes2Hs256A128Kw => write!(f, "PBES2-HS256+A128KW"),
            Self::Pbes2Hs384A192Kw => write!(f, "PBES2-HS384+A192KW"),
            Self::Pbes2Hs512A256Kw => write!(f, "PBES2-HS512+A256KW"),
            Self::RsaOaep384 => write!(f, "RSA-OAEP-384"),
            Self::RsaOaep512 => write!(f, "RSA-OAEP-512"),
            Self::Unknown(value) => write!(f, "{value}"),
        }
    }
}

impl core::str::FromStr for JsonWebEncryptionAlg {
    type Err = core::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "RSA1_5" => Ok(Self::Rsa15),
            "RSA-OAEP" => Ok(Self::RsaOaep),
            "RSA-OAEP-256" => Ok(Self::RsaOaep256),
            "A128KW" => Ok(Self::A128Kw),
            "A192KW" => Ok(Self::A192Kw),
            "A256KW" => Ok(Self::A256Kw),
            "dir" => Ok(Self::Dir),
            "ECDH-ES" => Ok(Self::EcdhEs),
            "ECDH-ES+A128KW" => Ok(Self::EcdhEsA128Kw),
            "ECDH-ES+A192KW" => Ok(Self::EcdhEsA192Kw),
            "ECDH-ES+A256KW" => Ok(Self::EcdhEsA256Kw),
            "A128GCMKW" => Ok(Self::A128Gcmkw),
            "A192GCMKW" => Ok(Self::A192Gcmkw),
            "A256GCMKW" => Ok(Self::A256Gcmkw),
            "PBES2-HS256+A128KW" => Ok(Self::Pbes2Hs256A128Kw),
            "PBES2-HS384+A192KW" => Ok(Self::Pbes2Hs384A192Kw),
            "PBES2-HS512+A256KW" => Ok(Self::Pbes2Hs512A256Kw),
            "RSA-OAEP-384" => Ok(Self::RsaOaep384),
            "RSA-OAEP-512" => Ok(Self::RsaOaep512),
            value => Ok(Self::Unknown(value.to_owned())),
        }
    }
}

impl<'de> serde::Deserialize<'de> for JsonWebEncryptionAlg {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::de::Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
    }
}

impl serde::Serialize for JsonWebEncryptionAlg {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::ser::Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl schemars::JsonSchema for JsonWebEncryptionAlg {
    fn schema_name() -> String {
        "JsonWebEncryptionAlg".to_owned()
    }

    fn json_schema(_gen: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema {
        let enums = vec![
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"RSAES-PKCS1-v1_5".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("RSA1_5".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"RSAES OAEP using default parameters".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("RSA-OAEP".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"RSAES OAEP using SHA-256 and MGF1 with SHA-256".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("RSA-OAEP-256".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"AES Key Wrap using 128-bit key".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("A128KW".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"AES Key Wrap using 192-bit key".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("A192KW".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"AES Key Wrap using 256-bit key".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("A256KW".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"Direct use of a shared symmetric key".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("dir".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"ECDH-ES using Concat KDF".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("ECDH-ES".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r#"ECDH-ES using Concat KDF and "A128KW" wrapping"#.to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("ECDH-ES+A128KW".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r#"ECDH-ES using Concat KDF and "A192KW" wrapping"#.to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("ECDH-ES+A192KW".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r#"ECDH-ES using Concat KDF and "A256KW" wrapping"#.to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("ECDH-ES+A256KW".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"Key wrapping with AES GCM using 128-bit key".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("A128GCMKW".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"Key wrapping with AES GCM using 192-bit key".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("A192GCMKW".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"Key wrapping with AES GCM using 256-bit key".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("A256GCMKW".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r#"PBES2 with HMAC SHA-256 and "A128KW" wrapping"#.to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("PBES2-HS256+A128KW".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r#"PBES2 with HMAC SHA-384 and "A192KW" wrapping"#.to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("PBES2-HS384+A192KW".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r#"PBES2 with HMAC SHA-512 and "A256KW" wrapping"#.to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("PBES2-HS512+A256KW".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"RSA-OAEP using SHA-384 and MGF1 with SHA-384".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("RSA-OAEP-384".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"RSA-OAEP using SHA-512 and MGF1 with SHA-512".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("RSA-OAEP-512".into()),
                ..Default::default()
            }
            .into(),
        ];

        let description = r#"JSON Web Encryption "alg" parameter"#;
        schemars::schema::SchemaObject {
            metadata: Some(Box::new(schemars::schema::Metadata {
                description: Some(description.to_owned()),
                ..Default::default()
            })),
            subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
                any_of: Some(enums),
                ..Default::default()
            })),
            ..Default::default()
        }
        .into()
    }
}

/// JSON Web Encryption "enc" parameter
///
/// Source: <http://www.iana.org/assignments/jose/web-signature-encryption-algorithms.csv>
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
pub enum JsonWebEncryptionEnc {
    /// AES_128_CBC_HMAC_SHA_256 authenticated encryption algorithm
    A128CbcHs256,

    /// AES_192_CBC_HMAC_SHA_384 authenticated encryption algorithm
    A192CbcHs384,

    /// AES_256_CBC_HMAC_SHA_512 authenticated encryption algorithm
    A256CbcHs512,

    /// AES GCM using 128-bit key
    A128Gcm,

    /// AES GCM using 192-bit key
    A192Gcm,

    /// AES GCM using 256-bit key
    A256Gcm,

    /// An unknown value.
    Unknown(String),
}

impl core::fmt::Display for JsonWebEncryptionEnc {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            Self::A128CbcHs256 => write!(f, "A128CBC-HS256"),
            Self::A192CbcHs384 => write!(f, "A192CBC-HS384"),
            Self::A256CbcHs512 => write!(f, "A256CBC-HS512"),
            Self::A128Gcm => write!(f, "A128GCM"),
            Self::A192Gcm => write!(f, "A192GCM"),
            Self::A256Gcm => write!(f, "A256GCM"),
            Self::Unknown(value) => write!(f, "{value}"),
        }
    }
}

impl core::str::FromStr for JsonWebEncryptionEnc {
    type Err = core::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "A128CBC-HS256" => Ok(Self::A128CbcHs256),
            "A192CBC-HS384" => Ok(Self::A192CbcHs384),
            "A256CBC-HS512" => Ok(Self::A256CbcHs512),
            "A128GCM" => Ok(Self::A128Gcm),
            "A192GCM" => Ok(Self::A192Gcm),
            "A256GCM" => Ok(Self::A256Gcm),
            value => Ok(Self::Unknown(value.to_owned())),
        }
    }
}

impl<'de> serde::Deserialize<'de> for JsonWebEncryptionEnc {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::de::Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
    }
}

impl serde::Serialize for JsonWebEncryptionEnc {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::ser::Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl schemars::JsonSchema for JsonWebEncryptionEnc {
    fn schema_name() -> String {
        "JsonWebEncryptionEnc".to_owned()
    }

    fn json_schema(_gen: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema {
        let enums = vec![
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"AES_128_CBC_HMAC_SHA_256 authenticated encryption algorithm".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("A128CBC-HS256".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"AES_192_CBC_HMAC_SHA_384 authenticated encryption algorithm".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("A192CBC-HS384".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"AES_256_CBC_HMAC_SHA_512 authenticated encryption algorithm".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("A256CBC-HS512".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"AES GCM using 128-bit key".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("A128GCM".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"AES GCM using 192-bit key".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("A192GCM".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"AES GCM using 256-bit key".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("A256GCM".into()),
                ..Default::default()
            }
            .into(),
        ];

        let description = r#"JSON Web Encryption "enc" parameter"#;
        schemars::schema::SchemaObject {
            metadata: Some(Box::new(schemars::schema::Metadata {
                description: Some(description.to_owned()),
                ..Default::default()
            })),
            subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
                any_of: Some(enums),
                ..Default::default()
            })),
            ..Default::default()
        }
        .into()
    }
}

/// JSON Web Encryption Compression Algorithm
///
/// Source: <http://www.iana.org/assignments/jose/web-encryption-compression-algorithms.csv>
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
pub enum JsonWebEncryptionCompressionAlgorithm {
    /// DEFLATE
    Def,

    /// An unknown value.
    Unknown(String),
}

impl core::fmt::Display for JsonWebEncryptionCompressionAlgorithm {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            Self::Def => write!(f, "DEF"),
            Self::Unknown(value) => write!(f, "{value}"),
        }
    }
}

impl core::str::FromStr for JsonWebEncryptionCompressionAlgorithm {
    type Err = core::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "DEF" => Ok(Self::Def),
            value => Ok(Self::Unknown(value.to_owned())),
        }
    }
}

impl<'de> serde::Deserialize<'de> for JsonWebEncryptionCompressionAlgorithm {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::de::Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
    }
}

impl serde::Serialize for JsonWebEncryptionCompressionAlgorithm {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::ser::Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl schemars::JsonSchema for JsonWebEncryptionCompressionAlgorithm {
    fn schema_name() -> String {
        "JsonWebEncryptionCompressionAlgorithm".to_owned()
    }

    fn json_schema(_gen: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema {
        let enums = vec![
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"DEFLATE".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("DEF".into()),
                ..Default::default()
            }
            .into(),
        ];

        let description = r"JSON Web Encryption Compression Algorithm";
        schemars::schema::SchemaObject {
            metadata: Some(Box::new(schemars::schema::Metadata {
                description: Some(description.to_owned()),
                ..Default::default()
            })),
            subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
                any_of: Some(enums),
                ..Default::default()
            })),
            ..Default::default()
        }
        .into()
    }
}

/// JSON Web Key Type
///
/// Source: <http://www.iana.org/assignments/jose/web-key-types.csv>
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
pub enum JsonWebKeyType {
    /// Elliptic Curve
    Ec,

    /// RSA
    Rsa,

    /// Octet sequence
    Oct,

    /// Octet string key pairs
    Okp,

    /// An unknown value.
    Unknown(String),
}

impl core::fmt::Display for JsonWebKeyType {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            Self::Ec => write!(f, "EC"),
            Self::Rsa => write!(f, "RSA"),
            Self::Oct => write!(f, "oct"),
            Self::Okp => write!(f, "OKP"),
            Self::Unknown(value) => write!(f, "{value}"),
        }
    }
}

impl core::str::FromStr for JsonWebKeyType {
    type Err = core::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "EC" => Ok(Self::Ec),
            "RSA" => Ok(Self::Rsa),
            "oct" => Ok(Self::Oct),
            "OKP" => Ok(Self::Okp),
            value => Ok(Self::Unknown(value.to_owned())),
        }
    }
}

impl<'de> serde::Deserialize<'de> for JsonWebKeyType {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::de::Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
    }
}

impl serde::Serialize for JsonWebKeyType {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::ser::Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl schemars::JsonSchema for JsonWebKeyType {
    fn schema_name() -> String {
        "JsonWebKeyType".to_owned()
    }

    fn json_schema(_gen: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema {
        let enums = vec![
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"Elliptic Curve".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("EC".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"RSA".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("RSA".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"Octet sequence".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("oct".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"Octet string key pairs".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("OKP".into()),
                ..Default::default()
            }
            .into(),
        ];

        let description = r"JSON Web Key Type";
        schemars::schema::SchemaObject {
            metadata: Some(Box::new(schemars::schema::Metadata {
                description: Some(description.to_owned()),
                ..Default::default()
            })),
            subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
                any_of: Some(enums),
                ..Default::default()
            })),
            ..Default::default()
        }
        .into()
    }
}

/// JSON Web Key EC Elliptic Curve
///
/// Source: <http://www.iana.org/assignments/jose/web-key-elliptic-curve.csv>
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
pub enum JsonWebKeyEcEllipticCurve {
    /// P-256 Curve
    P256,

    /// P-384 Curve
    P384,

    /// P-521 Curve
    P521,

    /// SECG secp256k1 curve
    Secp256K1,

    /// An unknown value.
    Unknown(String),
}

impl core::fmt::Display for JsonWebKeyEcEllipticCurve {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            Self::P256 => write!(f, "P-256"),
            Self::P384 => write!(f, "P-384"),
            Self::P521 => write!(f, "P-521"),
            Self::Secp256K1 => write!(f, "secp256k1"),
            Self::Unknown(value) => write!(f, "{value}"),
        }
    }
}

impl core::str::FromStr for JsonWebKeyEcEllipticCurve {
    type Err = core::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "P-256" => Ok(Self::P256),
            "P-384" => Ok(Self::P384),
            "P-521" => Ok(Self::P521),
            "secp256k1" => Ok(Self::Secp256K1),
            value => Ok(Self::Unknown(value.to_owned())),
        }
    }
}

impl<'de> serde::Deserialize<'de> for JsonWebKeyEcEllipticCurve {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::de::Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
    }
}

impl serde::Serialize for JsonWebKeyEcEllipticCurve {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::ser::Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl schemars::JsonSchema for JsonWebKeyEcEllipticCurve {
    fn schema_name() -> String {
        "JsonWebKeyEcEllipticCurve".to_owned()
    }

    fn json_schema(_gen: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema {
        let enums = vec![
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"P-256 Curve".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("P-256".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"P-384 Curve".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("P-384".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"P-521 Curve".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("P-521".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"SECG secp256k1 curve".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("secp256k1".into()),
                ..Default::default()
            }
            .into(),
        ];

        let description = r"JSON Web Key EC Elliptic Curve";
        schemars::schema::SchemaObject {
            metadata: Some(Box::new(schemars::schema::Metadata {
                description: Some(description.to_owned()),
                ..Default::default()
            })),
            subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
                any_of: Some(enums),
                ..Default::default()
            })),
            ..Default::default()
        }
        .into()
    }
}

/// JSON Web Key OKP Elliptic Curve
///
/// Source: <http://www.iana.org/assignments/jose/web-key-elliptic-curve.csv>
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
pub enum JsonWebKeyOkpEllipticCurve {
    /// Ed25519 signature algorithm key pairs
    Ed25519,

    /// Ed448 signature algorithm key pairs
    Ed448,

    /// X25519 function key pairs
    X25519,

    /// X448 function key pairs
    X448,

    /// An unknown value.
    Unknown(String),
}

impl core::fmt::Display for JsonWebKeyOkpEllipticCurve {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            Self::Ed25519 => write!(f, "Ed25519"),
            Self::Ed448 => write!(f, "Ed448"),
            Self::X25519 => write!(f, "X25519"),
            Self::X448 => write!(f, "X448"),
            Self::Unknown(value) => write!(f, "{value}"),
        }
    }
}

impl core::str::FromStr for JsonWebKeyOkpEllipticCurve {
    type Err = core::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "Ed25519" => Ok(Self::Ed25519),
            "Ed448" => Ok(Self::Ed448),
            "X25519" => Ok(Self::X25519),
            "X448" => Ok(Self::X448),
            value => Ok(Self::Unknown(value.to_owned())),
        }
    }
}

impl<'de> serde::Deserialize<'de> for JsonWebKeyOkpEllipticCurve {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::de::Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
    }
}

impl serde::Serialize for JsonWebKeyOkpEllipticCurve {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::ser::Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl schemars::JsonSchema for JsonWebKeyOkpEllipticCurve {
    fn schema_name() -> String {
        "JsonWebKeyOkpEllipticCurve".to_owned()
    }

    fn json_schema(_gen: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema {
        let enums = vec![
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"Ed25519 signature algorithm key pairs".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("Ed25519".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"Ed448 signature algorithm key pairs".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("Ed448".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"X25519 function key pairs".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("X25519".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"X448 function key pairs".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("X448".into()),
                ..Default::default()
            }
            .into(),
        ];

        let description = r"JSON Web Key OKP Elliptic Curve";
        schemars::schema::SchemaObject {
            metadata: Some(Box::new(schemars::schema::Metadata {
                description: Some(description.to_owned()),
                ..Default::default()
            })),
            subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
                any_of: Some(enums),
                ..Default::default()
            })),
            ..Default::default()
        }
        .into()
    }
}

/// JSON Web Key Use
///
/// Source: <http://www.iana.org/assignments/jose/web-key-use.csv>
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
pub enum JsonWebKeyUse {
    /// Digital Signature or MAC
    Sig,

    /// Encryption
    Enc,

    /// An unknown value.
    Unknown(String),
}

impl core::fmt::Display for JsonWebKeyUse {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            Self::Sig => write!(f, "sig"),
            Self::Enc => write!(f, "enc"),
            Self::Unknown(value) => write!(f, "{value}"),
        }
    }
}

impl core::str::FromStr for JsonWebKeyUse {
    type Err = core::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "sig" => Ok(Self::Sig),
            "enc" => Ok(Self::Enc),
            value => Ok(Self::Unknown(value.to_owned())),
        }
    }
}

impl<'de> serde::Deserialize<'de> for JsonWebKeyUse {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::de::Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
    }
}

impl serde::Serialize for JsonWebKeyUse {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::ser::Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl schemars::JsonSchema for JsonWebKeyUse {
    fn schema_name() -> String {
        "JsonWebKeyUse".to_owned()
    }

    fn json_schema(_gen: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema {
        let enums = vec![
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"Digital Signature or MAC".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("sig".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"Encryption".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("enc".into()),
                ..Default::default()
            }
            .into(),
        ];

        let description = r"JSON Web Key Use";
        schemars::schema::SchemaObject {
            metadata: Some(Box::new(schemars::schema::Metadata {
                description: Some(description.to_owned()),
                ..Default::default()
            })),
            subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
                any_of: Some(enums),
                ..Default::default()
            })),
            ..Default::default()
        }
        .into()
    }
}

/// JSON Web Key Operation
///
/// Source: <http://www.iana.org/assignments/jose/web-key-operations.csv>
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
pub enum JsonWebKeyOperation {
    /// Compute digital signature or MAC
    Sign,

    /// Verify digital signature or MAC
    Verify,

    /// Encrypt content
    Encrypt,

    /// Decrypt content and validate decryption, if applicable
    Decrypt,

    /// Encrypt key
    WrapKey,

    /// Decrypt key and validate decryption, if applicable
    UnwrapKey,

    /// Derive key
    DeriveKey,

    /// Derive bits not to be used as a key
    DeriveBits,

    /// An unknown value.
    Unknown(String),
}

impl core::fmt::Display for JsonWebKeyOperation {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            Self::Sign => write!(f, "sign"),
            Self::Verify => write!(f, "verify"),
            Self::Encrypt => write!(f, "encrypt"),
            Self::Decrypt => write!(f, "decrypt"),
            Self::WrapKey => write!(f, "wrapKey"),
            Self::UnwrapKey => write!(f, "unwrapKey"),
            Self::DeriveKey => write!(f, "deriveKey"),
            Self::DeriveBits => write!(f, "deriveBits"),
            Self::Unknown(value) => write!(f, "{value}"),
        }
    }
}

impl core::str::FromStr for JsonWebKeyOperation {
    type Err = core::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "sign" => Ok(Self::Sign),
            "verify" => Ok(Self::Verify),
            "encrypt" => Ok(Self::Encrypt),
            "decrypt" => Ok(Self::Decrypt),
            "wrapKey" => Ok(Self::WrapKey),
            "unwrapKey" => Ok(Self::UnwrapKey),
            "deriveKey" => Ok(Self::DeriveKey),
            "deriveBits" => Ok(Self::DeriveBits),
            value => Ok(Self::Unknown(value.to_owned())),
        }
    }
}

impl<'de> serde::Deserialize<'de> for JsonWebKeyOperation {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::de::Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom)
    }
}

impl serde::Serialize for JsonWebKeyOperation {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::ser::Serializer,
    {
        serializer.serialize_str(&self.to_string())
    }
}

impl schemars::JsonSchema for JsonWebKeyOperation {
    fn schema_name() -> String {
        "JsonWebKeyOperation".to_owned()
    }

    fn json_schema(_gen: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema {
        let enums = vec![
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"Compute digital signature or MAC".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("sign".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"Verify digital signature or MAC".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("verify".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"Encrypt content".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("encrypt".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"Decrypt content and validate decryption, if applicable".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("decrypt".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"Encrypt key".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("wrapKey".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"Decrypt key and validate decryption, if applicable".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("unwrapKey".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"Derive key".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("deriveKey".into()),
                ..Default::default()
            }
            .into(),
            // ---
            schemars::schema::SchemaObject {
                metadata: Some(Box::new(schemars::schema::Metadata {
                    description: Some(
                        // ---
                        r"Derive bits not to be used as a key".to_owned(),
                    ),
                    ..Default::default()
                })),
                const_value: Some("deriveBits".into()),
                ..Default::default()
            }
            .into(),
        ];

        let description = r"JSON Web Key Operation";
        schemars::schema::SchemaObject {
            metadata: Some(Box::new(schemars::schema::Metadata {
                description: Some(description.to_owned()),
                ..Default::default()
            })),
            subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
                any_of: Some(enums),
                ..Default::default()
            })),
            ..Default::default()
        }
        .into()
    }
}
