<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
	<id>https://mochiu.net/index.php?action=history&amp;feed=atom&amp;title=Tauri%E3%81%AE%E5%9F%BA%E7%A4%8E_-_Commands</id>
	<title>Tauriの基礎 - Commands - 版の履歴</title>
	<link rel="self" type="application/atom+xml" href="https://mochiu.net/index.php?action=history&amp;feed=atom&amp;title=Tauri%E3%81%AE%E5%9F%BA%E7%A4%8E_-_Commands"/>
	<link rel="alternate" type="text/html" href="https://mochiu.net/index.php?title=Tauri%E3%81%AE%E5%9F%BA%E7%A4%8E_-_Commands&amp;action=history"/>
	<updated>2026-06-01T21:33:01Z</updated>
	<subtitle>このウィキのこのページに関する変更履歴</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://mochiu.net/index.php?title=Tauri%E3%81%AE%E5%9F%BA%E7%A4%8E_-_Commands&amp;diff=14515&amp;oldid=prev</id>
		<title>Wiki: ページの作成:「== 概要 == Tauriの &lt;u&gt;Commands&lt;/u&gt; は、フロントエンド (JavaScript / TypeScript) からバックエンド (Rust) の関数を呼び出すための通信メカニズムである。&lt;br&gt; &lt;br&gt; この機能により、ReactやVue等のフロントエンドフレームワークから、Rustで実装された高速で安全な処理を直接実行できる。&lt;br&gt; &lt;br&gt; TauriのCommandsはIPC (Inter-Process Communication) を基盤としており、WebViewプロ…」</title>
		<link rel="alternate" type="text/html" href="https://mochiu.net/index.php?title=Tauri%E3%81%AE%E5%9F%BA%E7%A4%8E_-_Commands&amp;diff=14515&amp;oldid=prev"/>
		<updated>2026-03-03T15:37:47Z</updated>

		<summary type="html">&lt;p&gt;ページの作成:「== 概要 == Tauriの &amp;lt;u&amp;gt;Commands&amp;lt;/u&amp;gt; は、フロントエンド (JavaScript / TypeScript) からバックエンド (Rust) の関数を呼び出すための通信メカニズムである。&amp;lt;br&amp;gt; &amp;lt;br&amp;gt; この機能により、ReactやVue等のフロントエンドフレームワークから、Rustで実装された高速で安全な処理を直接実行できる。&amp;lt;br&amp;gt; &amp;lt;br&amp;gt; TauriのCommandsはIPC (Inter-Process Communication) を基盤としており、WebViewプロ…」&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新規ページ&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== 概要 ==&lt;br /&gt;
Tauriの &amp;lt;u&amp;gt;Commands&amp;lt;/u&amp;gt; は、フロントエンド (JavaScript / TypeScript) からバックエンド (Rust) の関数を呼び出すための通信メカニズムである。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
この機能により、ReactやVue等のフロントエンドフレームワークから、Rustで実装された高速で安全な処理を直接実行できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
TauriのCommandsはIPC (Inter-Process Communication) を基盤としており、WebViewプロセスとRustプロセス間でのデータの送受信を行う。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
通信はJSONベースのシリアライズを通じて行われ、型安全性を確保しながらデータのやり取りが可能である。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Commandsの主な特徴は以下の通りである。&amp;lt;br&amp;gt;&lt;br /&gt;
* 型安全な通信&lt;br /&gt;
*: Rustの型システムとTypeScriptの型定義により、コンパイル時に型チェックが行われる。&lt;br /&gt;
* JSONシリアライズ&lt;br /&gt;
*: Serdeクレートを使用して、自動的にJSONへの変換が行われる。&lt;br /&gt;
* 非同期サポート&lt;br /&gt;
*: 非同期関数を定義することで、ブロッキングを回避できる。&lt;br /&gt;
* エラーハンドリング&lt;br /&gt;
*: Result型を使用して、構造化されたエラー処理が可能である。&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 前提条件 ==&lt;br /&gt;
Commandsを使用するには、以下に示す前提条件を満たしている必要がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 必要な依存関係 ====&lt;br /&gt;
Cargo.tomlファイルに以下に示す依存関係を追加する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;toml&amp;quot;&amp;gt;&lt;br /&gt;
 [dependencies]&lt;br /&gt;
 tauri = { version = &amp;quot;2&amp;quot;, features = [&amp;quot;unstable&amp;quot;] }&lt;br /&gt;
 serde = { version = &amp;quot;1&amp;quot;, features = [&amp;quot;derive&amp;quot;] }&lt;br /&gt;
 serde_json = &amp;quot;1&amp;quot;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== プロジェクト構成 ====&lt;br /&gt;
Tauriプロジェクトの基本的な構成を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 my-tauri-app/&lt;br /&gt;
 ├── src/                    # フロントエンド (React / TypeScript)&lt;br /&gt;
 │   ├── App.tsx&lt;br /&gt;
 │   └── main.tsx&lt;br /&gt;
 ├── src-tauri/              # バックエンド (Rust)&lt;br /&gt;
 │   ├── src/&lt;br /&gt;
 │   │   ├── main.rs         # エントリーポイント&lt;br /&gt;
 │   │   └── lib.rs          # Commands定義&lt;br /&gt;
 │   └── Cargo.toml&lt;br /&gt;
 └── package.json&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== TypeScriptの型定義 ====&lt;br /&gt;
