Use one standard Iris resource bundle

This commit is contained in:
iris committed 2026-09-11 02:09:17 -04:00
1 parent 6dbc800739
commit 7e5a4c0071
16 files changed
+129 -100

No files matched your search

+69 -14
View File
@@ -103,31 +103,72 @@ pub fn widget_trait(input: TokenStream) -> TokenStream {
#[proc_macro_derive(DesktopUiState, attributes(desktop_ui_state))]
pub fn derive_desktop_ui_state(input: TokenStream) -> TokenStream {
let mut output = proc_macro2::TokenStream::new();
let state: ItemStruct = parse_macro_input!(input);
derive_ui_state(
state,
UiStateDerive {
module: "desktop",
state_type: "DesktopUiState",
state_trait: "HasDesktopUiState",
field_attr: "desktop_ui_state",
get: "desktop_state",
get_mut: "desktop_state_mut",
},
)
}
#[proc_macro_derive(AndroidUiState, attributes(android_ui_state))]
pub fn derive_android_ui_state(input: TokenStream) -> TokenStream {
let state: ItemStruct = parse_macro_input!(input);
derive_ui_state(
state,
UiStateDerive {
module: "android",
state_type: "AndroidUiState",
state_trait: "HasAndroidUiState",
field_attr: "android_ui_state",
get: "android_state",
get_mut: "android_state_mut",
},
)
}
struct UiStateDerive {
module: &'static str,
state_type: &'static str,
state_trait: &'static str,
field_attr: &'static str,
get: &'static str,
get_mut: &'static str,
}
fn derive_ui_state(state: ItemStruct, names: UiStateDerive) -> TokenStream {
let UiStateDerive {
module,
state_type,
state_trait,
field_attr,
get,
get_mut,
} = names;
let mut output = proc_macro2::TokenStream::new();
let mut found_attr = false;
let mut state_field = None;
for field in &state.fields {
if !found_attr
&& let Type::Path(path) = &field.ty
&& path.path.is_ident("DesktopUiState")
&& path.path.is_ident(state_type)
{
state_field = Some(field);
}
let Some(attr) = field
.attrs
.iter()
.find(|a| a.path().is_ident("desktop_ui_state"))
else {
let Some(attr) = field.attrs.iter().find(|a| a.path().is_ident(field_attr)) else {
continue;
};
if found_attr {
output.extend(
Error::new(
attr.span(),
"cannot have more than one desktop_ui_state attribute",
format!("cannot have more than one {field_attr} attribute"),
)
.into_compile_error(),
);
@@ -138,18 +179,32 @@ pub fn derive_desktop_ui_state(input: TokenStream) -> TokenStream {
}
let Some(field) = state_field else {
output.extend(
Error::new(state.ident.span(), "no DesktopUiState field found").into_compile_error(),
Error::new(state.ident.span(), format!("no {state_type} field found"))
.into_compile_error(),
);
return output.into();
};
let sname = &state.ident;
let fname = field.ident.as_ref().unwrap();
let Some(fname) = field.ident.as_ref() else {
return Error::new(
field.span(),
format!("the {state_type} field must be named"),
)
.into_compile_error()
.into();
};
let module = Ident::new(module, sname.span());
let state_type = Ident::new(state_type, sname.span());
let state_trait = Ident::new(state_trait, sname.span());
let get = Ident::new(get, sname.span());
let get_mut = Ident::new(get_mut, sname.span());
let (impl_generics, type_generics, where_clause) = state.generics.split_for_impl();
output.extend(quote! {
impl iris::desktop::HasDesktopUiState for #sname {
fn desktop_state(&self) -> &iris::desktop::DesktopUiState {
impl #impl_generics iris::#module::#state_trait for #sname #type_generics #where_clause {
fn #get(&self) -> &iris::#module::#state_type {
&self.#fname
}
fn desktop_state_mut(&mut self) -> &mut iris::desktop::DesktopUiState {
fn #get_mut(&mut self) -> &mut iris::#module::#state_type {
&mut self.#fname
}
}