dampen_core/codegen/
update.rs

1//! Update function generation
2
3use crate::HandlerSignature;
4use proc_macro2::TokenStream;
5use quote::{format_ident, quote};
6
7/// Convert snake_case to UpperCamelCase
8fn to_upper_camel_case(s: &str) -> String {
9    let mut result = String::new();
10    let mut capitalize_next = true;
11    for c in s.chars() {
12        if c == '_' {
13            capitalize_next = true;
14        } else if capitalize_next {
15            result.push(c.to_ascii_uppercase());
16            capitalize_next = false;
17        } else {
18            result.push(c);
19        }
20    }
21    result
22}
23
24/// Generate the update match arms for use in a standalone function
25pub fn generate_update_match_arms(
26    handlers: &[HandlerSignature],
27    message_name: &str,
28) -> Result<TokenStream, super::CodegenError> {
29    let arms = generate_arms(handlers, message_name)?;
30
31    Ok(quote! {
32        match message {
33            #arms
34        }
35    })
36}
37
38/// Generate ONLY the match arms (without the match message { ... } wrapper)
39pub fn generate_arms(
40    handlers: &[HandlerSignature],
41    message_name: &str,
42) -> Result<TokenStream, super::CodegenError> {
43    let message_ident = format_ident!("{}", message_name);
44
45    let match_arms: Vec<TokenStream> = handlers
46        .iter()
47        .map(|handler| {
48            let handler_name = format_ident!("{}", handler.name);
49            let variant_name = to_upper_camel_case(&handler.name);
50            let variant_ident = syn::Ident::new(&variant_name, proc_macro2::Span::call_site());
51
52            if let Some(_param_type) = &handler.param_type {
53                quote! {
54                    #message_ident::#variant_ident(value) => {
55                        #handler_name(model, value);
56                        iced::Task::none()
57                    }
58                }
59            } else if handler.returns_command {
60                quote! {
61                    #message_ident::#variant_ident => {
62                        #handler_name(model)
63                    }
64                }
65            } else {
66                quote! {
67                    #message_ident::#variant_ident => {
68                        #handler_name(model);
69                        iced::Task::none()
70                    }
71                }
72            }
73        })
74        .collect();
75
76    Ok(quote! {
77        #(#match_arms)*
78    })
79}