use crate::types::RequiredInterface;
use crate::types::TypeName;
use proc_macro2::TokenStream;
use quote::quote;
pub fn debug_tokens(type_name: &TypeName, interfaces: &Vec<RequiredInterface>) -> TokenStream {
let name = &type_name.name;
let default_impl = quote! { ::std::format!("{}({:?})", #name, <Self as ::winrt::AbiTransferable>::get_abi(self)) };
let implements_istringable = interfaces.iter().any(|interface| {
interface.name.name == "IStringable" && interface.name.namespace == "Windows.Foundation"
});
let is_istringable =
type_name.name == "IStringable" && type_name.namespace == "Windows.Foundation";
let implementation = if implements_istringable && !is_istringable {
let istringable_namespace = crate::types::namespace::to_namespace_tokens(
"Windows.Foundation",
&type_name.namespace,
);
quote! {
"{:?}",
{
let s: #istringable_namespace IStringable = self.into();
s
}
}
} else if is_istringable {
quote! {
"{}",
match self.to_string() {
Ok(s) => s.to_string(),
Err(_) => #default_impl
}
}
} else {
quote! {
"{}", #default_impl
}
};
to_tokens(type_name, &implementation)
}
pub fn default_debug_tokens(type_name: &TypeName) -> TokenStream {
let name = &type_name.name;
let implementation =
quote! { "{}({:?})", #name, <Self as ::winrt::AbiTransferable>::get_abi(self) };
to_tokens(type_name, &implementation)
}
fn to_tokens(type_name: &TypeName, implementation: &TokenStream) -> TokenStream {
let constraints = &type_name.constraints;
let name = &type_name.tokens;
quote! {
impl<#constraints> ::std::fmt::Debug for #name {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
write!(
f,
#implementation
)
}
}
}
}