Compare commits

..

2 commits

Author SHA1 Message Date
19a025d47f remove extraneous comments 2025-07-09 12:42:06 -04:00
ba3fb5357c add new convenience attr: from_display 2025-07-09 12:41:28 -04:00
2 changed files with 44 additions and 0 deletions

View file

@ -2,9 +2,11 @@ use syn::parse::{Parse, ParseStream};
use syn::{Expr, Ident, LitStr, Token, custom_keyword}; use syn::{Expr, Ident, LitStr, Token, custom_keyword};
custom_keyword!(transparent); custom_keyword!(transparent);
custom_keyword!(from_display);
pub enum OsDisplayAttribute { pub enum OsDisplayAttribute {
Transparent, Transparent,
FromDisplay,
Format(FormatArgs), Format(FormatArgs),
} }
@ -25,6 +27,13 @@ impl Parse for OsDisplayAttribute {
} else { } else {
Ok(OsDisplayAttribute::Transparent) Ok(OsDisplayAttribute::Transparent)
} }
} else if lookahead.peek(from_display) {
input.parse::<from_display>()?;
if !input.is_empty() {
Err(input.error("Unexpected tokens after `from_display` attribute."))
} else {
Ok(OsDisplayAttribute::FromDisplay)
}
} else if lookahead.peek(LitStr) { } else if lookahead.peek(LitStr) {
let format_string = input.parse()?; let format_string = input.parse()?;

View file

@ -61,6 +61,32 @@ pub fn os_display_derive(input: TokenStream) -> TokenStream {
} }
} }
} }
OsDisplayAttribute::FromDisplay => {
match &variant.fields {
Fields::Unnamed(fields) if fields.unnamed.len() == 1 => {
quote_spanned! {variant.span() =>
match self {
#name::#variant_name(value) => f.write_str(&value.to_string()),
_ => unreachable!(),
}
}
}
Fields::Named(fields) if fields.named.len() == 1 => {
let field_ident = fields.named.first().unwrap().ident.as_ref().unwrap();
quote_spanned! {variant.span() =>
match self {
#name::#variant_name{#field_ident} => f.write_str(&#field_ident.to_string()),
_ => unreachable!(),
}
}
}
_ => {
return quote_spanned! {variant.span() =>
compile_error!("#[os_display(from_display)] on an enum variant requires a single field which implements std::fmt::Display.");
};
}
}
}
OsDisplayAttribute::Format(format_args) => { OsDisplayAttribute::Format(format_args) => {
let format_str_value = format_args.format_string.value(); let format_str_value = format_args.format_string.value();
@ -191,6 +217,15 @@ pub fn os_display_derive(input: TokenStream) -> TokenStream {
} }
} }
} }
OsDisplayAttribute::FromDisplay => {
quote! {
impl #impl_generics my_os_traits::OsDisplay for #name #ty_generics #where_clause {
fn fmt_os(&self, f: &mut my_os_traits::OsStringFormatter) -> std::fmt::Result {
f.write_str(&self.to_string())
}
}
}
}
OsDisplayAttribute::Format(format_args) => { OsDisplayAttribute::Format(format_args) => {
let format_str_value = format_args.format_string.value(); let format_str_value = format_args.format_string.value();
let positional_expressions: Vec<&Expr> = format_args.positional_args.iter().collect(); let positional_expressions: Vec<&Expr> = format_args.positional_args.iter().collect();