產生 FIDL Rust Crate
您可以利用下列兩種方式,從 FIDL 程式庫產生 FIDL Rust Crate:
- 手動使用 標準 FIDL 工具鍊。
- 自動、 Android Studio 分析應用程式 (後端使用標準 FIDL 工具鍊)。這個選項僅適用於 可在 Fuchsia 原始碼樹狀結構中找到。
程式庫
FIDL library
對應至名為 fidl_
的 Rust 程式庫 Crate,後面會接著
完整資料庫路徑,使用底線而非半形句號。
舉例來說,如果是 library
宣告:
library fuchsia.examples;
對應的 FIDL Crate 名稱為 fidl_fuchsia_examples
:
use fidl_fuchsia_examples as fex;
特徵
FIDL Rust Crate 中的部分方法和常數是由透過實作 FIDL 執行階段 Crate 中的特性。如要存取這些資料, 您必須匯入對應的特徵最簡單的方式就是 從 Prelude 模組一次匯入所有內容:
use fidl::prelude::*;
序數會使用 as _
語法重新匯出特徵,因此 glob 只會匯入
會將特徵帶入解析方法和常數的範圍。無法匯入
特徵的名稱本身
常數
以下是常數:
const BOARD_SIZE uint8 = 9;
const NAME string = "Tic-Tac-Toe";
FIDL 工具鍊會產生下列常數:
pub const BOARD_SIZE: u8
pub const NAME: &str
FIDL 原始類型和 Rust 型別之間的對應概述 內建類型。
欄位
本節說明 FIDL 工具鍊如何將 FIDL 類型轉換為原生類型 Rust 中的多種型別這些類型可以以會員類型顯示, 新增至通訊協定方法。
內建類型
在下表中,如果同時有「擁有者」以及「借用」變化版本
「自有」type 指的是在匯總類型中出現的類型 (例如
做為 struct 欄位或向量元素的類型),而「借用」類型是指
是做為通訊協定方法參數使用的類型
(從用戶端的觀點擷取) 或回應元組值 (來自伺服器的
)。自有和借用的區別存在
運用 Rust 擁有權模型的優勢如果使用
類型 T
,則 proxied 函式呼叫不需要
擁有 T
的擁有權,因此 FIDL 工具鍊需要產生借用版本的
T
。借用版本通常會使用 &mut
,因為類型 T
可能包含控點、
在此案例中,FIDL 繫結會在編碼時 00 至控點,
會修改輸入內容使用 &mut
而非取得擁有權時,呼叫端可以
如果輸入值不含任何控點,就會重複使用輸入值。
FIDL 類型 | Rust 類型 |
---|---|
bool |
bool |
int8 |
i8 |
int16 |
i16 |
int32 |
i32 |
int64 |
i64 |
uint8 |
u8 |
uint16 |
u16 |
uint32 |
u32 |
uint64 |
u64 |
float32 |
f32 |
float64 |
f64 |
array<T, N> |
&mut [T; N] (借用)[T, N] (已擁有) |
vector<T>:N |
&[T] (借用,T 為數字)&mut dyn ExactSizeIterator (借用)Vec (擁有) |
string |
&str (借用)String (已擁有) |
server_end:P |
fidl::endpoints::ServerEnd<PMarker> ,其中 PMarker 是這個通訊協定的標記類型。 |
client_end:P |
fidl::endpoints::ClientEnd<PMarker> 其中 PMarker 是這個通訊協定的標記類型。 |
zx.Handle |
fidl::Handle |
zx.Handle:S |
使用對應的帳號代碼類型。例如 fidl::Channel 或 fidl::Vmo |
使用者定義的類型
位元、列舉和資料表一律會使用產生的類型 T
參照。
結構體和聯集可以是必要或選用項目,可在自有物件中
所謂「利用」或「借用的背景」,也就是說,
Rust 型別。針對特定 struct T
或 union T
,類型如下:
擁有的 | 借用 | |
---|---|---|
必要 | T |
&mut T |
選用 | Option<T> |
Option<&mut T> |
要求、回應和事件參數
當 FIDL 需要產生單一 Rust 類型來代表 要求、回應或事件,例如結果類型 請使用下列規則:
- 多個參數會以參數類型的元組表示。
- 單一參數只會以參數的類型表示。
- 空白的參數組合會使用單位類型
()
表示。
類型
點數
如果是 bits 定義:
type FileMode = strict bits : uint16 {
READ = 0b001;
WRITE = 0b010;
EXECUTE = 0b100;
};
FIDL 工具鍊會產生一組
已呼叫 bitflags
FileMode
含有標記 FileMode::READ
、FileMode::WRITE
和
FileMode::EXECUTE
。
bitflags
結構也提供下列方法:
get_unknown_bits(&self) -> u16
:傳回僅含括 從這個位元值中取得的不明成員如果是嚴格位元,則 會標示為#[deprecated]
且一律傳回 0。has_unknown_bits(&self) -> bool
:傳回這個值是否包含任何 如果是嚴格位元,會標示為#[deprecated]
而且一律會傳回false
產生的 FileMode
結構體一律包含一組完整的 #[derive]
規則。
使用範例:
let flags = fex::FileMode::READ | fex::FileMode::WRITE;
println!("{:?}", flags);
列舉
採用 enum 定義:
type LocationType = strict enum {
MUSEUM = 1;
AIRPORT = 2;
RESTAURANT = 3;
};
FIDL 工具鍊會使用指定的基礎類型產生 Rust enum
。
或 u32
(如果沒有指定):
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(u32)]
pub enum LocationType {
Museum = 1,
Airport = 2,
Restaurant = 3,
}
使用下列方法:
from_primitive(prim: u32) -> Option<Self>
:傳回列舉的Some
變數值 (如有),否則None
。into_primitive(&self) -> u32
:傳回基本判別值。is_unknown(&self) -> bool
:傳回表示這個列舉是否為不明狀態。適用對象 嚴格類型時,會標示為#[deprecated]
且一律會傳回false
。
如果 LocationType
為「彈性」,則內容如下:
其他方法:
from_primitive_allow_unknown(prim: u32) -> Self
:建立 列舉的原始值。unknown() -> Self
:傳回預留位置未知的列舉值。如果列舉 包含標記為[Unknown]
的成員,而該值 這個方法會傳回一個未知成員的值。
產生的 LocationType
enum
一律包含完整的 #[derive]
組合
規則。
使用範例:
let from_raw = fex::LocationType::from_primitive(1).expect("Could not create LocationType");
assert_eq!(from_raw, fex::LocationType::Museum);
assert_eq!(fex::LocationType::Restaurant.into_primitive(), 3);
為了提供來源相容性,彈性列舉為未知
巨集,應該用於比對不明成員,而不是 _
。舉例來說,請參閱 LocationTypeUnknown!()
巨集的用法:
match location_type {
fex::LocationType::Museum => println!("museum"),
fex::LocationType::Airport => println!("airport"),
fex::LocationType::Restaurant => println!("restaurant"),
fex::LocationTypeUnknown!() => {
println!("unknown value: {}", location_type.into_primitive())
}
}
不明巨集的行為與 _
模式相同,但可設定為
全部相符。這有助於找出遺漏的案件。
Structs
假設有 struct 宣告:
type Color = struct {
id uint32;
@allow_deprecated_struct_defaults
name string:MAX_STRING_LENGTH = "red";
};
FIDL 工具鍊會產生 Rust struct
:
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Color {
pub id: u32,
pub name: String,
}
產生的 Color
struct
遵循 #[derive]
規則。
使用範例:
let red = fex::Color { id: 0u32, name: "red".to_string() };
println!("{:?}", red);
聯合工會
考慮到 union 定義:
type JsonValue = strict union {
1: int_value int32;
2: string_value string:MAX_STRING_LENGTH;
};
FIDL 工具鍊會產生 Rust enum
:
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum JsonValue {
IntValue(i32),
StringValue(String),
}
使用下列方法:
ordinal(&self) -> u64
:傳回有效變化版本的序數,如 在 FIDL 類型中指定的值。is_unknown(&self) -> bool
:傳回是否未知此聯集。一律啟用 會針對非彈性聯集類型傳回false
。嚴格適用 就會標示為#[deprecated]
且一律傳回false
。
如果 JsonValue
為「彈性」,則內容如下:
其他方法:
unknown_variant_for_testing() -> Self
:建立不明的聯集值。這個 建議您只用於測試
產生的 JsonValue
enum
遵循 #[derive]
規則。
使用範例:
let int_val = fex::JsonValue::IntValue(1);
let str_val = fex::JsonValue::StringValue("1".to_string());
println!("{:?}", int_val);
assert_ne!(int_val, str_val);
彈性聯集和未知的變體
彈性聯集會產生額外的變化版本來代表 未知的情況系統會將這個變化版本視為私人版本,不應 直接參照。
為了提供來源相容性,「彈性」聯集具有
未知的巨集;此巨集應用於比對不明成員,而不是
_
模式。舉例來說,請參閱 JsonValueUnknown!()
巨集的用法:
match json_value {
fex::JsonValue::IntValue(val) => println!("int: {}", val),
fex::JsonValue::StringValue(val) => println!("string: {}", val),
fex::JsonValueUnknown!() => println!("unknown ordinal: {}", json_value.ordinal()),
}
不明巨集的行為與 _
模式相同,但可設定為
全部相符。這有助於找出遺漏的案件。
當 FIDL 訊息含有不明變體的聯集時,解碼成
JsonValue
,JsonValue::is_unknown()
會傳回 true。
彈性聯集會使用自訂 PartialEq
,表示不明變化版本的行為如下:
NN:它們不等於任何一處,包括本身。請參閱 RFC-0137:
捨棄 FIDL 中的不明資料,即可做為這項決策的背景資料。
在解碼未知的變體時,Strict 聯集會失敗。 彈性聯集會在解碼未知的變化版本時成功,但 無法順利執行
表格
採用 table 定義:
type User = table {
1: age uint8;
2: name string:MAX_STRING_LENGTH;
};
FIDL 工具鍊會產生含有選用成員的 struct
User
:
#[derive(Debug, PartialEq)]
pub struct User {
pub age: Option<u8>,
pub name: Option<String>,
#[doc(hidden)]
pub __source_breaking: fidl::marker::SourceBreaking,
}
如果在解碼期間遇到任何不明欄位,這些欄位就會遭到捨棄。有 ,或判斷是否發生存取事件。
__source_breaking
成員表示要徹底初始化資料表
新增欄位會導致 API 故障。建議您改用
結構體更新語法,用 Default::default()
填入未指定的欄位。
例如:
let user = fex::User { age: Some(20), ..Default::default() };
println!("{:?}", user);
assert!(user.age.is_some());
同樣地,資料表也不允許進行全面比對。相反地,您必須使用
..
語法忽略未指定的欄位。例如:
let fex::User { age, name, .. } = user;
產生的 User
struct
遵循 #[derive]
規則。
內嵌版面配置
產生的 Rust 程式碼會使用 fidlc
保留的名稱,供
內嵌版面配置。
衍生
FIDL 工具鍊為 FIDL 類型產生新的 struct
或 enum
時,
會嘗試從預先定義的實用特徵清單中 derive
盡可能的特徵,如
也可以加入 Debug
、Copy
、Clone
等
可在附錄 A 中找到。
針對結構體、聯集和資料表等匯總類型,衍生字組為
先從所有可能衍生作品的清單開始,然後移除
有些預測條件例如:
間接包含 vector
的匯總類型不會衍生 Copy
,且
包含 handle
的類型 (也就是沒有標示為
resource
) 不會衍生 Copy
和 Clone
。如有疑問
參照產生的程式碼,檢查哪些特徵是由特定的
類型。如要進一步瞭解實作詳情,請參閱附錄 B。
通訊協定
指定通訊協定:
closed protocol TicTacToe {
strict StartGame(struct {
start_first bool;
});
strict MakeMove(struct {
row uint8;
col uint8;
}) -> (struct {
success bool;
new_state box<GameState>;
});
strict -> OnOpponentMove(struct {
new_state GameState;
});
};
與 TicTacToe
互動的主要進入點是 TicTacToeMarker
結構體,包含兩種相關聯的類型:
Proxy
:與非同步用戶端搭配使用的相關 Proxy 類型。在本 例如,這是產生的TicTacToeProxy
類型。同步用戶端 直接使用TicTacToeSynchronousProxy
(請參閱 同步),並不會儲存在TicTacToeMarker
上的相關類型。RequestStream
:與伺服器相關聯的要求串流 必須處理這個通訊協定在這個範例中TicTacToeRequestStream
,由 FIDL 產生。
此外,TicTacToeMarker
還有下列來自
實作 fidl::endpoints::ProtocolMarker
:
DEBUG_NAME: &’static str
:適合偵錯的服務名稱 用途。
其他程式碼也可能根據通訊協定和方法 屬性。
用戶端
非同步
如果是非同步用戶端,FIDL 工具鍊會產生 TicTacToeProxy
結構體。
取代為:
相關類型:
TicTacToeProxy::MakeMoveResponseFut
:回應的Future
類型 這個類型會實作std::future::Future<Output = Result<(bool, Option<Box<GameState>>), fidl::Error>> + Send
。
方法:
new(channel: fidl::AsyncChannel) -> TicTacToeProxy
:為TicTacToe
。take_event_stream(&self) -> TicTacToeEventStream
:取得事件的Stream
才會收到回應 (請參閱「事件」)。
實作 fidl::endpoints::Proxy
的方法:
from_channel(channel: fidl::AsyncChannel) -> TicTacToeProxy
:與TicTacToeProxy::new
。into_channel(self) -> Result<fidl::AsyncChannel>
:嘗試將 也使用 Proxy 追蹤管道as_channel(&self) -> &fidl::AsyncChannel
:取得 Proxy 的參照 基準管道is_closed(&self) -> bool
:檢查 Proxy 是否已收到PEER_CLOSED
網路。on_closed<'a>(&'a self) -> fuchsia_async::OnSignals<'a>
:取得符合以下條件的未來: Proxy 收到PEER_CLOSED
信號時就會完成
實作 TicTacToeProxyInterface
的方法:
start_game(&self, mut start_first: bool) -> Result<(), fidl::Error>
:Proxy 這個方法。它會以引數形式 要求參數,並傳回空白結果。make_move(&self, mut row: u8, mut col: u8) -> Self::MakeMoveResponseFut
: 雙向代理方法。它會將要求做為引數 並傳回回應的Future
。
如需設定非同步 Proxy 的範例,請前往 Rust 教學課程。
TicTacToeProxyInterface
特徵在測試用戶端程式碼時相當實用。適用對象
舉例來說,如果您編寫的函式將 &T
做為參數,其中 T:
TicTacToeProxyInterface
,則可以用假的 Proxy 類型對其進行單元測試:
use futures::future::{ready, Ready};
struct FakeTicTacToeProxy {
move_response: (bool, Option<Box<GameState>>),
}
impl TicTacToeProxyInterface for FakeTicTacToeProxy {
fn start_game(&self, mut start_first: bool) -> Result<(), fidl::Error> {
Ok(())
}
type MakeMoveResponseFut = Ready<fidl::Result<(bool, Option<Box<GameState>>)>>;
fn make_move(&self, mut row: u8, mut col: u8) -> Self::MakeMoveResponseFut {
ready(self.move_response.clone())
}
}
同步
如果是 TicTacToe
通訊協定的同步用戶端,FIDL 工具鍊
利用以下方法產生 TicTacToeSynchronousProxy
結構:
new(channel: fidl::Channel) -> TicTacToeSynchronousProxy
:傳回新的 則適用於管道用戶端的同步 Proxy系統會假設 實作TicTacToe
通訊協定。into_channel(self) -> fidl::Channel
:將 Proxy 轉換回管道。start_game(&self, mut a: i64) -> Result<(), fidl::Error>
:Proxy 方法 就會將要求參數做為引數 會傳回空白結果。make_move(&self, mut row: u8, mut col: u8, __deadline: zx::MonotonicTime) -> Result<(bool, Option<Box<GameState>>), fidl::Error>
:兩者的代理方法 這個方法。會將要求參數做為引數,後面接著 date 參數,用來指定方法呼叫要等待多久的時間 回應 (或zx::MonotonicTime::INFINITE
即可無限期封鎖)。其會傳回 回應參數的Result
。wait_for_event(&self, deadline: zx::MonotonicTime) -> Result<TicTacToeEvent, fidl::Error>
:封鎖直到接收事件或 期限已過 (請使用zx::MonotonicTime::INFINITE
無限期封鎖)。並傳回TicTacToeEvent
列舉的Result
。
如需設定同步 Proxy 的範例,請前往 Rust 教學課程。
伺服器
通訊協定要求串流
為了表示對伺服器的連入要求串流,FIDL 工具鍊
會產生實作 futures::Stream<Item
= Result<TicTacToeRequest, fidl::Error>>
的 TicTacToeRequestStream
類型,以及
fidl::endpoints::RequestStream
。每個通訊協定都有相對應的要求
串流類型
要求列舉
TicTacToeRequest
是一個列舉值,用來代表
TicTacToe
通訊協定。並具有以下變化版本:
StartGame { start_first: bool, control_handle: TicTacToeControlHandle }
:A 觸發及清除要求,當中包含要求參數和控制控點。MakeMove { row: u8, col: u8, responder: TicTacToeMakeMoveResponder }
:兩個 方法要求,內含要求參數和 回應者:
系統會為每個通訊協定產生一個列舉。
要求作答者
這兩種方法各有對應的產生的回應者類型,
回應要求時使用的伺服器在本例中
方法,FIDL 工具鍊會產生 TicTacToeMakeMoveResponder
,
提供以下方法:
send(self, mut success: bool, mut new_state: Option<&mut GameState>) -> Result<(), fidl::Error>
:傳送回應。send_no_shutdown_on_err(self, mut success: bool, mut new_state: Option<&mut GameState>) -> Result<(), fidl::Error>
:與send
類似,但不關閉 發生錯誤。control_handle(&self) -> &TicTacToeControlHandle
:取得基礎 「控制控點」。drop_without_shutdown(mut self)
:拖放作答者而不關閉 頻道。
通訊協定控制控點
FIDL 工具鍊會產生 TicTacToeControlHandle
來封裝用戶端
伺服器端 TicTacToe
通訊協定的端點。這個 SDK 包含
方法如下:
shutdown(&self)
:關閉管道。shutdown_with_epitaph(&self, status: zx_status::Status)
:傳送口號和 然後關閉管道send_on_opponent_move(&self, mut new_state: &mut GameState) -> Result<(), fidl::Error>
:事件的 Proxy 方法,會將事件的 並傳回空白結果 (請參閱 「事件」)。
活動
用戶端
為了在非同步用戶端接收事件,FIDL 工具鍊會產生
TicTacToeEventStream
,可透過 take_event_stream()
取得
方法 (在 TicTacToeProxy
中)。
TicTacToeEventStream
實作 futures::Stream<Item = Result<TicTacToeEvent,
fidl::Error>>
。
為了在同步用戶端接收事件,FIDL 工具鍊會產生
上的 wait_for_event
方法
會傳回 TicTacToeSynchronousProxy
TicTacToeEvent
。
TicTacToeEvent
是一個列舉,代表可能的事件。這個元件具有
下列變體:
OnOpponentMove { new_state: GameState }
:判別標準TicTacToeEvent
事件。
並提供下列方法:
into_on_opponent_move(self) -> Option<GameState>
:傳回以下值的Some
: 事件的 parameters,或None
如果 變數與方法呼叫不符。
伺服器
伺服器可以使用控制控點傳送事件
每個 IP 位址範圍、通訊協定和通訊埠的對應項目控制控點可透過
已從用戶端收到 TicTacToeRequest
。對於火災和遺忘方法,
控制控點可透過 control_handle
欄位使用,有兩種方法
方法,可透過回應器的 control_handle()
方法取得。
通訊協定的控制控點可經由
要求串流 (在此範例中為 TicTacToeRequestStream
)
fidl::endpoints::RequestStream
。
結果
若是含有錯誤類型的方法:
protocol TicTacToe {
MakeMove(struct {
row uint8;
col uint8;
}) -> (struct {
new_state GameState;
}) error MoveError;
};
FIDL 工具鍊會產生公開的 TicTacToeMakeMoveResult
類型別名
std::result::Result<GameState, MoveError>
。其餘繫結程式碼
系統會假設它含有一個回應參數 result
類型:TicTacToeMakeMoveResult
。成功結果使用的類型如下
參數類型轉換規則。
不明互動處理
伺服器端
如果通訊協定宣告為 open
或 ajar
,就會產生的要求
列舉將另一個名為
_UnknownMethod
內含以下欄位:
#[non_exhausitve]
_UnknownMethod {
/// Ordinal of the method that was called.
ordinal: u64,
/// Control handle for the protocol.
control_handle: TicTacToeControlHandle,
/// Enum indicating whether the method is a one-way method or a two way
/// method. This field only exists if the protocol is open.
method_type: fidl::MethodType,
}
MethodType
是一個列舉,包含兩個單位變化版本:OneWay
和 TwoWay
。
指出呼叫的方法種類
每當伺服器收到彈性的不明事件時,要求串流就會 發出這個要求列舉的變數。
用戶端
用戶端無法判斷自己是否知道 flexible
單向方法。
設定要求針對 flexible
雙向方法 (如果方法不明)
用戶端就會收到 Err
結果,其值為
fidl::Error::UnsupportedMethod
。UnsupportedMethod
錯誤只會發生
瞭解較為彈性的雙向方式
除了可能會收到 UnsupportedMethod
錯誤外,
用戶端上 strict
和 flexible
方法之間的 API 差異。
如果是 open
和 ajar
通訊協定,系統會產生的 事件
列舉將另一個名為
_UnknownEvent
內含以下欄位:
#[non_exhaustive]
_UnknownEvent {
/// Ordinal of the event that was sent.
ordinal: u64,
}
每當用戶端收到不明事件時,用戶端事件串流就會發出 就會產生這個事件列舉的變化版本
通訊協定組合
FIDL 沒有繼承的概念,而會產生完整的程式碼做為 以上說明適用於所有編寫的通訊協定。於 也就是針對下列項目產生的程式碼:
protocol A {
Foo();
};
protocol B {
compose A;
Bar();
};
與下列程式碼相同:
protocol A {
Foo();
};
protocol B {
Foo();
Bar();
};
通訊協定和方法屬性
不透明
@transitional
屬性只會影響 ProxyInterface
特徵,
有時用於測試程式碼如果是非測試程式碼,則可以在
讓要求處理常式暫時使用全部接收比對分支
Request
處理常式中。用戶端程式碼不需要進行軟體轉換
因為產生的 Proxy 一律會實作所有方法。
如果是加上 @transitional
屬性註解的方法,ProxyInterface
非同步用戶端的特性
呼叫 unimplemented!()
的預設實作方式。如先前所述
對 Proxy
類型沒有影響,這種類型一律會實作所有特徵的方法。
不過,如果 ProxyInterface
特徵為
在用戶端單元測試中用於假 Proxy
可供偵測
如果是加上 @discoverable
屬性註解的通訊協定,「標記」類型
且會實作 fidl::endpoints::DiscoverableProtocolMarker
特徵。
這會提供 PROTOCOL_NAME
相關常數。
明確編碼和解碼
FIDL 訊息傳送及解碼時,系統會自動編碼訊息 的執行緒。您也可以明確編碼及解碼,例如 將 FIDL 資料寫入檔案。遵循 RFC-0120:單獨使用 FIDL 線 格式,繫結可提供永久 API 和 獨立 API。
保留
如要明確編碼並解碼,建議您使用 persist
和
unpersist
。適用於非資源結構、資料表和
聯集。
舉例來說,您可以保留 Color
結構:
let original_value = fex::Color { id: 0, name: "red".to_string() };
let bytes = fidl::persist(&original_value)?;
之後再拆除:
let decoded_value = fidl::unpersist(&bytes)?;
assert_eq!(original_value, decoded_value);
一般版 UI
針對未使用 persistence API 的進階用途 您可以使用獨立編碼和解碼 API。這適用於 所有結構體、資料表和聯集函式共有兩組,分別適用於 value 類型,以及 resource 類型。
舉例來說,由於 JsonValue
聯集是值類型,因此我們會編碼
方法是使用 standalone_encode_value
:
let original_value = fex::JsonValue::StringValue("hello".to_string());
let (bytes, wire_metadata) = fidl::standalone_encode_value(&original_value)?;
這會傳回一個位元組向量,以及一個儲存線路格式的不透明物件
中繼資料。如要解碼,請將這兩個值傳遞至 standalone_decode_value
:
let decoded_value = fidl::standalone_decode_value(&bytes, &wire_metadata)?;
assert_eq!(original_value, decoded_value);
另外,請思考結構 EventStruct
:
type EventStruct = resource struct {
event zx.Handle:<EVENT, optional>;
};
由於這是資源類型,因此我們會使用
standalone_encode_resource
:
let original_value = fex::EventStruct { event: Some(fidl::Event::create()) };
let (bytes, handle_dispositions, wire_metadata) =
fidl::standalone_encode_resource(original_value)?;
除了位元組和傳輸格式中繼資料以外,這也會傳回
HandleDisposition
。如要解碼,請將控點配置轉換為
HandleInfo
,然後將這三個值傳遞至
standalone_decode_resource
:
let mut handle_infos = fidl::convert_handle_dispositions_to_infos(handle_dispositions)?;
let decoded_value: fex::EventStruct =
fidl::standalone_decode_resource(&bytes, &mut handle_infos, &wire_metadata)?;
assert!(decoded_value.event.is_some());
附錄 A:衍生特徵
"Debug",
"Copy",
"Clone",
"Default",
"Eq",
"PartialEq",
"Ord",
"PartialOrd",
"Hash",
附錄 B:填補衍生資料
您可以看到特徵衍生規則的計算結果: fidlgen_rust:
// Calculates what traits should be derived for each output type,
// filling in all `*derives` in the IR.
func (c *compiler) fillDerives(ir *Root) {