Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug] Failed to pass an enum as argument in command #10127

Closed
shadow3aaa opened this issue Jun 26, 2024 · 5 comments
Closed

[bug] Failed to pass an enum as argument in command #10127

shadow3aaa opened this issue Jun 26, 2024 · 5 comments
Labels
status: needs triage This issue needs to triage, applied to new issues type: bug

Comments

@shadow3aaa
Copy link

Describe the bug

I have a command project_manager_create_project:

#[tauri::command]
pub fn project_manager_create_project(
    project_info: ProjectInfo,
    state: State<ProjectManagerWarpper>,
) {
    state
        .read()
        .project_infos
        .write()
        .infos
        .insert(project_info.name.clone(), project_info);
}

And I tried to invoke it like this:

invoke("project_manager_create_project", {
  projectInfo: projectInfo.value,
});

But it didn't work. So I open devtool and it prompts me with the error: Uncaught (in promise) invalid args 'projectInfo' for command 'project_manager_create_project': invalid type: integer '0', expected string or map.

I searched for a few issues, like #6566, which looks like the same issue. So I tried the following solution (marking enum with #[repr(u16)]) but it didn't work

ProjectInfo struct:

use serde::{Deserialize, Serialize};
#[derive(Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ProjectInfo {
    pub name: String,
    pub template: Template,
}

#[derive(Serialize, Deserialize, Clone, Copy)]
#[serde(rename_all = "camelCase")]
pub enum Template {
    RustBinary,
    RustLibrary,
    Empty,
}

Reproduction

No response

Expected behavior

No response

Full tauri info output

❯ pnpm tauri info

> [email protected] tauri C:\Users\13940\Documents\GitHub\Codroid
> tauri "info"


[✔] Environment
    - OS: Windows 10.0.26120 X64
    ✔ WebView2: 126.0.2592.68
    ✔ MSVC: Visual Studio Community 2022
    ✔ rustc: 1.81.0-nightly (3cb521a43 2024-06-22)
    ✔ cargo: 1.81.0-nightly (bc89bffa5 2024-06-22)
    ✔ rustup: 1.27.1 (54dd3d00f 2024-04-24)
    ✔ Rust toolchain: nightly-x86_64-pc-windows-msvc (default)
    - node: 22.3.0
    - pnpm: 9.4.0
    - npm: 10.8.1

[-] Packages
    - tauri [RUST]: 2.0.0-beta.22
    - tauri-build [RUST]: 2.0.0-beta.17
    - wry [RUST]: 0.40.1
    - tao [RUST]: 0.28.1
    - @tauri-apps/api [NPM]: 2.0.0-beta.13
    - @tauri-apps/cli [NPM]: 2.0.0-beta.20

[-] App
    - build-type: bundle
    - CSP: unset
    - frontendDist: ../dist
    - devUrl: https://localhost:1420/
    - framework: Vue.js
    - bundler: Vite

Stack trace

No response

Additional context

No response

@shadow3aaa shadow3aaa added status: needs triage This issue needs to triage, applied to new issues type: bug labels Jun 26, 2024
@amrbashir
Copy link
Member

amrbashir commented Jun 26, 2024

sounds like an issue in your frontend code, what is the value of projectInfo.value in your frontend code?
it should look something like this:

{
  name: "Project name",
  template: "rustBinary"
}

if it doesn't look like this, then your frontend is the issue, otherwise please provide a minimal repro and ping me

@amrbashir amrbashir closed this as not planned Won't fix, can't repro, duplicate, stale Jun 26, 2024
@shadow3aaa
Copy link
Author

shadow3aaa commented Jun 26, 2024

sounds like an issue in your frontend code, what is the value of projectInfo.value in your frontend code?
it should look something like this:

{
  name: "Project name",
  template: "rustBinary"
}

if it doesn't look like this, then your frontend is the issue, otherwise please provide a minimal repro and ping me

It's something like this:

enum Template {
  RustBinary,
  RustLibrary,
  ...
}

const projectInfo: ComputedRef<ProjectInfo> = computed(() => {
  const template =
    Template[projectTemplateInput.value as keyof typeof Template];
  return {
    name: projectName.value, // string
    template, // Template
  });

@amrbashir
Copy link
Member

amrbashir commented Jun 26, 2024

Typescript enums are not 1:1 equivalent of Rust enums, so you have to make sure they are equal, there is two ways you can do this:

  1. use repr(u16) but will require usage of serde_repr crate so serialization/deserialization could work properly, see https://serde.rs/enum-number.html
  2. change the typescript enum definition to match the serialization of rust enum, so it would look like this:
    enum Template {
      RustBinary = "rustBinary",
      RustLibrary = "rustLibrary",
      ...
    }

@shadow3aaa
Copy link
Author

Typescript enums are not 1:1 equivalent of Rust enums, so you have to make sure they are equal, there is two ways you can do this:

  1. use repr(u16) but will require usage of serde_repr crate so serialization/deserialization could work properly, see https://serde.rs/enum-number.html
  2. change the typescript enum definition to match the serialization of rust enum, so it would look like this:
    enum Template {
      RustBinary = "rustBinary",
      RustLibrary = "rustLibrary",
      ...
    }

I have fixed it through the first way.
But I think this is really confusing for tauri user, maybe Tauri should provide a macro like #[derive(tauri::CommandArg)] to do these works(derive Serialize_repr, Deserialize_repr or Serialize, Deserialize traits, and add #[serde(rename_all = "camelCase")]) on-demand?

@amrbashir
Copy link
Member

I think you're looking for https://github.com/oscartbeaumont/tauri-specta which generates typescript definitions for your based on your commands .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: needs triage This issue needs to triage, applied to new issues type: bug
Projects
None yet
Development

No branches or pull requests

2 participants