Вправа: Розбір 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; }

Messages

A proto message is encoded as a series of fields, one after the next. Each is implemented as a “tag” followed by the value. The tag contains a field number (e.g., 2 for the id field of a Person message) and a wire type defining how the payload should be determined from the byte stream. These are combined into a single integer, as decoded in unpack_tag below.

Varint

Integers, including the tag, are represented with a variable-length encoding called VARINT. Luckily, parse_varint is defined for you below.

Wire Types

Proto defines several wire types, only two of which are used in this exercise.

The Varint wire type contains a single varint, and is used to encode proto values of type int32 such as Person.id.

The Len wire type contains a length expressed as a varint, followed by a payload of that number of bytes. This is used to encode proto values of type string such as Person.name. It is also used to encode proto values containing sub-messages such as Person.phones, where the payload contains an encoding of the sub-message.

Вправа

The given code also defines callbacks to handle Person and PhoneNumber fields, and to parse a message into a series of calls to those callbacks.

Вам залишається реалізувати функцію parse_field та трейт ProtoMessage для Person та PhoneNumber.

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Speaker Notes

This slide and its sub-slides should take about 30 minutes.
  • У цій вправі існують різні випадки, коли розбір protobuf може не спрацювати, наприклад, якщо ви спробуєте розібрати i32, коли у буфері даних залишилося менше 4 байт. У звичайному Rust-коді ми б впоралися з цим за допомогою переліку Result, але для простоти у цій вправі ми панікуємо, якщо виникають помилки. На четвертий день ми розглянемо обробку помилок у Rust більш детально.