From 311cad47c2c84df3487592519264f0e034a24e41 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Wed, 1 Feb 2023 14:20:45 +0100 Subject: [PATCH] iana: manually implement JsonSchema/Display/FromStr/Serialize/Deserialize This removes the dependency on serde_with and parse-display, and makes the serde & schemars dependencies optional --- Cargo.lock | 3 +- crates/iana-codegen/src/gen.rs | 261 +++++ crates/iana-codegen/src/main.rs | 78 +- crates/iana/Cargo.toml | 10 +- crates/iana/src/jose.rs | 1824 ++++++++++++++++++++++++++----- crates/iana/src/lib.rs | 25 +- crates/iana/src/oauth.rs | 648 ++++++++--- docs/config.schema.json | 185 +--- 8 files changed, 2424 insertions(+), 610 deletions(-) create mode 100644 crates/iana-codegen/src/gen.rs diff --git a/Cargo.lock b/Cargo.lock index 95e3a471..a9af5f4a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2975,9 +2975,8 @@ dependencies = [ name = "mas-iana" version = "0.1.0" dependencies = [ - "parse-display", "schemars", - "serde_with", + "serde", ] [[package]] diff --git a/crates/iana-codegen/src/gen.rs b/crates/iana-codegen/src/gen.rs new file mode 100644 index 00000000..5f403708 --- /dev/null +++ b/crates/iana-codegen/src/gen.rs @@ -0,0 +1,261 @@ +// Copyright 2023 The Matrix.org Foundation C.I.C. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::traits::{EnumMember, Section}; + +pub fn struct_def( + f: &mut std::fmt::Formatter<'_>, + section: &Section, + list: &[EnumMember], + is_exhaustive: bool, +) -> std::fmt::Result { + write!( + f, + r#"/// {} +/// +/// Source: <{}> +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]"#, + section.doc, + section.url.unwrap(), + )?; + + if !is_exhaustive { + write!( + f, + r#" +#[non_exhaustive]"# + )?; + } + + write!( + f, + r#" +pub enum {} {{"#, + section.key, + )?; + for member in list { + writeln!(f)?; + if let Some(description) = &member.description { + writeln!(f, " /// {description}")?; + } else { + writeln!(f, " /// `{}`", member.value)?; + } + writeln!(f, " {},", member.enum_name)?; + } + + if !is_exhaustive { + // Add a variant for custom enums + writeln!(f)?; + writeln!(f, " /// An unknown value.")?; + writeln!(f, " Unknown(String),")?; + } + + writeln!(f, "}}") +} + +pub fn display_impl( + f: &mut std::fmt::Formatter<'_>, + section: &Section, + list: &[EnumMember], + is_exhaustive: bool, +) -> std::fmt::Result { + write!( + f, + r#"impl core::fmt::Display for {} {{ + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {{ + match self {{"#, + section.key, + )?; + + for member in list { + write!( + f, + r#" + Self::{} => write!(f, "{}"),"#, + member.enum_name, member.value + )?; + } + + if !is_exhaustive { + write!( + f, + r#" + Self::Unknown(value) => write!(f, "{{value}}"),"# + )?; + } + + writeln!( + f, + r#" + }} + }} +}}"#, + ) +} + +pub fn from_str_impl( + f: &mut std::fmt::Formatter<'_>, + section: &Section, + list: &[EnumMember], + is_exhaustive: bool, +) -> std::fmt::Result { + let err_ty = if is_exhaustive { + "crate::ParseError" + } else { + "core::convert::Infallible" + }; + write!( + f, + r#"impl core::str::FromStr for {} {{ + type Err = {err_ty}; + + fn from_str(s: &str) -> Result {{ + match s {{"#, + section.key, + )?; + + for member in list { + write!( + f, + r#" + "{}" => Ok(Self::{}),"#, + member.value, member.enum_name + )?; + } + + if is_exhaustive { + write!( + f, + r#" + _ => Err(crate::ParseError::new()),"# + )?; + } else { + write!( + f, + r#" + value => Ok(Self::Unknown(value.to_owned())),"#, + )?; + } + + writeln!( + f, + r#" + }} + }} +}}"#, + ) +} + +pub fn json_schema_impl( + f: &mut std::fmt::Formatter<'_>, + section: &Section, + list: &[EnumMember], +) -> std::fmt::Result { + write!( + f, + r#"#[cfg(feature = "schemars")] +impl schemars::JsonSchema for {} {{ + fn schema_name() -> String {{ + "{}".to_owned() + }} + + #[allow(clippy::too_many_lines)] + fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {{ + let enums = vec!["#, + section.key, section.key, + )?; + + for member in list { + write!( + f, + r#" + // --- + schemars::schema::SchemaObject {{"#, + )?; + + if let Some(description) = &member.description { + write!( + f, + r##" + metadata: Some(Box::new(schemars::schema::Metadata {{ + description: Some( + // --- + r#"{description}"#.to_owned(), + ), + ..Default::default() + }})),"##, + )?; + } + + write!( + f, + r#" + const_value: Some("{}".into()), + ..Default::default() + }} + .into(),"#, + member.value + )?; + } + + writeln!( + f, + r##" + ]; + + let description = r#"{}"#; + 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() + }} +}}"##, + section.doc, + ) +} + +pub fn serde_impl(f: &mut std::fmt::Formatter<'_>, section: &Section) -> std::fmt::Result { + writeln!( + f, + r#"#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for {} {{ + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + {{ + let s = String::deserialize(deserializer)?; + core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom) + }} +}} + +#[cfg(feature = "serde")] +impl serde::Serialize for {} {{ + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + {{ + serializer.serialize_str(&self.to_string()) + }} +}}"#, + section.key, section.key, + ) +} diff --git a/crates/iana-codegen/src/main.rs b/crates/iana-codegen/src/main.rs index 9c5a7d55..f3303be2 100644 --- a/crates/iana-codegen/src/main.rs +++ b/crates/iana-codegen/src/main.rs @@ -1,4 +1,4 @@ -// Copyright 2022 The Matrix.org Foundation C.I.C. +// Copyright 2022, 2023 The Matrix.org Foundation C.I.C. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ use reqwest::Client; use tokio::io::AsyncWriteExt; use tracing::Level; +mod gen; pub mod jose; pub mod oauth; pub mod traits; @@ -82,10 +83,11 @@ impl File { } impl Display for File { + #[allow(clippy::too_many_lines)] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { writeln!( f, - r#"// Copyright 2022 The Matrix.org Foundation C.I.C. + r#"// Copyright 2023 The Matrix.org Foundation C.I.C. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -102,11 +104,7 @@ impl Display for File { //! Enums from the {:?} IANA registry //! See <{}> -// Do not edit this file manually - -use parse_display::{{Display, FromStr}}; -use schemars::JsonSchema; -use serde_with::{{DeserializeFromStr, SerializeDisplay}};"#, +// Do not edit this file manually"#, self.registry_name, self.registry_url, )?; @@ -116,61 +114,25 @@ use serde_with::{{DeserializeFromStr, SerializeDisplay}};"#, }; let is_exhaustive = section.key == "OAuthAuthorizationEndpointResponseType"; + writeln!(f)?; - let non_exhaustive_attr = if is_exhaustive { - "" - } else { - "\n#[non_exhaustive]" - }; + self::gen::struct_def(f, section, list, is_exhaustive)?; + writeln!(f)?; - write!( - f, - r#" -/// {} -/// -/// Source: <{}> -#[derive( - Debug, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Display, - FromStr, - SerializeDisplay, - DeserializeFromStr, - JsonSchema, -)]{} -pub enum {} {{"#, - section.doc, - section.url.unwrap(), - non_exhaustive_attr, - section.key, - )?; - for member in list { - writeln!(f)?; - if let Some(description) = &member.description { - writeln!(f, " /// {description}")?; - } else { - writeln!(f, " /// `{}`", member.value)?; - } - writeln!(f, " #[schemars(rename = \"{}\")]", member.value)?; - writeln!(f, " #[display(\"{}\")]", member.value)?; - writeln!(f, " {},", member.enum_name)?; - } + // Write the Display impl + self::gen::display_impl(f, section, list, is_exhaustive)?; + writeln!(f)?; - if !is_exhaustive { - // Add a variant for custom enums - writeln!(f)?; - writeln!(f, " /// An unknown value.")?; - writeln!(f, " #[display(\"{{0}}\")]")?; - writeln!(f, " #[schemars(skip)]")?; - writeln!(f, " Unknown(String),")?; - } + // Write the FromStr impl + self::gen::from_str_impl(f, section, list, is_exhaustive)?; + writeln!(f)?; - writeln!(f, "}}")?; + // Write the Serialize and Deserialize impls + self::gen::serde_impl(f, section)?; + writeln!(f)?; + + // Write the JsonSchema impl + self::gen::json_schema_impl(f, section, list)?; } Ok(()) diff --git a/crates/iana/Cargo.toml b/crates/iana/Cargo.toml index bf27b6b7..53b0ae6f 100644 --- a/crates/iana/Cargo.toml +++ b/crates/iana/Cargo.toml @@ -6,6 +6,10 @@ edition = "2021" license = "Apache-2.0" [dependencies] -serde_with = "2.2.0" -schemars = "0.8.11" -parse-display = "0.8.0" +serde = { version = "1.0.130", optional = true } +schemars = { version = "0.8.11", default-features = false, optional = true } + +[features] +default = ["serde", "schemars"] +serde = ["dep:serde"] +schemars = ["dep:schemars"] diff --git a/crates/iana/src/jose.rs b/crates/iana/src/jose.rs index cc4a16c2..99f031e5 100644 --- a/crates/iana/src/jose.rs +++ b/crates/iana/src/jose.rs @@ -1,4 +1,4 @@ -// Copyright 2022 The Matrix.org Foundation C.I.C. +// Copyright 2023 The Matrix.org Foundation C.I.C. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,546 +17,1820 @@ // Do not edit this file manually -use parse_display::{Display, FromStr}; -use schemars::JsonSchema; -use serde_with::{DeserializeFromStr, SerializeDisplay}; - /// JSON Web Signature "alg" parameter /// /// Source: -#[derive( - Debug, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Display, - FromStr, - SerializeDisplay, - DeserializeFromStr, - JsonSchema, -)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[non_exhaustive] pub enum JsonWebSignatureAlg { /// HMAC using SHA-256 - #[schemars(rename = "HS256")] - #[display("HS256")] Hs256, /// HMAC using SHA-384 - #[schemars(rename = "HS384")] - #[display("HS384")] Hs384, /// HMAC using SHA-512 - #[schemars(rename = "HS512")] - #[display("HS512")] Hs512, /// RSASSA-PKCS1-v1_5 using SHA-256 - #[schemars(rename = "RS256")] - #[display("RS256")] Rs256, /// RSASSA-PKCS1-v1_5 using SHA-384 - #[schemars(rename = "RS384")] - #[display("RS384")] Rs384, /// RSASSA-PKCS1-v1_5 using SHA-512 - #[schemars(rename = "RS512")] - #[display("RS512")] Rs512, /// ECDSA using P-256 and SHA-256 - #[schemars(rename = "ES256")] - #[display("ES256")] Es256, /// ECDSA using P-384 and SHA-384 - #[schemars(rename = "ES384")] - #[display("ES384")] Es384, /// ECDSA using P-521 and SHA-512 - #[schemars(rename = "ES512")] - #[display("ES512")] Es512, /// RSASSA-PSS using SHA-256 and MGF1 with SHA-256 - #[schemars(rename = "PS256")] - #[display("PS256")] Ps256, /// RSASSA-PSS using SHA-384 and MGF1 with SHA-384 - #[schemars(rename = "PS384")] - #[display("PS384")] Ps384, /// RSASSA-PSS using SHA-512 and MGF1 with SHA-512 - #[schemars(rename = "PS512")] - #[display("PS512")] Ps512, /// No digital signature or MAC performed - #[schemars(rename = "none")] - #[display("none")] None, /// EdDSA signature algorithms - #[schemars(rename = "EdDSA")] - #[display("EdDSA")] EdDsa, /// ECDSA using secp256k1 curve and SHA-256 - #[schemars(rename = "ES256K")] - #[display("ES256K")] Es256K, /// An unknown value. - #[display("{0}")] - #[schemars(skip)] 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::Unknown(value) => write!(f, "{value}"), + } + } +} + +impl core::str::FromStr for JsonWebSignatureAlg { + type Err = core::convert::Infallible; + + fn from_str(s: &str) -> Result { + 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), + value => Ok(Self::Unknown(value.to_owned())), + } + } +} + +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for JsonWebSignatureAlg { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom) + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for JsonWebSignatureAlg { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for JsonWebSignatureAlg { + fn schema_name() -> String { + "JsonWebSignatureAlg".to_owned() + } + + #[allow(clippy::too_many_lines)] + fn json_schema(_gen: &mut schemars::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(), + ]; + + 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: -#[derive( - Debug, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Display, - FromStr, - SerializeDisplay, - DeserializeFromStr, - JsonSchema, -)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[non_exhaustive] pub enum JsonWebEncryptionAlg { /// RSAES-PKCS1-v1_5 - #[schemars(rename = "RSA1_5")] - #[display("RSA1_5")] Rsa15, /// RSAES OAEP using default parameters - #[schemars(rename = "RSA-OAEP")] - #[display("RSA-OAEP")] RsaOaep, /// RSAES OAEP using SHA-256 and MGF1 with SHA-256 - #[schemars(rename = "RSA-OAEP-256")] - #[display("RSA-OAEP-256")] RsaOaep256, /// AES Key Wrap using 128-bit key - #[schemars(rename = "A128KW")] - #[display("A128KW")] A128Kw, /// AES Key Wrap using 192-bit key - #[schemars(rename = "A192KW")] - #[display("A192KW")] A192Kw, /// AES Key Wrap using 256-bit key - #[schemars(rename = "A256KW")] - #[display("A256KW")] A256Kw, /// Direct use of a shared symmetric key - #[schemars(rename = "dir")] - #[display("dir")] Dir, /// ECDH-ES using Concat KDF - #[schemars(rename = "ECDH-ES")] - #[display("ECDH-ES")] EcdhEs, /// ECDH-ES using Concat KDF and "A128KW" wrapping - #[schemars(rename = "ECDH-ES+A128KW")] - #[display("ECDH-ES+A128KW")] EcdhEsA128Kw, /// ECDH-ES using Concat KDF and "A192KW" wrapping - #[schemars(rename = "ECDH-ES+A192KW")] - #[display("ECDH-ES+A192KW")] EcdhEsA192Kw, /// ECDH-ES using Concat KDF and "A256KW" wrapping - #[schemars(rename = "ECDH-ES+A256KW")] - #[display("ECDH-ES+A256KW")] EcdhEsA256Kw, /// Key wrapping with AES GCM using 128-bit key - #[schemars(rename = "A128GCMKW")] - #[display("A128GCMKW")] A128Gcmkw, /// Key wrapping with AES GCM using 192-bit key - #[schemars(rename = "A192GCMKW")] - #[display("A192GCMKW")] A192Gcmkw, /// Key wrapping with AES GCM using 256-bit key - #[schemars(rename = "A256GCMKW")] - #[display("A256GCMKW")] A256Gcmkw, /// PBES2 with HMAC SHA-256 and "A128KW" wrapping - #[schemars(rename = "PBES2-HS256+A128KW")] - #[display("PBES2-HS256+A128KW")] Pbes2Hs256A128Kw, /// PBES2 with HMAC SHA-384 and "A192KW" wrapping - #[schemars(rename = "PBES2-HS384+A192KW")] - #[display("PBES2-HS384+A192KW")] Pbes2Hs384A192Kw, /// PBES2 with HMAC SHA-512 and "A256KW" wrapping - #[schemars(rename = "PBES2-HS512+A256KW")] - #[display("PBES2-HS512+A256KW")] Pbes2Hs512A256Kw, /// RSA-OAEP using SHA-384 and MGF1 with SHA-384 - #[schemars(rename = "RSA-OAEP-384")] - #[display("RSA-OAEP-384")] RsaOaep384, /// RSA-OAEP using SHA-512 and MGF1 with SHA-512 - #[schemars(rename = "RSA-OAEP-512")] - #[display("RSA-OAEP-512")] RsaOaep512, /// An unknown value. - #[display("{0}")] - #[schemars(skip)] 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 { + 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())), + } + } +} + +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for JsonWebEncryptionAlg { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom) + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for JsonWebEncryptionAlg { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for JsonWebEncryptionAlg { + fn schema_name() -> String { + "JsonWebEncryptionAlg".to_owned() + } + + #[allow(clippy::too_many_lines)] + fn json_schema(_gen: &mut schemars::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: -#[derive( - Debug, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Display, - FromStr, - SerializeDisplay, - DeserializeFromStr, - JsonSchema, -)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[non_exhaustive] pub enum JsonWebEncryptionEnc { /// AES_128_CBC_HMAC_SHA_256 authenticated encryption algorithm - #[schemars(rename = "A128CBC-HS256")] - #[display("A128CBC-HS256")] A128CbcHs256, /// AES_192_CBC_HMAC_SHA_384 authenticated encryption algorithm - #[schemars(rename = "A192CBC-HS384")] - #[display("A192CBC-HS384")] A192CbcHs384, /// AES_256_CBC_HMAC_SHA_512 authenticated encryption algorithm - #[schemars(rename = "A256CBC-HS512")] - #[display("A256CBC-HS512")] A256CbcHs512, /// AES GCM using 128-bit key - #[schemars(rename = "A128GCM")] - #[display("A128GCM")] A128Gcm, /// AES GCM using 192-bit key - #[schemars(rename = "A192GCM")] - #[display("A192GCM")] A192Gcm, /// AES GCM using 256-bit key - #[schemars(rename = "A256GCM")] - #[display("A256GCM")] A256Gcm, /// An unknown value. - #[display("{0}")] - #[schemars(skip)] 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 { + 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())), + } + } +} + +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for JsonWebEncryptionEnc { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom) + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for JsonWebEncryptionEnc { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for JsonWebEncryptionEnc { + fn schema_name() -> String { + "JsonWebEncryptionEnc".to_owned() + } + + #[allow(clippy::too_many_lines)] + fn json_schema(_gen: &mut schemars::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: -#[derive( - Debug, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Display, - FromStr, - SerializeDisplay, - DeserializeFromStr, - JsonSchema, -)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[non_exhaustive] pub enum JsonWebEncryptionCompressionAlgorithm { /// DEFLATE - #[schemars(rename = "DEF")] - #[display("DEF")] Def, /// An unknown value. - #[display("{0}")] - #[schemars(skip)] 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 { + match s { + "DEF" => Ok(Self::Def), + value => Ok(Self::Unknown(value.to_owned())), + } + } +} + +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for JsonWebEncryptionCompressionAlgorithm { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom) + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for JsonWebEncryptionCompressionAlgorithm { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for JsonWebEncryptionCompressionAlgorithm { + fn schema_name() -> String { + "JsonWebEncryptionCompressionAlgorithm".to_owned() + } + + #[allow(clippy::too_many_lines)] + fn json_schema(_gen: &mut schemars::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: -#[derive( - Debug, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Display, - FromStr, - SerializeDisplay, - DeserializeFromStr, - JsonSchema, -)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[non_exhaustive] pub enum JsonWebKeyType { /// Elliptic Curve - #[schemars(rename = "EC")] - #[display("EC")] Ec, /// RSA - #[schemars(rename = "RSA")] - #[display("RSA")] Rsa, /// Octet sequence - #[schemars(rename = "oct")] - #[display("oct")] Oct, /// Octet string key pairs - #[schemars(rename = "OKP")] - #[display("OKP")] Okp, /// An unknown value. - #[display("{0}")] - #[schemars(skip)] 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 { + 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())), + } + } +} + +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for JsonWebKeyType { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom) + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for JsonWebKeyType { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for JsonWebKeyType { + fn schema_name() -> String { + "JsonWebKeyType".to_owned() + } + + #[allow(clippy::too_many_lines)] + fn json_schema(_gen: &mut schemars::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: -#[derive( - Debug, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Display, - FromStr, - SerializeDisplay, - DeserializeFromStr, - JsonSchema, -)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[non_exhaustive] pub enum JsonWebKeyEcEllipticCurve { /// P-256 Curve - #[schemars(rename = "P-256")] - #[display("P-256")] P256, /// P-384 Curve - #[schemars(rename = "P-384")] - #[display("P-384")] P384, /// P-521 Curve - #[schemars(rename = "P-521")] - #[display("P-521")] P521, /// SECG secp256k1 curve - #[schemars(rename = "secp256k1")] - #[display("secp256k1")] Secp256K1, /// An unknown value. - #[display("{0}")] - #[schemars(skip)] 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 { + 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())), + } + } +} + +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for JsonWebKeyEcEllipticCurve { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom) + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for JsonWebKeyEcEllipticCurve { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for JsonWebKeyEcEllipticCurve { + fn schema_name() -> String { + "JsonWebKeyEcEllipticCurve".to_owned() + } + + #[allow(clippy::too_many_lines)] + fn json_schema(_gen: &mut schemars::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: -#[derive( - Debug, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Display, - FromStr, - SerializeDisplay, - DeserializeFromStr, - JsonSchema, -)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[non_exhaustive] pub enum JsonWebKeyOkpEllipticCurve { /// Ed25519 signature algorithm key pairs - #[schemars(rename = "Ed25519")] - #[display("Ed25519")] Ed25519, /// Ed448 signature algorithm key pairs - #[schemars(rename = "Ed448")] - #[display("Ed448")] Ed448, /// X25519 function key pairs - #[schemars(rename = "X25519")] - #[display("X25519")] X25519, /// X448 function key pairs - #[schemars(rename = "X448")] - #[display("X448")] X448, /// An unknown value. - #[display("{0}")] - #[schemars(skip)] 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 { + 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())), + } + } +} + +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for JsonWebKeyOkpEllipticCurve { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom) + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for JsonWebKeyOkpEllipticCurve { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for JsonWebKeyOkpEllipticCurve { + fn schema_name() -> String { + "JsonWebKeyOkpEllipticCurve".to_owned() + } + + #[allow(clippy::too_many_lines)] + fn json_schema(_gen: &mut schemars::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: -#[derive( - Debug, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Display, - FromStr, - SerializeDisplay, - DeserializeFromStr, - JsonSchema, -)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[non_exhaustive] pub enum JsonWebKeyUse { /// Digital Signature or MAC - #[schemars(rename = "sig")] - #[display("sig")] Sig, /// Encryption - #[schemars(rename = "enc")] - #[display("enc")] Enc, /// An unknown value. - #[display("{0}")] - #[schemars(skip)] 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 { + match s { + "sig" => Ok(Self::Sig), + "enc" => Ok(Self::Enc), + value => Ok(Self::Unknown(value.to_owned())), + } + } +} + +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for JsonWebKeyUse { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom) + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for JsonWebKeyUse { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for JsonWebKeyUse { + fn schema_name() -> String { + "JsonWebKeyUse".to_owned() + } + + #[allow(clippy::too_many_lines)] + fn json_schema(_gen: &mut schemars::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: -#[derive( - Debug, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Display, - FromStr, - SerializeDisplay, - DeserializeFromStr, - JsonSchema, -)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[non_exhaustive] pub enum JsonWebKeyOperation { /// Compute digital signature or MAC - #[schemars(rename = "sign")] - #[display("sign")] Sign, /// Verify digital signature or MAC - #[schemars(rename = "verify")] - #[display("verify")] Verify, /// Encrypt content - #[schemars(rename = "encrypt")] - #[display("encrypt")] Encrypt, /// Decrypt content and validate decryption, if applicable - #[schemars(rename = "decrypt")] - #[display("decrypt")] Decrypt, /// Encrypt key - #[schemars(rename = "wrapKey")] - #[display("wrapKey")] WrapKey, /// Decrypt key and validate decryption, if applicable - #[schemars(rename = "unwrapKey")] - #[display("unwrapKey")] UnwrapKey, /// Derive key - #[schemars(rename = "deriveKey")] - #[display("deriveKey")] DeriveKey, /// Derive bits not to be used as a key - #[schemars(rename = "deriveBits")] - #[display("deriveBits")] DeriveBits, /// An unknown value. - #[display("{0}")] - #[schemars(skip)] 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 { + 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())), + } + } +} + +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for JsonWebKeyOperation { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom) + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for JsonWebKeyOperation { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for JsonWebKeyOperation { + fn schema_name() -> String { + "JsonWebKeyOperation".to_owned() + } + + #[allow(clippy::too_many_lines)] + fn json_schema(_gen: &mut schemars::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() + } +} diff --git a/crates/iana/src/lib.rs b/crates/iana/src/lib.rs index 0a118c1a..d5c218c4 100644 --- a/crates/iana/src/lib.rs +++ b/crates/iana/src/lib.rs @@ -27,4 +27,27 @@ pub mod jose; pub mod oauth; -pub use parse_display::ParseError; +/// An error that occurred while parsing a value from a string. +pub struct ParseError { + _private: (), +} + +impl ParseError { + fn new() -> Self { + Self { _private: () } + } +} + +impl core::fmt::Debug for ParseError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("ParseError") + } +} + +impl core::fmt::Display for ParseError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("Parse error") + } +} + +impl std::error::Error for ParseError {} diff --git a/crates/iana/src/oauth.rs b/crates/iana/src/oauth.rs index 4014571c..677a4df7 100644 --- a/crates/iana/src/oauth.rs +++ b/crates/iana/src/oauth.rs @@ -1,4 +1,4 @@ -// Copyright 2022 The Matrix.org Foundation C.I.C. +// Copyright 2023 The Matrix.org Foundation C.I.C. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,240 +17,630 @@ // Do not edit this file manually -use parse_display::{Display, FromStr}; -use schemars::JsonSchema; -use serde_with::{DeserializeFromStr, SerializeDisplay}; - /// OAuth Access Token Type /// /// Source: -#[derive( - Debug, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Display, - FromStr, - SerializeDisplay, - DeserializeFromStr, - JsonSchema, -)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[non_exhaustive] pub enum OAuthAccessTokenType { /// `Bearer` - #[schemars(rename = "Bearer")] - #[display("Bearer")] Bearer, /// `N_A` - #[schemars(rename = "N_A")] - #[display("N_A")] Na, /// `PoP` - #[schemars(rename = "PoP")] - #[display("PoP")] PoP, /// An unknown value. - #[display("{0}")] - #[schemars(skip)] Unknown(String), } +impl core::fmt::Display for OAuthAccessTokenType { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::Bearer => write!(f, "Bearer"), + Self::Na => write!(f, "N_A"), + Self::PoP => write!(f, "PoP"), + Self::Unknown(value) => write!(f, "{value}"), + } + } +} + +impl core::str::FromStr for OAuthAccessTokenType { + type Err = core::convert::Infallible; + + fn from_str(s: &str) -> Result { + match s { + "Bearer" => Ok(Self::Bearer), + "N_A" => Ok(Self::Na), + "PoP" => Ok(Self::PoP), + value => Ok(Self::Unknown(value.to_owned())), + } + } +} + +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for OAuthAccessTokenType { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom) + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for OAuthAccessTokenType { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for OAuthAccessTokenType { + fn schema_name() -> String { + "OAuthAccessTokenType".to_owned() + } + + #[allow(clippy::too_many_lines)] + fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let enums = vec![ + // --- + schemars::schema::SchemaObject { + const_value: Some("Bearer".into()), + ..Default::default() + } + .into(), + // --- + schemars::schema::SchemaObject { + const_value: Some("N_A".into()), + ..Default::default() + } + .into(), + // --- + schemars::schema::SchemaObject { + const_value: Some("PoP".into()), + ..Default::default() + } + .into(), + ]; + + let description = r#"OAuth Access Token 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() + } +} + /// OAuth Authorization Endpoint Response Type /// /// Source: -#[derive( - Debug, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Display, - FromStr, - SerializeDisplay, - DeserializeFromStr, - JsonSchema, -)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum OAuthAuthorizationEndpointResponseType { /// `code` - #[schemars(rename = "code")] - #[display("code")] Code, /// `code id_token` - #[schemars(rename = "code id_token")] - #[display("code id_token")] CodeIdToken, /// `code id_token token` - #[schemars(rename = "code id_token token")] - #[display("code id_token token")] CodeIdTokenToken, /// `code token` - #[schemars(rename = "code token")] - #[display("code token")] CodeToken, /// `id_token` - #[schemars(rename = "id_token")] - #[display("id_token")] IdToken, /// `id_token token` - #[schemars(rename = "id_token token")] - #[display("id_token token")] IdTokenToken, /// `none` - #[schemars(rename = "none")] - #[display("none")] None, /// `token` - #[schemars(rename = "token")] - #[display("token")] Token, } +impl core::fmt::Display for OAuthAuthorizationEndpointResponseType { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::Code => write!(f, "code"), + Self::CodeIdToken => write!(f, "code id_token"), + Self::CodeIdTokenToken => write!(f, "code id_token token"), + Self::CodeToken => write!(f, "code token"), + Self::IdToken => write!(f, "id_token"), + Self::IdTokenToken => write!(f, "id_token token"), + Self::None => write!(f, "none"), + Self::Token => write!(f, "token"), + } + } +} + +impl core::str::FromStr for OAuthAuthorizationEndpointResponseType { + type Err = crate::ParseError; + + fn from_str(s: &str) -> Result { + match s { + "code" => Ok(Self::Code), + "code id_token" => Ok(Self::CodeIdToken), + "code id_token token" => Ok(Self::CodeIdTokenToken), + "code token" => Ok(Self::CodeToken), + "id_token" => Ok(Self::IdToken), + "id_token token" => Ok(Self::IdTokenToken), + "none" => Ok(Self::None), + "token" => Ok(Self::Token), + _ => Err(crate::ParseError::new()), + } + } +} + +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for OAuthAuthorizationEndpointResponseType { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom) + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for OAuthAuthorizationEndpointResponseType { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for OAuthAuthorizationEndpointResponseType { + fn schema_name() -> String { + "OAuthAuthorizationEndpointResponseType".to_owned() + } + + #[allow(clippy::too_many_lines)] + fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let enums = vec![ + // --- + schemars::schema::SchemaObject { + const_value: Some("code".into()), + ..Default::default() + } + .into(), + // --- + schemars::schema::SchemaObject { + const_value: Some("code id_token".into()), + ..Default::default() + } + .into(), + // --- + schemars::schema::SchemaObject { + const_value: Some("code id_token token".into()), + ..Default::default() + } + .into(), + // --- + schemars::schema::SchemaObject { + const_value: Some("code token".into()), + ..Default::default() + } + .into(), + // --- + schemars::schema::SchemaObject { + const_value: Some("id_token".into()), + ..Default::default() + } + .into(), + // --- + schemars::schema::SchemaObject { + const_value: Some("id_token token".into()), + ..Default::default() + } + .into(), + // --- + schemars::schema::SchemaObject { + const_value: Some("none".into()), + ..Default::default() + } + .into(), + // --- + schemars::schema::SchemaObject { + const_value: Some("token".into()), + ..Default::default() + } + .into(), + ]; + + let description = r#"OAuth Authorization Endpoint Response 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() + } +} + /// OAuth Token Type Hint /// /// Source: -#[derive( - Debug, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Display, - FromStr, - SerializeDisplay, - DeserializeFromStr, - JsonSchema, -)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[non_exhaustive] pub enum OAuthTokenTypeHint { /// `access_token` - #[schemars(rename = "access_token")] - #[display("access_token")] AccessToken, /// `refresh_token` - #[schemars(rename = "refresh_token")] - #[display("refresh_token")] RefreshToken, /// `pct` - #[schemars(rename = "pct")] - #[display("pct")] Pct, /// An unknown value. - #[display("{0}")] - #[schemars(skip)] Unknown(String), } +impl core::fmt::Display for OAuthTokenTypeHint { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::AccessToken => write!(f, "access_token"), + Self::RefreshToken => write!(f, "refresh_token"), + Self::Pct => write!(f, "pct"), + Self::Unknown(value) => write!(f, "{value}"), + } + } +} + +impl core::str::FromStr for OAuthTokenTypeHint { + type Err = core::convert::Infallible; + + fn from_str(s: &str) -> Result { + match s { + "access_token" => Ok(Self::AccessToken), + "refresh_token" => Ok(Self::RefreshToken), + "pct" => Ok(Self::Pct), + value => Ok(Self::Unknown(value.to_owned())), + } + } +} + +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for OAuthTokenTypeHint { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom) + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for OAuthTokenTypeHint { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for OAuthTokenTypeHint { + fn schema_name() -> String { + "OAuthTokenTypeHint".to_owned() + } + + #[allow(clippy::too_many_lines)] + fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let enums = vec![ + // --- + schemars::schema::SchemaObject { + const_value: Some("access_token".into()), + ..Default::default() + } + .into(), + // --- + schemars::schema::SchemaObject { + const_value: Some("refresh_token".into()), + ..Default::default() + } + .into(), + // --- + schemars::schema::SchemaObject { + const_value: Some("pct".into()), + ..Default::default() + } + .into(), + ]; + + let description = r#"OAuth Token Type Hint"#; + 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() + } +} + /// OAuth Token Endpoint Authentication Method /// /// Source: -#[derive( - Debug, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Display, - FromStr, - SerializeDisplay, - DeserializeFromStr, - JsonSchema, -)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[non_exhaustive] pub enum OAuthClientAuthenticationMethod { /// `none` - #[schemars(rename = "none")] - #[display("none")] None, /// `client_secret_post` - #[schemars(rename = "client_secret_post")] - #[display("client_secret_post")] ClientSecretPost, /// `client_secret_basic` - #[schemars(rename = "client_secret_basic")] - #[display("client_secret_basic")] ClientSecretBasic, /// `client_secret_jwt` - #[schemars(rename = "client_secret_jwt")] - #[display("client_secret_jwt")] ClientSecretJwt, /// `private_key_jwt` - #[schemars(rename = "private_key_jwt")] - #[display("private_key_jwt")] PrivateKeyJwt, /// `tls_client_auth` - #[schemars(rename = "tls_client_auth")] - #[display("tls_client_auth")] TlsClientAuth, /// `self_signed_tls_client_auth` - #[schemars(rename = "self_signed_tls_client_auth")] - #[display("self_signed_tls_client_auth")] SelfSignedTlsClientAuth, /// An unknown value. - #[display("{0}")] - #[schemars(skip)] Unknown(String), } +impl core::fmt::Display for OAuthClientAuthenticationMethod { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::None => write!(f, "none"), + Self::ClientSecretPost => write!(f, "client_secret_post"), + Self::ClientSecretBasic => write!(f, "client_secret_basic"), + Self::ClientSecretJwt => write!(f, "client_secret_jwt"), + Self::PrivateKeyJwt => write!(f, "private_key_jwt"), + Self::TlsClientAuth => write!(f, "tls_client_auth"), + Self::SelfSignedTlsClientAuth => write!(f, "self_signed_tls_client_auth"), + Self::Unknown(value) => write!(f, "{value}"), + } + } +} + +impl core::str::FromStr for OAuthClientAuthenticationMethod { + type Err = core::convert::Infallible; + + fn from_str(s: &str) -> Result { + match s { + "none" => Ok(Self::None), + "client_secret_post" => Ok(Self::ClientSecretPost), + "client_secret_basic" => Ok(Self::ClientSecretBasic), + "client_secret_jwt" => Ok(Self::ClientSecretJwt), + "private_key_jwt" => Ok(Self::PrivateKeyJwt), + "tls_client_auth" => Ok(Self::TlsClientAuth), + "self_signed_tls_client_auth" => Ok(Self::SelfSignedTlsClientAuth), + value => Ok(Self::Unknown(value.to_owned())), + } + } +} + +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for OAuthClientAuthenticationMethod { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom) + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for OAuthClientAuthenticationMethod { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for OAuthClientAuthenticationMethod { + fn schema_name() -> String { + "OAuthClientAuthenticationMethod".to_owned() + } + + #[allow(clippy::too_many_lines)] + fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let enums = vec![ + // --- + schemars::schema::SchemaObject { + const_value: Some("none".into()), + ..Default::default() + } + .into(), + // --- + schemars::schema::SchemaObject { + const_value: Some("client_secret_post".into()), + ..Default::default() + } + .into(), + // --- + schemars::schema::SchemaObject { + const_value: Some("client_secret_basic".into()), + ..Default::default() + } + .into(), + // --- + schemars::schema::SchemaObject { + const_value: Some("client_secret_jwt".into()), + ..Default::default() + } + .into(), + // --- + schemars::schema::SchemaObject { + const_value: Some("private_key_jwt".into()), + ..Default::default() + } + .into(), + // --- + schemars::schema::SchemaObject { + const_value: Some("tls_client_auth".into()), + ..Default::default() + } + .into(), + // --- + schemars::schema::SchemaObject { + const_value: Some("self_signed_tls_client_auth".into()), + ..Default::default() + } + .into(), + ]; + + let description = r#"OAuth Token Endpoint Authentication Method"#; + 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() + } +} + /// PKCE Code Challenge Method /// /// Source: -#[derive( - Debug, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Display, - FromStr, - SerializeDisplay, - DeserializeFromStr, - JsonSchema, -)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[non_exhaustive] pub enum PkceCodeChallengeMethod { /// `plain` - #[schemars(rename = "plain")] - #[display("plain")] Plain, /// `S256` - #[schemars(rename = "S256")] - #[display("S256")] S256, /// An unknown value. - #[display("{0}")] - #[schemars(skip)] Unknown(String), } + +impl core::fmt::Display for PkceCodeChallengeMethod { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::Plain => write!(f, "plain"), + Self::S256 => write!(f, "S256"), + Self::Unknown(value) => write!(f, "{value}"), + } + } +} + +impl core::str::FromStr for PkceCodeChallengeMethod { + type Err = core::convert::Infallible; + + fn from_str(s: &str) -> Result { + match s { + "plain" => Ok(Self::Plain), + "S256" => Ok(Self::S256), + value => Ok(Self::Unknown(value.to_owned())), + } + } +} + +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for PkceCodeChallengeMethod { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + core::str::FromStr::from_str(&s).map_err(serde::de::Error::custom) + } +} + +#[cfg(feature = "serde")] +impl serde::Serialize for PkceCodeChallengeMethod { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +#[cfg(feature = "schemars")] +impl schemars::JsonSchema for PkceCodeChallengeMethod { + fn schema_name() -> String { + "PkceCodeChallengeMethod".to_owned() + } + + #[allow(clippy::too_many_lines)] + fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + let enums = vec![ + // --- + schemars::schema::SchemaObject { + const_value: Some("plain".into()), + ..Default::default() + } + .into(), + // --- + schemars::schema::SchemaObject { + const_value: Some("S256".into()), + ..Default::default() + } + .into(), + ]; + + let description = r#"PKCE Code Challenge Method"#; + 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() + } +} diff --git a/docs/config.schema.json b/docs/config.schema.json index d4dbf185..eb27ef8a 100644 --- a/docs/config.schema.json +++ b/docs/config.schema.json @@ -759,129 +759,81 @@ } }, "JsonWebKeyEcEllipticCurve": { - "description": "JSON Web Key EC Elliptic Curve\n\nSource: ", - "oneOf": [ + "description": "JSON Web Key EC Elliptic Curve", + "anyOf": [ { "description": "P-256 Curve", - "type": "string", - "enum": [ - "P-256" - ] + "const": "P-256" }, { "description": "P-384 Curve", - "type": "string", - "enum": [ - "P-384" - ] + "const": "P-384" }, { "description": "P-521 Curve", - "type": "string", - "enum": [ - "P-521" - ] + "const": "P-521" }, { "description": "SECG secp256k1 curve", - "type": "string", - "enum": [ - "secp256k1" - ] + "const": "secp256k1" } ] }, "JsonWebKeyOkpEllipticCurve": { - "description": "JSON Web Key OKP Elliptic Curve\n\nSource: ", - "oneOf": [ + "description": "JSON Web Key OKP Elliptic Curve", + "anyOf": [ { "description": "Ed25519 signature algorithm key pairs", - "type": "string", - "enum": [ - "Ed25519" - ] + "const": "Ed25519" }, { "description": "Ed448 signature algorithm key pairs", - "type": "string", - "enum": [ - "Ed448" - ] + "const": "Ed448" }, { "description": "X25519 function key pairs", - "type": "string", - "enum": [ - "X25519" - ] + "const": "X25519" }, { "description": "X448 function key pairs", - "type": "string", - "enum": [ - "X448" - ] + "const": "X448" } ] }, "JsonWebKeyOperation": { - "description": "JSON Web Key Operation\n\nSource: ", - "oneOf": [ + "description": "JSON Web Key Operation", + "anyOf": [ { "description": "Compute digital signature or MAC", - "type": "string", - "enum": [ - "sign" - ] + "const": "sign" }, { "description": "Verify digital signature or MAC", - "type": "string", - "enum": [ - "verify" - ] + "const": "verify" }, { "description": "Encrypt content", - "type": "string", - "enum": [ - "encrypt" - ] + "const": "encrypt" }, { "description": "Decrypt content and validate decryption, if applicable", - "type": "string", - "enum": [ - "decrypt" - ] + "const": "decrypt" }, { "description": "Encrypt key", - "type": "string", - "enum": [ - "wrapKey" - ] + "const": "wrapKey" }, { "description": "Decrypt key and validate decryption, if applicable", - "type": "string", - "enum": [ - "unwrapKey" - ] + "const": "unwrapKey" }, { "description": "Derive key", - "type": "string", - "enum": [ - "deriveKey" - ] + "const": "deriveKey" }, { "description": "Derive bits not to be used as a key", - "type": "string", - "enum": [ - "deriveBits" - ] + "const": "deriveBits" } ] }, @@ -900,21 +852,15 @@ } }, "JsonWebKeyUse": { - "description": "JSON Web Key Use\n\nSource: ", - "oneOf": [ + "description": "JSON Web Key Use", + "anyOf": [ { "description": "Digital Signature or MAC", - "type": "string", - "enum": [ - "sig" - ] + "const": "sig" }, { "description": "Encryption", - "type": "string", - "enum": [ - "enc" - ] + "const": "enc" } ] }, @@ -1026,112 +972,67 @@ } }, "JsonWebSignatureAlg": { - "description": "JSON Web Signature \"alg\" parameter\n\nSource: ", - "oneOf": [ + "description": "JSON Web Signature \"alg\" parameter", + "anyOf": [ { "description": "HMAC using SHA-256", - "type": "string", - "enum": [ - "HS256" - ] + "const": "HS256" }, { "description": "HMAC using SHA-384", - "type": "string", - "enum": [ - "HS384" - ] + "const": "HS384" }, { "description": "HMAC using SHA-512", - "type": "string", - "enum": [ - "HS512" - ] + "const": "HS512" }, { "description": "RSASSA-PKCS1-v1_5 using SHA-256", - "type": "string", - "enum": [ - "RS256" - ] + "const": "RS256" }, { "description": "RSASSA-PKCS1-v1_5 using SHA-384", - "type": "string", - "enum": [ - "RS384" - ] + "const": "RS384" }, { "description": "RSASSA-PKCS1-v1_5 using SHA-512", - "type": "string", - "enum": [ - "RS512" - ] + "const": "RS512" }, { "description": "ECDSA using P-256 and SHA-256", - "type": "string", - "enum": [ - "ES256" - ] + "const": "ES256" }, { "description": "ECDSA using P-384 and SHA-384", - "type": "string", - "enum": [ - "ES384" - ] + "const": "ES384" }, { "description": "ECDSA using P-521 and SHA-512", - "type": "string", - "enum": [ - "ES512" - ] + "const": "ES512" }, { "description": "RSASSA-PSS using SHA-256 and MGF1 with SHA-256", - "type": "string", - "enum": [ - "PS256" - ] + "const": "PS256" }, { "description": "RSASSA-PSS using SHA-384 and MGF1 with SHA-384", - "type": "string", - "enum": [ - "PS384" - ] + "const": "PS384" }, { "description": "RSASSA-PSS using SHA-512 and MGF1 with SHA-512", - "type": "string", - "enum": [ - "PS512" - ] + "const": "PS512" }, { "description": "No digital signature or MAC performed", - "type": "string", - "enum": [ - "none" - ] + "const": "none" }, { "description": "EdDSA signature algorithms", - "type": "string", - "enum": [ - "EdDSA" - ] + "const": "EdDSA" }, { "description": "ECDSA using secp256k1 curve and SHA-256", - "type": "string", - "enum": [ - "ES256K" - ] + "const": "ES256K" } ] },