フロントエンドで型安全性を確保するために、以下に示すパッケージをインストールする。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 npm install @tauri-apps/api&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== #[tauri::command]マクロ ==&lt;br /&gt;
&amp;lt;code&amp;gt;#[tauri::command]&amp;lt;/code&amp;gt; マクロは、Rust関数をフロントエンドから呼び出し可能にするための属性マクロである。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 基本的な使い方 ====&lt;br /&gt;
マクロを関数に付与することにより、その関数がCommandとして登録される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
 use tauri::command;&lt;br /&gt;
 &lt;br /&gt;
 #[command]&lt;br /&gt;
 fn greet(name: &amp;amp;str) -&amp;gt; String {&lt;br /&gt;
    format!(&amp;quot;Hello, {}!&amp;quot;, name)&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 関数シグネチャの要件 ====&lt;br /&gt;
Commandとして定義する関数は、以下に示す要件を満たす必要がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* 引数の型&lt;br /&gt;
*: 引数は、&amp;lt;code&amp;gt;serde::Deserialize&amp;lt;/code&amp;gt; を実装している必要がある。&lt;br /&gt;
*: 基本的な型 (String、i32、bool等) や カスタム構造体を使用できる。&lt;br /&gt;
* 戻り値の型&lt;br /&gt;
*: 戻り値は、&amp;lt;code&amp;gt;serde::Serialize&amp;lt;/code&amp;gt; を実装している必要がある。&lt;br /&gt;
*: &amp;lt;code&amp;gt;Result&amp;lt;T, E&amp;gt;&amp;lt;/code&amp;gt; 型も使用可能である。(Eは、Serializeを実装している必要がある)&lt;br /&gt;
* ライフタイム&lt;br /&gt;
*: 引数に参照を使用する場合は、ライフタイムの考慮が必要である。&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 複数の引数を受け取る関数 ====&lt;br /&gt;
複数の引数を受け取る関数の例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
 #[command]&lt;br /&gt;
 fn calculate(a: i32, b: i32, operation: String) -&amp;gt; Result&amp;lt;i32, String&amp;gt; {&lt;br /&gt;
    match operation.as_str() {&lt;br /&gt;
       &amp;quot;add&amp;quot; =&amp;gt; Ok(a + b),&lt;br /&gt;
       &amp;quot;subtract&amp;quot; =&amp;gt; Ok(a - b),&lt;br /&gt;
       &amp;quot;multiply&amp;quot; =&amp;gt; Ok(a * b),&lt;br /&gt;
       &amp;quot;divide&amp;quot; =&amp;gt; {&lt;br /&gt;
          if b == 0 {&lt;br /&gt;
             Err(&amp;quot;Division by zero&amp;quot;.to_string())&lt;br /&gt;
          }&lt;br /&gt;
          else {&lt;br /&gt;
             Ok(a / b)&lt;br /&gt;
          }&lt;br /&gt;
       }&lt;br /&gt;
       _ =&amp;gt; Err(format!(&amp;quot;Unknown operation: {}&amp;quot;, operation)),&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== invoke関数による呼び出し ==&lt;br /&gt;
フロントエンドからCommandを呼び出すには、&amp;lt;code&amp;gt;invoke&amp;lt;/code&amp;gt;関数を使用する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== JavaScript / TypeScript側の実装 ====&lt;br /&gt;
&amp;lt;u&amp;gt;@tauri-apps/api&amp;lt;/u&amp;gt; パッケージから &amp;lt;code&amp;gt;invoke&amp;lt;/code&amp;gt; 関数をインポートして使用する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 import { invoke } from &amp;#039;@tauri-apps/api/core&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
 // 基本的な呼び出し&lt;br /&gt;
 const result = await invoke&amp;lt;string&amp;gt;(&amp;#039;greet&amp;#039;, { name: &amp;#039;Tauri&amp;#039; })&lt;br /&gt;
 console.log(result) // &amp;quot;Hello, Tauri!&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 // エラーハンドリング付き&lt;br /&gt;
 try {&lt;br /&gt;
    const result = await invoke&amp;lt;number&amp;gt;(&amp;#039;calculate&amp;#039;, {&lt;br /&gt;
       a: 10,&lt;br /&gt;
       b: 5,&lt;br /&gt;
       operation: &amp;#039;add&amp;#039;&lt;br /&gt;
    })&lt;br /&gt;
    console.log(result)  // 15&lt;br /&gt;
 }&lt;br /&gt;
 catch (error) {&lt;br /&gt;
    console.error(&amp;#039;Error:&amp;#039;, error)&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== Reactでの使用パターン ====&lt;br /&gt;
ReactコンポーネントでCommandを呼び出す例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 import { useState } from &amp;#039;react&amp;#039;&lt;br /&gt;
 import { invoke } from &amp;#039;@tauri-apps/api/core&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
 interface GreetingProps {&lt;br /&gt;
   initialName?: string&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 function Greeting({ initialName = &amp;#039;&amp;#039; }: GreetingProps) {&lt;br /&gt;
   const [name, setName] = useState(initialName)&lt;br /&gt;
   const [greeting, setGreeting] = useState(&amp;#039;&amp;#039;)&lt;br /&gt;
   const [loading, setLoading] = useState(false)&lt;br /&gt;
   const [error, setError] = useState&amp;lt;string | null&amp;gt;(null)&lt;br /&gt;
 &lt;br /&gt;
   const handleGreet = async () =&amp;gt; {&lt;br /&gt;
     setLoading(true)&lt;br /&gt;
     setError(null)&lt;br /&gt;
     try {&lt;br /&gt;
       const result = await invoke&amp;lt;string&amp;gt;(&amp;#039;greet&amp;#039;, { name })&lt;br /&gt;
       setGreeting(result)&lt;br /&gt;
     }&lt;br /&gt;
     catch (err) {&lt;br /&gt;
       setError(err as string)&lt;br /&gt;
     }&lt;br /&gt;
     finally {&lt;br /&gt;
       setLoading(false)&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   return (&lt;br /&gt;
     &amp;lt;div&amp;gt;&lt;br /&gt;
       &amp;lt;input&lt;br /&gt;
         type=&amp;quot;text&amp;quot;&lt;br /&gt;
         value={name}&lt;br /&gt;
         onChange={(e) =&amp;gt; setName(e.target.value)}&lt;br /&gt;
         placeholder=&amp;quot;名前を入力&amp;quot;&lt;br /&gt;
       /&amp;gt;&lt;br /&gt;
       &amp;lt;button onClick={handleGreet} disabled={loading}&amp;gt;&lt;br /&gt;
         {loading ? &amp;#039;処理中...&amp;#039; : &amp;#039;挨拶&amp;#039;}&lt;br /&gt;
       &amp;lt;/button&amp;gt;&lt;br /&gt;
       {greeting &amp;amp;&amp;amp; &amp;lt;p&amp;gt;{greeting}&amp;lt;/p&amp;gt;}&lt;br /&gt;
       {error &amp;amp;&amp;amp; &amp;lt;p style={{ color: &amp;#039;red&amp;#039; }}&amp;gt;{error}&amp;lt;/p&amp;gt;}&lt;br /&gt;
     &amp;lt;/div&amp;gt;&lt;br /&gt;
   )&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 export default Greeting&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 型定義の自動生成 ====&lt;br /&gt;
Tauri v2では、&amp;lt;code&amp;gt;tauri-codegen&amp;lt;/code&amp;gt; クレートを使用して、TypeScriptの型定義を自動生成できる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Cargo.tomlファイルに以下に示す設定を追加する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;toml&amp;quot;&amp;gt;&lt;br /&gt;
 [build-dependencies]&lt;br /&gt;
 tauri-build = { version = &amp;quot;2&amp;quot;, features = [&amp;quot;codegen&amp;quot;] }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
build.rsファイルを作成する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
 fn main() {&lt;br /&gt;
    tauri_build::build()&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
これにより、ビルド時にTypeScriptの型定義ファイルが生成される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 引数の受け渡し (JSONシリアライズ) ==&lt;br /&gt;
Commandへの引数は、JSONシリアライズを通じて渡される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 基本的な引数 ====&lt;br /&gt;
基本的な型は自動的にシリアライズされる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ サポートされる基本的な型&lt;br /&gt;
|-&lt;br /&gt;
! Rust型 !! TypeScript型 !! 説明&lt;br /&gt;
|-&lt;br /&gt;
| String || string || 文字列&lt;br /&gt;
|-&lt;br /&gt;
| i32, i64 || number || 整数&lt;br /&gt;
|-&lt;br /&gt;
| f64 || number || 浮動小数点数&lt;br /&gt;
|-&lt;br /&gt;
| bool || boolean || 真偽値&lt;br /&gt;
|-&lt;br /&gt;
| Vec&amp;lt;T&amp;gt; || T[] || 配列&lt;br /&gt;
|-&lt;br /&gt;
| Option&amp;lt;T&amp;gt; || T \| null || NULL許容&lt;br /&gt;
|-&lt;br /&gt;
| HashMap&amp;lt;K, V&amp;gt; || Record&amp;lt;K, V&amp;gt; || マップ&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 複雑なオブジェクトの受け渡し ====&lt;br /&gt;
カスタム構造体を使用して、複雑なオブジェクトを渡すことができる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* Rust側の定義&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
 use serde::Deserialize;&lt;br /&gt;
 &lt;br /&gt;
 #[derive(Deserialize)]&lt;br /&gt;
 struct User {&lt;br /&gt;
    id: u32,&lt;br /&gt;
    name: String,&lt;br /&gt;
    email: String,&lt;br /&gt;
    active: bool,&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 #[command]&lt;br /&gt;
 fn create_user(user: User) -&amp;gt; Result&amp;lt;String, String&amp;gt; {&lt;br /&gt;
    if user.name.is_empty() {&lt;br /&gt;
       return Err(&amp;quot;Name is required&amp;quot;.to_string())&lt;br /&gt;
    }&lt;br /&gt;
    Ok(format!(&amp;quot;Created user: {} (ID: {})&amp;quot;, user.name, user.id))&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*: &amp;lt;br&amp;gt;&lt;br /&gt;
* TypeScript側の呼び出し&lt;br /&gt;
*: &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 interface User {&lt;br /&gt;
   id: number&lt;br /&gt;
   name: string&lt;br /&gt;
   email: string&lt;br /&gt;
   active: boolean&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 const createUser = async (user: User) =&amp;gt; {&lt;br /&gt;
   try {&lt;br /&gt;
     const result = await invoke&amp;lt;string&amp;gt;(&amp;#039;create_user&amp;#039;, { user })&lt;br /&gt;
     console.log(result)&lt;br /&gt;
   }&lt;br /&gt;
   catch (error) {&lt;br /&gt;
     console.error(&amp;#039;Failed to create user:&amp;#039;, error)&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // 使用例&lt;br /&gt;
 createUser({&lt;br /&gt;
   id: 1,&lt;br /&gt;
   name: &amp;#039;John Doe&amp;#039;,&lt;br /&gt;
   email: &amp;#039;john@example.com&amp;#039;,&lt;br /&gt;
   active: true&lt;br /&gt;
 })&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== Serdeによるシリアライズ ====&lt;br /&gt;
Serdeクレートを使用して、シリアライズの動作をカスタマイズできる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
 use serde::{Deserialize, Serialize};&lt;br /&gt;
 &lt;br /&gt;
 // フィールド名のリネーム&lt;br /&gt;
 #[derive(Deserialize)]&lt;br /&gt;
 #[serde(rename_all = &amp;quot;camelCase&amp;quot;)]&lt;br /&gt;
 struct UserProfile {&lt;br /&gt;
    user_id: u32,&lt;br /&gt;
    first_name: String,&lt;br /&gt;
    last_name: String,&lt;br /&gt;
    created_at: String,&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // オプショナルフィールド&lt;br /&gt;
 #[derive(Deserialize)]&lt;br /&gt;
 struct UpdateRequest {&lt;br /&gt;
    #[serde(default)]&lt;br /&gt;
    name: Option&amp;lt;String&amp;gt;,&lt;br /&gt;
    #[serde(default)]&lt;br /&gt;
    email: Option&amp;lt;String&amp;gt;,&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // カスタムデシリアライザ&lt;br /&gt;
 #[derive(Deserialize)]&lt;br /&gt;
 struct Config {&lt;br /&gt;
    #[serde(deserialize_with = &amp;quot;parse_version&amp;quot;)]&lt;br /&gt;
    version: u32,&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 戻り値の受け取り ==&lt;br /&gt;
Commandからの戻り値は、JSONシリアライズを通じてフロントエンドに返される。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 基本的な戻り値 ====&lt;br /&gt;
基本的な型を返す例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
 #[command]&lt;br /&gt;
 fn get_timestamp() -&amp;gt; u64 {&lt;br /&gt;
    std::time::SystemTime::now()&lt;br /&gt;
       .duration_since(std::time::UNIX_EPOCH)&lt;br /&gt;
       .unwrap()&lt;br /&gt;
       .as_secs()&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 #[command]&lt;br /&gt;
 fn get_app_info() -&amp;gt; (String, String) {&lt;br /&gt;
    (&amp;quot;MyApp&amp;quot;.to_string(), &amp;quot;1.0.0&amp;quot;.to_string())&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 複雑なオブジェクトの返却 ====&lt;br /&gt;
構造体を返すことにより、複雑なデータを渡すことができる。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
 use serde::Serialize;&lt;br /&gt;
 &lt;br /&gt;
 #[derive(Serialize)]&lt;br /&gt;
 struct FileInfo {&lt;br /&gt;
    name: String,&lt;br /&gt;
    size: u64,&lt;br /&gt;
    is_directory: bool,&lt;br /&gt;
    modified: String,&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 #[command]&lt;br /&gt;
 fn get_file_info(path: String) -&amp;gt; Result&amp;lt;FileInfo, String&amp;gt; {&lt;br /&gt;
    let metadata = std::fs::metadata(&amp;amp;path)&lt;br /&gt;
       .map_err(|e| format!(&amp;quot;Failed to read file: {}&amp;quot;, e))?;&lt;br /&gt;
    &lt;br /&gt;
    Ok(FileInfo {&lt;br /&gt;
       name: path.split(&amp;#039;/&amp;#039;).last().unwrap_or(&amp;amp;path).to_string(),&lt;br /&gt;
       size: metadata.len(),&lt;br /&gt;
       is_directory: metadata.is_dir(),&lt;br /&gt;
       modified: metadata.modified()&lt;br /&gt;
          .map(|t| format!(&amp;quot;{:?}&amp;quot;, t))&lt;br /&gt;
          .unwrap_or_else(|_| &amp;quot;Unknown&amp;quot;.to_string()),&lt;br /&gt;
    })&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 // TypeScript側での受信&lt;br /&gt;
 &lt;br /&gt;
 interface FileInfo {&lt;br /&gt;
   name: string&lt;br /&gt;
   size: number&lt;br /&gt;
   is_directory: boolean&lt;br /&gt;
   modified: string&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 const getFileInfo = async (path: string): Promise&amp;lt;FileInfo | null&amp;gt; =&amp;gt; {&lt;br /&gt;
   try {&lt;br /&gt;
     const info = await invoke&amp;lt;FileInfo&amp;gt;(&amp;#039;get_file_info&amp;#039;, { path })&lt;br /&gt;
     return info&lt;br /&gt;
   }&lt;br /&gt;
   catch (error) {&lt;br /&gt;
     console.error(&amp;#039;Failed to get file info:&amp;#039;, error)&lt;br /&gt;
     return null&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 型安全な受信 ====&lt;br /&gt;
TypeScriptのジェネリクスを使用して、型安全に受信する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 import { invoke } from &amp;#039;@tauri-apps/api/core&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
 // 型定義&lt;br /&gt;
 interface ApiResponse&amp;lt;T&amp;gt; {&lt;br /&gt;
   success: boolean&lt;br /&gt;
   data: T | null&lt;br /&gt;
   error: string | null&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 interface UserData {&lt;br /&gt;
   id: number&lt;br /&gt;
   name: string&lt;br /&gt;
   email: string&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // 型安全なinvokeラッパー&lt;br /&gt;
 async function typedInvoke&amp;lt;T&amp;gt;(&lt;br /&gt;
   command: string,&lt;br /&gt;
   args?: Record&amp;lt;string, unknown&amp;gt;&lt;br /&gt;
 ): Promise&amp;lt;T&amp;gt; {&lt;br /&gt;
   return invoke&amp;lt;T&amp;gt;(command, args)&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // 使用例&lt;br /&gt;
 const fetchUser = async (userId: number) =&amp;gt; {&lt;br /&gt;
   try {&lt;br /&gt;
     const response = await typedInvoke&amp;lt;ApiResponse&amp;lt;UserData&amp;gt;&amp;gt;(&lt;br /&gt;
       &amp;#039;fetch_user&amp;#039;,&lt;br /&gt;
       { userId }&lt;br /&gt;
     )&lt;br /&gt;
 &lt;br /&gt;
     if (response.success &amp;amp;&amp;amp; response.data) {&lt;br /&gt;
       console.log(&amp;#039;User:&amp;#039;, response.data.name)&lt;br /&gt;
     }&lt;br /&gt;
     else {&lt;br /&gt;
       console.error(&amp;#039;Error:&amp;#039;, response.error)&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
   catch (error) {&lt;br /&gt;
     console.error(&amp;#039;Command failed:&amp;#039;, error)&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== generate_handler!マクロによるコマンド登録 ==&lt;br /&gt;
定義したCommandを使用するには、&amp;lt;code&amp;gt;generate_handler!&amp;lt;/code&amp;gt; マクロで登録する必要がある。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 単一コマンドの登録 ====&lt;br /&gt;
基本的な登録方法を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
 // src-tauri/src/lib.rs&lt;br /&gt;
 use tauri::command;&lt;br /&gt;
 &lt;br /&gt;
 #[command]&lt;br /&gt;
 fn greet(name: &amp;amp;str) -&amp;gt; String {&lt;br /&gt;
    format!(&amp;quot;Hello, {}!&amp;quot;, name)&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // エクスポート&lt;br /&gt;
 #[tauri::command]&lt;br /&gt;
 fn get_version() -&amp;gt; String {&lt;br /&gt;
    env!(&amp;quot;CARGO_PKG_VERSION&amp;quot;).to_string()&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
 // main.rsでの登録&lt;br /&gt;
 // src-tauri/src/main.rs&lt;br /&gt;
 #![cfg_attr(not(debug_assertions), windows_subsystem = &amp;quot;windows&amp;quot;)]&lt;br /&gt;
 &lt;br /&gt;
 fn main() {&lt;br /&gt;
    tauri::Builder::default()&lt;br /&gt;
       .invoke_handler(tauri::generate_handler![greet, get_version])&lt;br /&gt;
       .run(tauri::generate_context!())&lt;br /&gt;
       .expect(&amp;quot;error while running tauri application&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 複数コマンドの登録 ====&lt;br /&gt;
複数のCommandを一括で登録する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
 // src-tauri/src/lib.rs&lt;br /&gt;
 mod commands;&lt;br /&gt;
 &lt;br /&gt;
 pub use commands::*;&lt;br /&gt;
 &lt;br /&gt;
 // src-tauri/src/commands/mod.rs&lt;br /&gt;
 pub mod user;&lt;br /&gt;
 pub mod file;&lt;br /&gt;
 pub mod system;&lt;br /&gt;
 &lt;br /&gt;
 pub use user::*;&lt;br /&gt;
 pub use file::*;&lt;br /&gt;
 pub use system::*;&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
 // src-tauri/src/main.rs&lt;br /&gt;
 use my_app::*;&lt;br /&gt;
 &lt;br /&gt;
 fn main() {&lt;br /&gt;
    tauri::Builder::default()&lt;br /&gt;
       .invoke_handler(tauri::generate_handler![&lt;br /&gt;
          // User commands&lt;br /&gt;
          user::create_user,&lt;br /&gt;
          user::get_user,&lt;br /&gt;
          user::update_user,&lt;br /&gt;
          user::delete_user,&lt;br /&gt;
          // File commands&lt;br /&gt;
          file::read_file,&lt;br /&gt;
          file::write_file,&lt;br /&gt;
          file::delete_file,&lt;br /&gt;
          // System commands&lt;br /&gt;
          system::get_system_info,&lt;br /&gt;
          system::get_env_var,&lt;br /&gt;
       ])&lt;br /&gt;
       .run(tauri::generate_context!())&lt;br /&gt;
       .expect(&amp;quot;error while running tauri application&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== main.rsでの設定 ====&lt;br /&gt;
Tauri Builderの設定例を以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
 use tauri::Manager;&lt;br /&gt;
 &lt;br /&gt;
 fn main() {&lt;br /&gt;
    tauri::Builder::default()&lt;br /&gt;
       // Commandsの登録&lt;br /&gt;
       .invoke_handler(tauri::generate_handler![&lt;br /&gt;
          greet,&lt;br /&gt;
          get_version,&lt;br /&gt;
          calculate,&lt;br /&gt;
          create_user,&lt;br /&gt;
          get_file_info,&lt;br /&gt;
       ])&lt;br /&gt;
       // ウィンドウ設定&lt;br /&gt;
       .setup(|app| {&lt;br /&gt;
          #[cfg(debug_assertions)]&lt;br /&gt;
          {&lt;br /&gt;
             let window = app.get_webview_window(&amp;quot;main&amp;quot;).unwrap();&lt;br /&gt;
             window.open_devtools();&lt;br /&gt;
          }&lt;br /&gt;
          Ok(())&lt;br /&gt;
       })&lt;br /&gt;
       .run(tauri::generate_context!())&lt;br /&gt;
       .expect(&amp;quot;error while running tauri application&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== サンプルコード ==&lt;br /&gt;
==== Rust側の実装 ====&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
 // src-tauri/src/lib.rs&lt;br /&gt;
 use serde::{Deserialize, Serialize};&lt;br /&gt;
 use tauri::command;&lt;br /&gt;
 &lt;br /&gt;
 // データ構造&lt;br /&gt;
 #[derive(Debug, Clone, Serialize, Deserialize)]&lt;br /&gt;
 pub struct Todo {&lt;br /&gt;
    id: u32,&lt;br /&gt;
    title: String,&lt;br /&gt;
    completed: bool,&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // グローバル状態 (実際のアプリではデータベースを使用)&lt;br /&gt;
 static mut TODOS: Vec&amp;lt;Todo&amp;gt; = Vec::new();&lt;br /&gt;
 &lt;br /&gt;
 // Todo一覧取得&lt;br /&gt;
 #[command]&lt;br /&gt;
 fn get_todos() -&amp;gt; Vec&amp;lt;Todo&amp;gt; {&lt;br /&gt;
    unsafe { TODOS.clone() }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // Todo追加&lt;br /&gt;
 #[command]&lt;br /&gt;
 fn add_todo(title: String) -&amp;gt; Result&amp;lt;Todo, String&amp;gt; {&lt;br /&gt;
    if title.trim().is_empty() {&lt;br /&gt;
       return Err(&amp;quot;Title cannot be empty&amp;quot;.to_string())&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    unsafe {&lt;br /&gt;
       let id = TODOS.len() as u32 + 1;&lt;br /&gt;
       let todo = Todo {&lt;br /&gt;
          id,&lt;br /&gt;
          title,&lt;br /&gt;
          completed: false,&lt;br /&gt;
       };&lt;br /&gt;
       TODOS.push(todo.clone());&lt;br /&gt;
       Ok(todo)&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // Todo更新&lt;br /&gt;
 #[command]&lt;br /&gt;
 fn update_todo(id: u32, completed: bool) -&amp;gt; Result&amp;lt;Todo, String&amp;gt; {&lt;br /&gt;
    unsafe {&lt;br /&gt;
       if let Some(todo) = TODOS.iter_mut().find(|t| t.id == id) {&lt;br /&gt;
          todo.completed = completed;&lt;br /&gt;
          Ok(todo.clone())&lt;br /&gt;
       }&lt;br /&gt;
       else {&lt;br /&gt;
          Err(format!(&amp;quot;Todo with id {} not found&amp;quot;, id))&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // Todo削除&lt;br /&gt;
 #[command]&lt;br /&gt;
 fn delete_todo(id: u32) -&amp;gt; Result&amp;lt;(), String&amp;gt; {&lt;br /&gt;
    unsafe {&lt;br /&gt;
       let initial_len = TODOS.len();&lt;br /&gt;
       TODOS.retain(|t| t.id != id);&lt;br /&gt;
       if TODOS.len() == initial_len {&lt;br /&gt;
          Err(format!(&amp;quot;Todo with id {} not found&amp;quot;, id))&lt;br /&gt;
       }&lt;br /&gt;
       else {&lt;br /&gt;
          Ok(())&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== TypeScript / React側の実装 ====&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 // src/App.tsx&lt;br /&gt;
 import { useState, useEffect } from &amp;#039;react&amp;#039;&lt;br /&gt;
 import { invoke } from &amp;#039;@tauri-apps/api/core&amp;#039;&lt;br /&gt;
 &lt;br /&gt;
 interface Todo {&lt;br /&gt;
   id: number&lt;br /&gt;
   title: string&lt;br /&gt;
   completed: boolean&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 function App() {&lt;br /&gt;
   const [todos, setTodos] = useState&amp;lt;Todo[]&amp;gt;([])&lt;br /&gt;
   const [newTodo, setNewTodo] = useState(&amp;#039;&amp;#039;)&lt;br /&gt;
   const [loading, setLoading] = useState(false)&lt;br /&gt;
   const [error, setError] = useState&amp;lt;string | null&amp;gt;(null)&lt;br /&gt;
 &lt;br /&gt;
   // Todo一覧取得&lt;br /&gt;
   const fetchTodos = async () =&amp;gt; {&lt;br /&gt;
     try {&lt;br /&gt;
       const result = await invoke&amp;lt;Todo[]&amp;gt;(&amp;#039;get_todos&amp;#039;)&lt;br /&gt;
       setTodos(result)&lt;br /&gt;
     }&lt;br /&gt;
     catch (err) {&lt;br /&gt;
       setError(err as string)&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   useEffect(() =&amp;gt; {&lt;br /&gt;
     fetchTodos()&lt;br /&gt;
   }, [])&lt;br /&gt;
 &lt;br /&gt;
   // Todo追加&lt;br /&gt;
   const handleAddTodo = async () =&amp;gt; {&lt;br /&gt;
     if (!newTodo.trim()) return&lt;br /&gt;
     &lt;br /&gt;
     setLoading(true)&lt;br /&gt;
     setError(null)&lt;br /&gt;
     try {&lt;br /&gt;
       await invoke&amp;lt;Todo&amp;gt;(&amp;#039;add_todo&amp;#039;, { title: newTodo })&lt;br /&gt;
       setNewTodo(&amp;#039;&amp;#039;)&lt;br /&gt;
       await fetchTodos()&lt;br /&gt;
     }&lt;br /&gt;
     catch (err) {&lt;br /&gt;
       setError(err as string)&lt;br /&gt;
     }&lt;br /&gt;
     finally {&lt;br /&gt;
       setLoading(false)&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   // Todo更新&lt;br /&gt;
   const handleToggleTodo = async (id: number, completed: boolean) =&amp;gt; {&lt;br /&gt;
     try {&lt;br /&gt;
       await invoke&amp;lt;Todo&amp;gt;(&amp;#039;update_todo&amp;#039;, { id, completed })&lt;br /&gt;
       await fetchTodos()&lt;br /&gt;
     }&lt;br /&gt;
     catch (err) {&lt;br /&gt;
       setError(err as string)&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   // Todo削除&lt;br /&gt;
   const handleDeleteTodo = async (id: number) =&amp;gt; {&lt;br /&gt;
     try {&lt;br /&gt;
       await invoke(&amp;#039;delete_todo&amp;#039;, { id })&lt;br /&gt;
       await fetchTodos()&lt;br /&gt;
     }&lt;br /&gt;
     catch (err) {&lt;br /&gt;
       setError(err as string)&lt;br /&gt;
     }&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   return (&lt;br /&gt;
     &amp;lt;div style={{ padding: &amp;#039;20px&amp;#039;, maxWidth: &amp;#039;600px&amp;#039;, margin: &amp;#039;0 auto&amp;#039; }}&amp;gt;&lt;br /&gt;
       &amp;lt;h1&amp;gt;Todo App&amp;lt;/h1&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
       {/* エラー表示 */}&lt;br /&gt;
       {error &amp;amp;&amp;amp; (&lt;br /&gt;
         &amp;lt;div style={{ color: &amp;#039;red&amp;#039;, marginBottom: &amp;#039;10px&amp;#039; }}&amp;gt;&lt;br /&gt;
           {error}&lt;br /&gt;
           &amp;lt;button onClick={() =&amp;gt; setError(null)}&amp;gt;×&amp;lt;/button&amp;gt;&lt;br /&gt;
         &amp;lt;/div&amp;gt;&lt;br /&gt;
       )}&lt;br /&gt;
 &lt;br /&gt;
       {/* Todo追加フォーム */}&lt;br /&gt;
       &amp;lt;div style={{ marginBottom: &amp;#039;20px&amp;#039; }}&amp;gt;&lt;br /&gt;
         &amp;lt;input&lt;br /&gt;
           type=&amp;quot;text&amp;quot;&lt;br /&gt;
           value={newTodo}&lt;br /&gt;
           onChange={(e) =&amp;gt; setNewTodo(e.target.value)}&lt;br /&gt;
           placeholder=&amp;quot;新しいTodoを入力&amp;quot;&lt;br /&gt;
           style={{ padding: &amp;#039;8px&amp;#039;, marginRight: &amp;#039;10px&amp;#039;, width: &amp;#039;300px&amp;#039; }}&lt;br /&gt;
           onKeyDown={(e) =&amp;gt; e.key === &amp;#039;Enter&amp;#039; &amp;amp;&amp;amp; handleAddTodo()}&lt;br /&gt;
         /&amp;gt;&lt;br /&gt;
         &amp;lt;button &lt;br /&gt;
           onClick={handleAddTodo} &lt;br /&gt;
           disabled={loading}&lt;br /&gt;
           style={{ padding: &amp;#039;8px 16px&amp;#039; }}&lt;br /&gt;
         &amp;gt;&lt;br /&gt;
           {loading ? &amp;#039;追加中...&amp;#039; : &amp;#039;追加&amp;#039;}&lt;br /&gt;
         &amp;lt;/button&amp;gt;&lt;br /&gt;
       &amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
       {/* Todo一覧 */}&lt;br /&gt;
       &amp;lt;ul style={{ listStyle: &amp;#039;none&amp;#039;, padding: 0 }}&amp;gt;&lt;br /&gt;
         {todos.map((todo) =&amp;gt; (&lt;br /&gt;
           &amp;lt;li&lt;br /&gt;
             key={todo.id}&lt;br /&gt;
             style={{&lt;br /&gt;
               display: &amp;#039;flex&amp;#039;,&lt;br /&gt;
               alignItems: &amp;#039;center&amp;#039;,&lt;br /&gt;
               padding: &amp;#039;10px&amp;#039;,&lt;br /&gt;
               borderBottom: &amp;#039;1px solid #ccc&amp;#039;&lt;br /&gt;
             }}&lt;br /&gt;
           &amp;gt;&lt;br /&gt;
             &amp;lt;input&lt;br /&gt;
               type=&amp;quot;checkbox&amp;quot;&lt;br /&gt;
               checked={todo.completed}&lt;br /&gt;
               onChange={(e) =&amp;gt; handleToggleTodo(todo.id, e.target.checked)}&lt;br /&gt;
               style={{ marginRight: &amp;#039;10px&amp;#039; }}&lt;br /&gt;
             /&amp;gt;&lt;br /&gt;
             &amp;lt;span&lt;br /&gt;
               style={{&lt;br /&gt;
                 flex: 1,&lt;br /&gt;
                 textDecoration: todo.completed ? &amp;#039;line-through&amp;#039; : &amp;#039;none&amp;#039;&lt;br /&gt;
               }}&lt;br /&gt;
             &amp;gt;&lt;br /&gt;
               {todo.title}&lt;br /&gt;
             &amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;button&lt;br /&gt;
               onClick={() =&amp;gt; handleDeleteTodo(todo.id)}&lt;br /&gt;
               style={{ color: &amp;#039;red&amp;#039; }}&lt;br /&gt;
             &amp;gt;&lt;br /&gt;
               削除&lt;br /&gt;
             &amp;lt;/button&amp;gt;&lt;br /&gt;
           &amp;lt;/li&amp;gt;&lt;br /&gt;
         ))}&lt;br /&gt;
       &amp;lt;/ul&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
       {todos.length === 0 &amp;amp;&amp;amp; (&lt;br /&gt;
         &amp;lt;p style={{ textAlign: &amp;#039;center&amp;#039;, color: &amp;#039;#666&amp;#039; }}&amp;gt;&lt;br /&gt;
           Todoがありません&lt;br /&gt;
         &amp;lt;/p&amp;gt;&lt;br /&gt;
       )}&lt;br /&gt;
     &amp;lt;/div&amp;gt;&lt;br /&gt;
   )&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 export default App&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 推奨される事柄 ==&lt;br /&gt;
==== 引数の命名規則 ====&lt;br /&gt;
Rust側ではスネークケース (snake_case) を使用して、TypeScript側ではキャメルケース (camelCase) を使用する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
 // Rust (snake_case)&lt;br /&gt;
 &lt;br /&gt;
 #[command]&lt;br /&gt;
 fn get_user_by_id(user_id: u32) -&amp;gt; Result&amp;lt;User, String&amp;gt; {&lt;br /&gt;
    // ...&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;typescript&amp;quot;&amp;gt;&lt;br /&gt;
 // TypeScript (camelCase)&lt;br /&gt;
 &lt;br /&gt;
 await invoke&amp;lt;User&amp;gt;(&amp;#039;get_user_by_id&amp;#039;, { userId: 1 })&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== 大きなデータの取り扱い ====&lt;br /&gt;
大きなデータを渡す場合は、パフォーマンスに注意する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* チャンク化&lt;br /&gt;
*: 大きなデータは小さなチャンクに分割して処理する。&lt;br /&gt;
* ストリーミング&lt;br /&gt;
*: Channel APIを使用して、ストリーミング処理を行う。&lt;br /&gt;
* 圧縮&lt;br /&gt;
*: 必要に応じてデータを圧縮する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== セキュリティ ====&lt;br /&gt;
CommandsはIPCを通じて通信するため、セキュリティに注意する。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
* 入力検証&lt;br /&gt;
*: 全ての入力を検証し、無効なデータを拒否する。&lt;br /&gt;
* 権限管理&lt;br /&gt;
*: ファイルシステムアクセス等の危険な操作は、必要最小限の権限で実行する。&lt;br /&gt;
* エラーメッセージ&lt;br /&gt;
*: 内部実装の詳細を漏らさないエラーメッセージを返す。&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==== デバッグのヒント ====&lt;br /&gt;
開発時のデバッグに役立つテクニックを以下に示す。&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot;&amp;gt;&lt;br /&gt;
 #[command]&lt;br /&gt;
 fn debug_command(input: String) -&amp;gt; String {&lt;br /&gt;
    #[cfg(debug_assertions)]&lt;br /&gt;
    println!(&amp;quot;Debug: input = {}&amp;quot;, input);&lt;br /&gt;
 &lt;br /&gt;
    format!(&amp;quot;Processed: {}&amp;quot;, input)&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 関連情報 ==&lt;br /&gt;
* [[Tauriの基礎 - 非同期Commands]]&lt;br /&gt;
*: 非同期処理、Channel API、プログレス表示について&lt;br /&gt;
* [[Tauriの基礎 - Commandsのエラーハンドリング]]&lt;br /&gt;
*: エラー処理、thiserror、anyhowについて&lt;br /&gt;
* [https://tauri.app/v2/guide/features/command/ Tauri公式ドキュメント - Commands]&lt;br /&gt;
*: 公式のCommandsリファレンス&lt;br /&gt;
* [https://serde.rs/ Serde公式ドキュメント]&lt;br /&gt;
*: シリアライズ / デシリアライズの詳細&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{#seo:&lt;br /&gt;
|title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki&lt;br /&gt;
|keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Tauri,Rust,React,TypeScript,Commands,IPC,Desktop App,Serde,invoke,generate_handler&lt;br /&gt;
|description={{PAGENAME}} - Tauri Commandsの基本機能に関するガイド | This page is {{PAGENAME}} in our wiki about Tauri Commands&lt;br /&gt;
|image=/resources/assets/MochiuLogo_Single_Blue.png&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
__FORCETOC__&lt;br /&gt;
[[カテゴリ:Rust]]&lt;/div&gt;</summary>
		<author><name>Wiki</name></author>
	</entry>
</feed>