macros: Add derive macro to implement as_str() from AsRef<str>

This commit is contained in:
Kévin Commaille 2022-05-30 15:19:13 +02:00 committed by Kévin Commaille
parent 7f164b3173
commit 24b4dd69ad
3 changed files with 25 additions and 0 deletions

View File

@ -33,6 +33,7 @@ use self::{
},
identifiers::IdentifierInput,
serde::{
as_str_as_ref_str::expand_as_str_as_ref_str,
deserialize_from_cow_str::expand_deserialize_from_cow_str,
display_as_ref_str::expand_display_as_ref_str,
enum_as_ref_str::expand_enum_as_ref_str,
@ -267,6 +268,13 @@ pub fn derive_enum_from_string(input: TokenStream) -> TokenStream {
// FIXME: The following macros aren't actually interested in type details beyond name (and possibly
// generics in the future). They probably shouldn't use `DeriveInput`.
/// Derive the `as_str()` method using the `AsRef<str>` implementation of the type.
#[proc_macro_derive(AsStrAsRefStr, attributes(ruma_enum))]
pub fn derive_as_str_as_ref_str(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
expand_as_str_as_ref_str(&input.ident).unwrap_or_else(syn::Error::into_compile_error).into()
}
/// Derive the `fmt::Display` trait using the `AsRef<str>` implementation of the type.
#[proc_macro_derive(DisplayAsRefStr)]
pub fn derive_display_as_ref_str(input: TokenStream) -> TokenStream {

View File

@ -1,5 +1,6 @@
//! Methods and types for (de)serialization.
pub mod as_str_as_ref_str;
pub mod attr;
pub mod case;
pub mod deserialize_from_cow_str;

View File

@ -0,0 +1,16 @@
use proc_macro2::{Ident, TokenStream};
use quote::quote;
pub fn expand_as_str_as_ref_str(ident: &Ident) -> syn::Result<TokenStream> {
let as_str_doc = format!("Creates a string slice from this `{}`.", ident);
Ok(quote! {
#[automatically_derived]
#[allow(deprecated)]
impl #ident {
#[doc = #as_str_doc]
pub fn as_str(&self) -> &str {
self.as_ref()
}
}
})
}