use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};
#[proc_macro_derive(FormatArg)]
pub fn derive_format_arg(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let name = &input.ident;
let mut generics = input.generics.clone();
for param in generics.type_params_mut() {
param.bounds.push(syn::parse_quote!(::core::fmt::Display));
param.bounds.push(syn::parse_quote!(::core::fmt::Debug));
}
let (impl_generics, _, _) = generics.split_for_impl();
let (_, ty_generics, where_clause) = input.generics.split_for_impl();
let expanded = quote! {
impl #impl_generics ::rtformat::FormatArg for #name #ty_generics #where_clause {
fn write(
&self,
ty: ::rtformat::FormatType,
pretty: bool,
_precision: ::core::option::Option<::core::primitive::usize>,
f: &mut ::core::fmt::Formatter<'_>,
) -> ::core::fmt::Result {
#[allow(unused_imports)]
use ::rtformat::__private::{DebugFallback as _, DisplayFallback as _};
let wrap = ::rtformat::__private::Wrap(self);
match ty {
::rtformat::FormatType::Display => wrap
.fmt_display(f)
.or_else(|_| wrap.fmt_debug(f))
.unwrap_or(::core::result::Result::Err(::core::fmt::Error)),
::rtformat::FormatType::Debug if pretty => wrap
.fmt_debug_pretty(f)
.unwrap_or(::core::result::Result::Err(::core::fmt::Error)),
::rtformat::FormatType::Debug => wrap
.fmt_debug(f)
.unwrap_or(::core::result::Result::Err(::core::fmt::Error)),
_ => ::core::result::Result::Err(::core::fmt::Error),
}
}
}
};
TokenStream::from(expanded)
}