// 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() -> std::borrow::Cow<'static, str> {
        std::borrow::Cow::Borrowed("JsonWebSignatureAlg")
    }

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

        let description = r#"JSON Web Signature "alg" parameter"#;
        schemars::json_schema!({
            "description": description,
            "anyOf": enums,
        })
    }
}

/// 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() -> std::borrow::Cow<'static, str> {
        std::borrow::Cow::Borrowed("JsonWebEncryptionAlg")
    }

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

        let description = r#"JSON Web Encryption "alg" parameter"#;
        schemars::json_schema!({
            "description": description,
            "anyOf": enums,
        })
    }
}

/// 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() -> std::borrow::Cow<'static, str> {
        std::borrow::Cow::Borrowed("JsonWebEncryptionEnc")
    }

    fn json_schema(_gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
        let enums = vec![
            // ---
            schemars::json_schema!({
                "description": r"AES_128_CBC_HMAC_SHA_256 authenticated encryption algorithm",
                "const": "A128CBC-HS256",
            }),
            // ---
            schemars::json_schema!({
                "description": r"AES_192_CBC_HMAC_SHA_384 authenticated encryption algorithm",
                "const": "A192CBC-HS384",
            }),
            // ---
            schemars::json_schema!({
                "description": r"AES_256_CBC_HMAC_SHA_512 authenticated encryption algorithm",
                "const": "A256CBC-HS512",
            }),
            // ---
            schemars::json_schema!({
                "description": r"AES GCM using 128-bit key",
                "const": "A128GCM",
            }),
            // ---
            schemars::json_schema!({
                "description": r"AES GCM using 192-bit key",
                "const": "A192GCM",
            }),
            // ---
            schemars::json_schema!({
                "description": r"AES GCM using 256-bit key",
                "const": "A256GCM",
            }),
        ];

        let description = r#"JSON Web Encryption "enc" parameter"#;
        schemars::json_schema!({
            "description": description,
            "anyOf": enums,
        })
    }
}

/// 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() -> std::borrow::Cow<'static, str> {
        std::borrow::Cow::Borrowed("JsonWebEncryptionCompressionAlgorithm")
    }

    fn json_schema(_gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
        let enums = vec![
            // ---
            schemars::json_schema!({
                "description": r"DEFLATE",
                "const": "DEF",
            }),
        ];

        let description = r"JSON Web Encryption Compression Algorithm";
        schemars::json_schema!({
            "description": description,
            "anyOf": enums,
        })
    }
}

/// 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() -> std::borrow::Cow<'static, str> {
        std::borrow::Cow::Borrowed("JsonWebKeyType")
    }

    fn json_schema(_gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
        let enums = vec![
            // ---
            schemars::json_schema!({
                "description": r"Elliptic Curve",
                "const": "EC",
            }),
            // ---
            schemars::json_schema!({
                "description": r"RSA",
                "const": "RSA",
            }),
            // ---
            schemars::json_schema!({
                "description": r"Octet sequence",
                "const": "oct",
            }),
            // ---
            schemars::json_schema!({
                "description": r"Octet string key pairs",
                "const": "OKP",
            }),
        ];

        let description = r"JSON Web Key Type";
        schemars::json_schema!({
            "description": description,
            "anyOf": enums,
        })
    }
}

/// 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() -> std::borrow::Cow<'static, str> {
        std::borrow::Cow::Borrowed("JsonWebKeyEcEllipticCurve")
    }

    fn json_schema(_gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
        let enums = vec![
            // ---
            schemars::json_schema!({
                "description": r"P-256 Curve",
                "const": "P-256",
            }),
            // ---
            schemars::json_schema!({
                "description": r"P-384 Curve",
                "const": "P-384",
            }),
            // ---
            schemars::json_schema!({
                "description": r"P-521 Curve",
                "const": "P-521",
            }),
            // ---
            schemars::json_schema!({
                "description": r"SECG secp256k1 curve",
                "const": "secp256k1",
            }),
        ];

        let description = r"JSON Web Key EC Elliptic Curve";
        schemars::json_schema!({
            "description": description,
            "anyOf": enums,
        })
    }
}

/// 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() -> std::borrow::Cow<'static, str> {
        std::borrow::Cow::Borrowed("JsonWebKeyOkpEllipticCurve")
    }

    fn json_schema(_gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
        let enums = vec![
            // ---
            schemars::json_schema!({
                "description": r"Ed25519 signature algorithm key pairs",
                "const": "Ed25519",
            }),
            // ---
            schemars::json_schema!({
                "description": r"Ed448 signature algorithm key pairs",
                "const": "Ed448",
            }),
            // ---
            schemars::json_schema!({
                "description": r"X25519 function key pairs",
                "const": "X25519",
            }),
            // ---
            schemars::json_schema!({
                "description": r"X448 function key pairs",
                "const": "X448",
            }),
        ];

        let description = r"JSON Web Key OKP Elliptic Curve";
        schemars::json_schema!({
            "description": description,
            "anyOf": enums,
        })
    }
}

/// 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() -> std::borrow::Cow<'static, str> {
        std::borrow::Cow::Borrowed("JsonWebKeyUse")
    }

    fn json_schema(_gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
        let enums = vec![
            // ---
            schemars::json_schema!({
                "description": r"Digital Signature or MAC",
                "const": "sig",
            }),
            // ---
            schemars::json_schema!({
                "description": r"Encryption",
                "const": "enc",
            }),
        ];

        let description = r"JSON Web Key Use";
        schemars::json_schema!({
            "description": description,
            "anyOf": enums,
        })
    }
}

/// 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() -> std::borrow::Cow<'static, str> {
        std::borrow::Cow::Borrowed("JsonWebKeyOperation")
    }

    fn json_schema(_gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
        let enums = vec![
            // ---
            schemars::json_schema!({
                "description": r"Compute digital signature or MAC",
                "const": "sign",
            }),
            // ---
            schemars::json_schema!({
                "description": r"Verify digital signature or MAC",
                "const": "verify",
            }),
            // ---
            schemars::json_schema!({
                "description": r"Encrypt content",
                "const": "encrypt",
            }),
            // ---
            schemars::json_schema!({
                "description": r"Decrypt content and validate decryption, if applicable",
                "const": "decrypt",
            }),
            // ---
            schemars::json_schema!({
                "description": r"Encrypt key",
                "const": "wrapKey",
            }),
            // ---
            schemars::json_schema!({
                "description": r"Decrypt key and validate decryption, if applicable",
                "const": "unwrapKey",
            }),
            // ---
            schemars::json_schema!({
                "description": r"Derive key",
                "const": "deriveKey",
            }),
            // ---
            schemars::json_schema!({
                "description": r"Derive bits not to be used as a key",
                "const": "deriveBits",
            }),
        ];

        let description = r"JSON Web Key Operation";
        schemars::json_schema!({
            "description": description,
            "anyOf": enums,
        })
    }
}
