// Typed message example: a Person and AddressBook implemented with the
// Message trait, demonstrating an end-to-end schema-driven workflow.
//
// Wire schema (field numbers are part of the protocol contract):
// message Person {
// string name = 1;
// int32 age = 2;
// bool active = 3;
// repeated string tags = 4;
// }
///|
/// A typed protobuf message with explicit field numbers.
pub(all) struct Person {
name : String
age : Int
active : Bool
tags : Array[String]
} derive(Debug, Eq)
///|
/// Create a Person from its fields.
pub fn Person::new(
name : String,
age : Int,
active : Bool,
tags : Array[String],
) -> Person {
{ name, age, active, tags }
}
///|
/// Encode a Person into an Encoder.
pub fn Person::encode(self : Person, enc : Encoder) -> Unit {
let _ = enc.encode_string(1U, self.name)
let _ = enc.encode_int32(2U, self.age)
let _ = enc.encode_bool(3U, self.active)
for tag in self.tags {
let _ = enc.encode_string(4U, tag)
}
}
///|
/// Decode a Person from a Decoder. Unknown fields are skipped.
pub fn Person::decode(dec : Decoder) -> Person {
let mut name = ""
let mut age = 0
let mut active = false
let tags : Array[String] = []
while dec.read_tag() is Some((fnum, wt)) {
match fnum {
1U => if dec.read_string() is Some(v) { name = v }
2U => if dec.read_int32() is Some(v) { age = v }
3U => if dec.read_bool() is Some(v) { active = v }
4U => if dec.read_string() is Some(v) { tags.push(v) }
_ => dec.skip_field(wt) |> ignore
}
}
{ name, age, active, tags }
}
///|
/// Serialize a Person to bytes.
pub fn Person::to_bytes(self : Person) -> Bytes {
let enc = Encoder::new()
self.encode(enc)
enc.to_bytes()
}
///|
/// Deserialize a Person from bytes.
pub fn Person::from_bytes(bytes : Bytes) -> Person {
Person::decode(Decoder::new(bytes))
}
///|
/// A collection of people, encoded as a repeated length-delimited field.
pub(all) struct AddressBook {
people : Array[Person]
} derive(Debug, Eq)
///|
/// Create an AddressBook from a list of people.
pub fn AddressBook::new(people : Array[Person]) -> AddressBook {
{ people, }
}
///|
/// Encode an AddressBook (field 1 is a repeated Person message).
pub fn AddressBook::encode(self : AddressBook, enc : Encoder) -> Unit {
for person in self.people {
let inner = Encoder::new()
person.encode(inner)
let _ = enc.encode_message(1U, inner)
}
}
///|
/// Decode an AddressBook from a Decoder.
pub fn AddressBook::decode(dec : Decoder) -> AddressBook {
let people : Array[Person] = []
while dec.read_tag() is Some((fnum, wt)) {
match fnum {
1U =>
if dec.read_message() is Some(inner) {
people.push(Person::decode(inner))
}
_ => dec.skip_field(wt) |> ignore
}
}
{ people, }
}
///|
/// Serialize an AddressBook to bytes.
pub fn AddressBook::to_bytes(self : AddressBook) -> Bytes {
let enc = Encoder::new()
self.encode(enc)
enc.to_bytes()
}
///|
/// Deserialize an AddressBook from bytes.
pub fn AddressBook::from_bytes(bytes : Bytes) -> AddressBook {
AddressBook::decode(Decoder::new(bytes))
}