演習: Protobufの解析
この演習では、protobuf バイナリ エンコード用のパーサーを作成します。見かけよりも簡単ですので、心配はいりません。これは、データのスライスを渡す一般的な解析パターンを示しています。基になるデータ自体がコピーされることはありません。
protobuf メッセージを完全に解析するには、フィールド番号でインデックス付けされたフィールドの型を知る必要があります。これは通常、proto
ファイルで提供されます。この演習では、フィールドごとに呼び出される関数の match
ステートメントに、その情報をエンコードします。
次の proto を使用します。
message PhoneNumber {
optional string number = 1;
optional string type = 2;
}
message Person {
optional string name = 1;
optional int32 id = 2;
repeated PhoneNumber phones = 3;
}
proto メッセージは、連続するフィールドとしてエンコードされます。それぞれが後ろに値を伴う「タグ」として実装されます。タグにはフィールド番号(例: Person
メッセージの id
フィールドには 2
)と、バイト ストリームからペイロードがどのように決定されるかを定義するワイヤータイプが含まれます。
タグを含む整数は、VARINT と呼ばれる可変長エンコードで表されます。幸いにも、parse_varint
は以下ですでに定義されています。また、このコードでは、Person
フィールドと PhoneNumber
フィールドを処理し、メッセージを解析してこれらのコールバックに対する一連の呼び出しに変換するコールバックも定義しています。
残る作業は、parse_field
関数と、Person
および PhoneNumber
の ProtoMessage
トレイトを実装するだけです。
Speaker Notes
This slide and its sub-slides should take about 30 minutes.
- In this exercise there are various cases where protobuf parsing might fail, e.g. if you try to parse an
i32
when there are fewer than 4 bytes left in the data buffer. In normal Rust code we’d handle this with theResult
enum, but for simplicity in this exercise we panic if any errors are encountered. On day 4 we’ll cover error handling in Rust in more detail.