You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-29 22:01:14 +03:00
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
This commit is contained in:
261
crates/iana-codegen/src/gen.rs
Normal file
261
crates/iana-codegen/src/gen.rs
Normal file
@ -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<Self, Self::Err> {{
|
||||
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<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)
|
||||
}}
|
||||
}}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl serde::Serialize for {} {{
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::ser::Serializer,
|
||||
{{
|
||||
serializer.serialize_str(&self.to_string())
|
||||
}}
|
||||
}}"#,
|
||||
section.key, section.key,
|
||||
)
|
||||
}
|
@ -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(())
|
||||
|
Reference in New Issue
Block a user