rusttauri

Why does Tauri modify the parameter names of invoked functions?


I am using Tauri to build a GUI. In my backend I define two commands:

#[tauri::command]
fn functional_test(msg: String) {
    println!("Received : {}", msg);
}

#[tauri::command]
fn no_functional_test(my_msg: String) {
    println!("Received : {}", my_msg);
}

fn main() {
    tauri::Builder::default()
        .setup(...)
        .invoke_handler(tauri::generate_handler![functional_test, no_functional_test])
        .run(tauri::generate_context!())
        .expect("failed to run app");
}

Note that the only difference between the two functions is the parameter's name: msg vs my_msg.

In the frontend (using react), I have this block of code:

export function AComponent({name}: {name: string}) {
    useEffect(() => {
        const fetchSomething = async () => {
            try {
                await invoke('functional_test', {msg:"This is a message"})
                await invoke('no_functional_test', {my_msg:"This is also a message"})
            } catch (error) {
                await invoke('functional_test', {msg:error})
            }
        };

        fetchSomething();
    }, [name]);

    return (...)
}

Here I try to invoke each one of the two functions. Because I don't know how to display logs of the frontend, I use the working function to debug.

There is the output:

Received : This is a message
Received : invalid args `myMsg` for command `no_functional_test`: command no_functional_test missing required key myMsg

Obviously, the first line of the result is the execution of the 5th line of the frontend code, but the second line is the execution of the 8th line, because the 6th line causes an error. As we see, Tauri expects the parameter to have the name myMsg, and not my_msg as I defined it in the backend.

What is happening? Is this normal?


Solution

  • From the Tauri guide on passing command arguments, it says:

    Please note, when declaring arguments in Rust using snake_case, the arguments are converted to camelCase for JavaScript.

    So this is done intentionally by Tauri. Why? Likely a best attempt to follow conventions (snake_case is preferred in Rust while camelCase is preferred in Javascript).

    If you don't want that, you can configure it when defining your command:

    #[tauri::command(rename_all = "snake_case")]
    

    Also, keep in mind the automatic renaming only affects the argument names and not the data they contain. So the outer name will be camelCase, but any nested fields will likely be snake_case (matching the Rust side) unless you configure serde to rename them via #[serde(rename_all = "camelCase")].

    Related: