zudo-text

検索したい単語を入力

いつでも検索バーを開ける

Adding New Tauri Commands

This guide walks through adding a new backend command that the React frontend can call. The process touches both the Rust backend and the TypeScript bridge layer.

Overview

The communication flow:

React component → getBackend().someApi.method()
  → TauriAdapter → invoke("command_name", { args })
    → Rust #[tauri::command] fn command_name()

Step 1: Add the Rust Command

Create the command function with the #[tauri::command] attribute in the appropriate file under tauri-app/src/commands/.

For example, to add a command to commands/files.rs:

#[tauri::command]
pub fn example_get_count(
    state: tauri::State<'_, AppState>,
) -> Result<usize, String> {
    let project_root = state.project_root.lock().unwrap();
    // ... implementation
    Ok(42)
}

Commands can:

  • Accept tauri::State<AppState> to access shared state

  • Accept tauri::Window for window operations

  • Return Result<T, String> for error handling

  • Accept any serde::Deserialize arguments

Step 2: Register in lib.rs

Add the command to the generate_handler![] macro in tauri-app/src/lib.rs:

.invoke_handler(tauri::generate_handler![
    // ... existing commands
    commands::files::example_get_count,
])

Step 3: Add to BackendAPI Interface

Add the method signature to the BackendAPI interface in packages/backend-bridge/src/types.ts:

export interface BackendAPI {
  // ... existing APIs
  example: {
    getCount: () => Promise<number>;
  };
}

Step 4: Implement in TauriAdapter

Add the real implementation in packages/backend-bridge/src/tauri-adapter.ts that calls invoke():

export function createTauriAdapter(): BackendAPI {
  return {
    // ... existing adapters
    example: {
      getCount: () => invoke<number>("example_get_count"),
    },
  };
}

The invoke() function maps to the Rust command name. Arguments are passed as a single object:

// TypeScript
invoke<boolean>("messages_write", { filename, content });

// Maps to Rust
#[tauri::command]
pub fn messages_write(filename: String, content: String) -> Result<bool, String>

Step 5: Implement in MockAdapter

Add a mock implementation in packages/backend-bridge/src/mock-adapter.ts so the command works in tests and Storybook:

example: {
  getCount: async () => {
    return files.size;
  },
},

Step 6: Call from React

Use getBackend() to access the API from any React component:

import { getBackend } from "@takazudo/backend-bridge";

function ExampleComponent() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    getBackend().example.getCount().then(setCount);
  }, []);

  return <div>Count: {count}</div>;
}

The getBackend() function returns the initialized backend adapter — TauriAdapter in the real app, or MockAdapter in tests.

Checklist

When adding a new command, make sure you have:

  1. Rust function with #[tauri::command] attribute

  2. Command registered in lib.rs generate_handler![]

  3. Type added to BackendAPI interface in types.ts

  4. Implementation in TauriAdapter (tauri-adapter.ts)

  5. Mock implementation in MockAdapter (mock-adapter.ts)

  6. REST implementation in RestAdapter (rest-adapter.ts) if applicable

  7. Frontend code calling via getBackend()