From 32e80987e16e07d50e12a23fbad43973a059c6f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Tue, 11 May 2021 09:10:57 +0200 Subject: [PATCH] serde: Add PartialOrdAsRefStr, OrdAsRefStr and PartialEqAsRefStr derives --- crates/ruma-serde-macros/src/eq_as_ref_str.rs | 14 ++++++++++ crates/ruma-serde-macros/src/lib.rs | 24 +++++++++++++++++ .../ruma-serde-macros/src/ord_as_ref_str.rs | 26 +++++++++++++++++++ crates/ruma-serde/CHANGELOG.md | 1 + 4 files changed, 65 insertions(+) create mode 100644 crates/ruma-serde-macros/src/eq_as_ref_str.rs create mode 100644 crates/ruma-serde-macros/src/ord_as_ref_str.rs diff --git a/crates/ruma-serde-macros/src/eq_as_ref_str.rs b/crates/ruma-serde-macros/src/eq_as_ref_str.rs new file mode 100644 index 00000000..846a9807 --- /dev/null +++ b/crates/ruma-serde-macros/src/eq_as_ref_str.rs @@ -0,0 +1,14 @@ +use proc_macro2::{Ident, TokenStream}; +use quote::quote; + +pub fn expand_partial_eq_as_ref_str(ident: &Ident) -> syn::Result { + Ok(quote! { + #[automatically_derived] + impl ::std::cmp::PartialEq for #ident { + fn eq(&self, other: &Self) -> bool { + let other = ::std::convert::AsRef::<::std::primitive::str>::as_ref(other); + ::std::convert::AsRef::<::std::primitive::str>::as_ref(self) == other + } + } + }) +} diff --git a/crates/ruma-serde-macros/src/lib.rs b/crates/ruma-serde-macros/src/lib.rs index 0d60b5a6..92c9bd1c 100644 --- a/crates/ruma-serde-macros/src/lib.rs +++ b/crates/ruma-serde-macros/src/lib.rs @@ -9,6 +9,8 @@ use deserialize_from_cow_str::expand_deserialize_from_cow_str; use display_as_ref_str::expand_display_as_ref_str; use enum_as_ref_str::expand_enum_as_ref_str; use enum_from_string::expand_enum_from_string; +use eq_as_ref_str::expand_partial_eq_as_ref_str; +use ord_as_ref_str::{expand_ord_as_ref_str, expand_partial_ord_as_ref_str}; use outgoing::expand_derive_outgoing; use serialize_as_ref_str::expand_serialize_as_ref_str; @@ -18,6 +20,8 @@ mod deserialize_from_cow_str; mod display_as_ref_str; mod enum_as_ref_str; mod enum_from_string; +mod eq_as_ref_str; +mod ord_as_ref_str; mod outgoing; mod serialize_as_ref_str; mod util; @@ -105,6 +109,26 @@ pub fn derive_deserialize_from_cow_str(input: TokenStream) -> TokenStream { .into() } +#[proc_macro_derive(PartialOrdAsRefStr)] +pub fn derive_partial_ord_as_ref_str(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + expand_partial_ord_as_ref_str(&input.ident) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} + +#[proc_macro_derive(OrdAsRefStr)] +pub fn derive_ord_as_ref_str(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + expand_ord_as_ref_str(&input.ident).unwrap_or_else(syn::Error::into_compile_error).into() +} + +#[proc_macro_derive(PartialEqAsRefStr)] +pub fn derive_partial_eq_as_ref_str(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + expand_partial_eq_as_ref_str(&input.ident).unwrap_or_else(syn::Error::into_compile_error).into() +} + /// Shorthand for the derives `AsRefStr`, `FromString`, `DisplayAsRefStr`, `SerializeAsRefStr` and /// `DeserializeFromCowStr`. #[proc_macro_derive(StringEnum, attributes(ruma_enum))] diff --git a/crates/ruma-serde-macros/src/ord_as_ref_str.rs b/crates/ruma-serde-macros/src/ord_as_ref_str.rs new file mode 100644 index 00000000..070a7a82 --- /dev/null +++ b/crates/ruma-serde-macros/src/ord_as_ref_str.rs @@ -0,0 +1,26 @@ +use proc_macro2::{Ident, TokenStream}; +use quote::quote; + +pub fn expand_partial_ord_as_ref_str(ident: &Ident) -> syn::Result { + Ok(quote! { + #[automatically_derived] + impl ::std::cmp::PartialOrd for #ident { + fn partial_cmp(&self, other: &Self) -> ::std::option::Option<::std::cmp::Ordering> { + let other = ::std::convert::AsRef::<::std::primitive::str>::as_ref(other); + ::std::convert::AsRef::<::std::primitive::str>::as_ref(self).partial_cmp(other) + } + } + }) +} + +pub fn expand_ord_as_ref_str(ident: &Ident) -> syn::Result { + Ok(quote! { + #[automatically_derived] + impl ::std::cmp::Ord for #ident { + fn cmp(&self, other: &Self) -> ::std::cmp::Ordering { + let other = ::std::convert::AsRef::<::std::primitive::str>::as_ref(other); + ::std::convert::AsRef::<::std::primitive::str>::as_ref(self).cmp(other) + } + } + }) +} diff --git a/crates/ruma-serde/CHANGELOG.md b/crates/ruma-serde/CHANGELOG.md index c2bcc700..9fea6db3 100644 --- a/crates/ruma-serde/CHANGELOG.md +++ b/crates/ruma-serde/CHANGELOG.md @@ -7,6 +7,7 @@ Breaking changes: Improvements: * Add serialization decorator `none_as_empty_string` to serialize `None`s as empty strings +* Add `PartialOrdAsRefStr`, `OrdAsRefStr` and `PartialEqAsRefStr` derives # 0.3.1