### Test Module Setup Source: https://docs.rs/prost-derive/0.14.4/src/prost_derive/field/scalar.rs.html?search=std%3A%3Avec Initial setup for the test module. ```rust #[cfg(test)] mod tests { use super::{DefaultValue, Ty}; use syn::{parse_str, Lit, Path}; #[test] ``` -------------------------------- ### compile_protos method documentation with example Source: https://docs.rs/prost-build/latest/src/prost_build/config.rs.html Documentation for the `compile_protos` method, including an example `build.rs` that uses `prost_build::Config::new()`, `btree_map`, and `compile_protos`. The example is marked as `no_run` and shows how to compile proto files with additional configuration. ```rust /// Compile `.proto` files into Rust files during a Cargo build with additional code generator /// configuration options. /// /// This method is like the `prost_build::compile_protos` function, with the added ability to /// specify non-default code generation options. See that function for more information about /// the arguments and generated outputs. /// /// The `protos` and `includes` arguments are ignored if `skip_protoc_run` is specified. /// /// # Example `build.rs` /// /// ```rust,no_run /// # use std::io::Result; /// fn main() -> Result<()> { /// let mut prost_build = prost_build::Config::new(); /// prost_build.btree_map(&["."]); /// prost_build.compile_protos(&["src/frontend.proto", "src/backend.proto"], &["src"])?; /// Ok(()) /// } /// ``` ``` -------------------------------- ### Example build.rs using compile_protos Source: https://docs.rs/prost-build/0.14.4/prost_build/fn.compile_protos.html?search= A minimal build.rs example that calls compile_protos with two .proto files and an include directory, then returns Ok(()). This is the typical usage in a Cargo build script. ```rust fn main() -> Result<()> { prost_build::compile_protos(&["src/frontend.proto", "src/backend.proto"], &["src"])?; Ok(()) } ``` -------------------------------- ### Pack and unpack Any in C++, Java, Python, and Go Source: https://docs.rs/prost-types/0.14.4/src/prost_types/protobuf.rs.html?search=u32+-%3E+bool These examples show how to pack and unpack a message into an `Any` in C++, Java, Python, and Go. The C++ example uses `PackFrom` and `UnpackTo`; Java uses `Any.pack` and `any.unpack`; Python uses `any.Pack` and `any.Unpack`; Go uses `anypb.New` and `any.UnmarshalTo`. Each example assumes a `Foo` message type and demonstrates the typical usage pattern. ```text Foo foo = ...; Any any; any.PackFrom(foo); ... if (any.UnpackTo(&foo)) { ... } ``` ```text Foo foo = ...; Any any = Any.pack(foo); ... if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } ``` ```text foo = Foo(...) any = Any() any.Pack(foo) ... if any.Is(Foo.DESCRIPTOR): any.Unpack(foo) ... ``` ```text foo := &pb.Foo{...} any, err := anypb.New(foo) if err != nil { ... } ... foo := &pb.Foo{} if err := any.UnmarshalTo(foo); err != nil { ... } ``` -------------------------------- ### Config struct and btree_map method example Source: https://docs.rs/prost-build/0.14.4/src/prost_build/config.rs.html?search=u32+-%3E+bool The source shows the beginning of the `Config` struct definition and its `btree_map` method documentation, including a Rust code example block that demonstrates various path patterns for `config.btree_map`. The example is truncated at the end of the method body, but the visible code is extracted verbatim. ```rust use std::collections::HashMap; use std::default; use std::env; use std::ffi::{OsStr, OsString}; use std::fmt; use std::fs; use std::io::{Error, ErrorKind, Result, Write}; use std::path::{Path, PathBuf}; use std::process::Command; use log::debug; use log::trace; use prost::Message; use prost_types::{FileDescriptorProto, FileDescriptorSet}; use crate::code_generator::CodeGenerator; use crate::context::Context; use crate::extern_paths::ExternPaths; use crate::message_graph::MessageGraph; use crate::path::PathMap; use crate::BytesType; use crate::MapType; use crate::Module; use crate::ServiceGenerator; /// Configuration options for Protobuf code generation. /// /// This configuration builder can be used to set non-default code generation options. pub struct Config { pub(crate) file_descriptor_set_path: Option, pub(crate) service_generator: Option>, pub(crate) map_type: PathMap, pub(crate) bytes_type: PathMap, pub(crate) type_attributes: PathMap, pub(crate) message_attributes: PathMap, pub(crate) enum_attributes: PathMap, pub(crate) field_attributes: PathMap, pub(crate) boxed: PathMap<()>, pub(crate) prost_types: bool, pub(crate) strip_enum_prefix: bool, pub(crate) out_dir: Option, pub(crate) extern_paths: Vec<(String, String)>, pub(crate) default_package_filename: String, pub(crate) enable_type_names: bool, pub(crate) type_name_domains: PathMap, pub(crate) protoc_args: Vec, pub(crate) protoc_executable: PathBuf, pub(crate) disable_comments: PathMap<()>, pub(crate) skip_debug: PathMap<()>, pub(crate) skip_protoc_run: bool, pub(crate) skip_source_info: bool, pub(crate) include_file: Option, pub(crate) prost_path: Option, pub(crate) prost_types_path: Option, #[cfg(feature = "format")] pub(crate) fmt: bool, } impl Config { /// Creates a new code generator configuration with default options. pub fn new() -> Config { Config::default() } /// Configure the code generator to generate Rust [`BTreeMap`][1] fields for Protobuf /// [`map`][2] type fields. /// /// # Arguments /// /// **`paths`** - paths to specific fields, messages, or packages which should use a Rust /// `BTreeMap` for Protobuf `map` fields. Paths are specified in terms of the Protobuf type /// name (not the generated Rust type name). Paths with a leading `.` are treated as fully /// qualified names. Paths without a leading `.` are treated as relative, and are suffix /// matched on the fully qualified field name. If a Protobuf map field matches any of the /// paths, a Rust `BTreeMap` field is generated instead of the default [`HashMap`][3]. /// /// The matching is done on the Protobuf names, before converting to Rust-friendly casing /// standards. /// /// # Examples /// /// ```rust /// # let mut config = prost_build::Config::new(); /// // Match a specific field in a message type. /// config.btree_map(&[".my_messages.MyMessageType.my_map_field"]); /// /// // Match all map fields in a message type. /// config.btree_map(&[".my_messages.MyMessageType"]); /// /// // Match all map fields in a package. /// config.btree_map(&[".my_messages"]); /// /// // Match all map fields. Specially useful in `no_std` contexts. /// config.btree_map(&["."]); /// /// // Match all map fields in a nested message. /// config.btree_map(&[".my_messages.MyMessageType.MyNestedMessageType"]); /// /// // Match all fields named 'my_map_field'. /// config.btree_map(&["my_map_field"]); /// /// // Match all fields named 'my_map_field' in messages named 'MyMessageType', regardless of /// // package or nesting. /// config.btree_map(&["MyMessageType.my_map_field"]); /// /// // Match all fields named 'my_map_field', and all fields in the 'foo.bar' package. /// config.btree_map(&["my_map_field", ".foo.bar"]); /// ``` /// /// [1]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html /// [2]: https://protobuf.dev/programming-guides/proto3/#maps /// [3]: https://doc.rust-lang.org/std/collections/struct.HashMap.html pub fn btree_map(&mut self, paths: I) -> &mut Self where I: IntoIterator, S: AsRef, { self.map_type.clear(); for matcher in paths { self.map_type } } } ``` -------------------------------- ### Mixin example and configuration Source: https://docs.rs/prost-types/0.14.4/src/prost_types/protobuf.rs.html Shows a mixin example where an interface includes another interface's methods, with HTTP annotations and version prefixes. The second block is a mixin configuration listing the included service. ```text package google.acl.v1; service AccessControl { // Get the underlying ACL object. rpc GetAcl(GetAclRequest) returns (Acl) { option (google.api.http).get = "/v1/{resource=**}:getAcl"; } } package google.storage.v2; service Storage { rpc GetAcl(GetAclRequest) returns (Acl); // Get a data record. rpc GetData(GetDataRequest) returns (Data) { option (google.api.http).get = "/v2/{resource=**}"; } } ``` ```text apis: - name: google.storage.v2.Storage ``` -------------------------------- ### Config::compile_fds example build.rs Source: https://docs.rs/prost-build/0.14.4/prost_build/struct.Config.html?search= Example build.rs for Config::compile_fds. It obtains a FileDescriptorSet from an external source (here a placeholder fds() function) and passes it to compile_fds, which compiles the descriptors into Rust files without invoking protoc. ```rust fn main() -> std::io::Result<()> { let file_descriptor_set = fds(); prost_build::Config::new() .compile_fds(file_descriptor_set) } ``` -------------------------------- ### Example Target Message Source: https://docs.rs/prost-types/0.14.4/prost_types/struct.FieldMask.html?search= The initial state of the target message before an update operation. ```protobuf f { b { d: 1 x: 2 } c: [1] } ``` -------------------------------- ### Compute Timestamp from Java System.currentTimeMillis() Source: https://docs.rs/prost-types/0.14.4/prost_types/struct.Timestamp.html Example 4: Uses System.currentTimeMillis() to get milliseconds, converting to seconds and nanoseconds. ```java long millis = System.currentTimeMillis(); Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) .setNanos((int) ((millis % 1000) * 1000000)).build(); ``` -------------------------------- ### Example build.rs using prost_build::Config::compile_protos Source: https://docs.rs/prost-build/0.14.4/src/prost_build/config.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Shows a minimal build.rs that creates a prost_build::Config, enables btree_map for the current directory, and compiles frontend.proto and backend.proto from the src directory. The protos and includes arguments are ignored if skip_protoc_run is specified. ```rust # use std::io::Result; fn main() -> Result<()> { let mut prost_build = prost_build::Config::new(); prost_build.btree_map(&["."]); prost_build.compile_protos(&["src/frontend.proto", "src/backend.proto"], &["src"])?; Ok(()) } ``` -------------------------------- ### Compute Timestamp from Java Instant.now() Source: https://docs.rs/prost-types/0.14.4/prost_types/struct.Timestamp.html Example 5: Uses Instant.now() to get the current instant, extracting epoch seconds and nanoseconds. ```java Instant now = Instant.now(); Timestamp timestamp = Timestamp.newBuilder().setSeconds(now.getEpochSecond()) .setNanos(now.getNano()).build(); ``` -------------------------------- ### Mixin examples: simple mixin, configuration, and root path Source: https://docs.rs/prost-types/0.14.4/prost_types/struct.Mixin.html These examples illustrate the mixin concept: the first shows the original AccessControl service and the Storage service that includes it; the second shows the mixin configuration; the third shows the effective Storage service after inheritance; the fourth shows a mixin configuration with a root field; the fifth shows the resulting inherited HTTP annotation with the root path applied. ```proto package google.acl.v1; service AccessControl { // Get the underlying ACL object. rpc GetAcl(GetAclRequest) returns (Acl) { option (google.api.http).get = "/v1/{resource=**}:getAcl"; } } package google.storage.v2; service Storage { rpc GetAcl(GetAclRequest) returns (Acl); // Get a data record. rpc GetData(GetDataRequest) returns (Data) { option (google.api.http).get = "/v2/{resource=**}"; } } ``` ```yaml apis: - name: google.storage.v2.Storage mixins: - name: google.acl.v1.AccessControl ``` ```proto service Storage { // Get the underlying ACL object. rpc GetAcl(GetAclRequest) returns (Acl) { option (google.api.http).get = "/v2/{resource=**}:getAcl"; } ... } ``` ```yaml apis: - name: google.storage.v2.Storage mixins: - name: google.acl.v1.AccessControl root: acls ``` ```proto service Storage { // Get the underlying ACL object. rpc GetAcl(GetAclRequest) returns (Acl) { option (google.api.http).get = "/v2/acls/{resource=**}:getAcl"; } ... } ``` -------------------------------- ### Compute Timestamp from Win32 GetSystemTimeAsFileTime() Source: https://docs.rs/prost-types/0.14.4/prost_types/struct.Timestamp.html Example 3: Uses GetSystemTimeAsFileTime() to get a FILETIME, converts ticks (100 nanoseconds) to seconds and nanoseconds, adjusting for the Windows epoch offset of 11644473600 seconds. ```cpp FILETIME ft; GetSystemTimeAsFileTime(&ft); UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. Timestamp timestamp; timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); ``` -------------------------------- ### Tag inference for existing types: annotated Person struct Source: https://docs.rs/prost/%5E0.14.4 Shows how to annotate an existing Rust type with prost derive macros. Tags are inferred sequentially starting at 1; use the tag attribute to skip reserved or removed numbers. The example also demonstrates an enum with explicit values. ```rust use prost; use prost::{Enumeration, Message}; #[derive(Clone, PartialEq, Message)] struct Person { #[prost(string, tag = "1")] pub id: String, // tag=1 // NOTE: Old "name" field has been removed // pub name: String, // tag=2 (Removed) #[prost(string, tag = "6")] pub given_name: String, // tag=6 #[prost(string)] pub family_name: String, // tag=7 #[prost(string)] pub formatted_name: String, // tag=8 #[prost(uint32, tag = "3")] pub age: u32, // tag=3 #[prost(uint32)] pub height: u32, // tag=4 #[prost(enumeration = "Gender")] pub gender: i32, // tag=5 // NOTE: Skip to less commonly occurring fields #[prost(string, tag = "16")] pub name_prefix: String, // tag=16 (eg. mr/mrs/ms) #[prost(string)] pub name_suffix: String, // tag=17 (eg. jr/esq) #[prost(string)] pub maiden_name: String, // tag=18 } #[derive(Clone, Copy, Debug, PartialEq, Eq, Enumeration)] pub enum Gender { Unknown = 0, Female = 1, Male = 2, } ``` -------------------------------- ### Example build.rs for Config::load_fds Source: https://docs.rs/prost-build/0.14.4/src/prost_build/config.rs.html?search=std%3A%3Avec Demonstrates how to load .proto files into a FileDescriptorSet, introspect services and methods, and apply custom attributes to messages before compiling. ```rust fn main() -> std::io::Result<()> { let mut config = Config::new(); let file_descriptor_set = config.load_fds(&["src/frontend.proto", "src/backend.proto"], &["src"])?; // Add custom attributes to messages that are service inputs or outputs. for file in &file_descriptor_set.file { for service in &file.service { for method in &service.method { if let Some(input) = &method.input_type { config.message_attribute(input, "#[derive(custom_proto::Input)]"); } if let Some(output) = &method.output_type { config.message_attribute(output, "#[derive(custom_proto::Output)]"); } } } } config.compile_fds(file_descriptor_set) } ``` -------------------------------- ### Tag inference for existing types with prost derive Source: https://docs.rs/prost/0.14.4/prost/index.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Shows tag inference for existing Rust types. Fields are tagged sequentially starting at 1, but explicit tag attributes can skip reserved or removed numbers. The example demonstrates skipping tag 2 and using tag 16 for a less common field. ```rust use prost; use prost::{Enumeration, Message}; #[derive(Clone, PartialEq, Message)] struct Person { #[prost(string, tag = "1")] pub id: String, // tag=1 // NOTE: Old "name" field has been removed // pub name: String, // tag=2 (Removed) #[prost(string, tag = "6")] pub given_name: String, // tag=6 #[prost(string)] pub family_name: String, // tag=7 #[prost(string)] pub formatted_name: String, // tag=8 #[prost(uint32, tag = "3")] pub age: u32, // tag=3 #[prost(uint32)] pub height: u32, // tag=4 #[prost(enumeration = "Gender")] pub gender: i32, // tag=5 // NOTE: Skip to less commonly occurring fields #[prost(string, tag = "16")] pub name_prefix: String, // tag=16 (eg. mr/mrs/ms) #[prost(string)] pub name_suffix: String, // tag=17 (eg. jr/esq) #[prost(string)] pub maiden_name: String, // tag=18 } #[derive(Clone, Copy, Debug, PartialEq, Eq, Enumeration)] pub enum Gender { Unknown = 0, Female = 1, Male = 2, } ``` -------------------------------- ### Go example: Pack and unpack a message Source: https://docs.rs/prost-types/0.14.4/prost_types/struct.Any.html?search=u32+-%3E+bool Shows how to pack a message into an `Any` using `anypb.New(foo)` and unpack it with `any.UnmarshalTo(foo)` in Go. Error handling is shown for both operations. ```go foo := &pb.Foo{...} any, err := anypb.New(foo) if err != nil { ... } ... foo := &pb.Foo{} if err := any.UnmarshalTo(foo); err != nil { ... } ``` -------------------------------- ### ReservedRange::start Source: https://docs.rs/prost-types/0.14.4/prost_types/descriptor_proto/struct.ReservedRange.html Returns the value of the start field, or the default value if start is unset. ```APIDOC ## ReservedRange::start ### Description Returns the value of `start`, or the default value if `start` is unset. ### Method `pub fn start(&self) -> i32` ### Parameters None ### Returns - `i32` - The value of `start`, or the default value if unset. ``` -------------------------------- ### Initialize Nix development shell Source: https://docs.rs/prost/0.14.4/prost/index.html?search= Run this command to enter a shell with all dependencies configured for building the project. ```bash nix develop ``` -------------------------------- ### Message Declarations for Field Mask Example Source: https://docs.rs/prost-types/0.14.4/prost_types/struct.FieldMask.html?search= Example message declarations used to demonstrate field mask encoding. ```protobuf message Profile { User user = 1; Photo photo = 2; } message User { string display_name = 1; string address = 2; } ``` -------------------------------- ### Example .proto file (tutorial.proto) Source: https://docs.rs/prost/0.14.4/prost?search= Defines Person and AddressBook messages with nested types and enums. Used as input to prost-build to generate Rust code. ```protobuf syntax = "proto3"; package tutorial; message Person { string name = 1; int32 id = 2; // Unique ID number for this person. string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { string number = 1; PhoneType type = 2; } repeated PhoneNumber phones = 4; } // Our address book file is just one of these. message AddressBook { repeated Person people = 1; } ``` -------------------------------- ### Example field mask paths Source: https://docs.rs/prost-types/0.14.4/prost_types/struct.FieldMask.html?search=std%3A%3Avec Example paths for a FieldMask, showing symbolic field paths like 'f.a' and 'f.b.d'. ```text paths: "f.a" paths: "f.b.d" ``` -------------------------------- ### Compute seconds from Unix epoch for year start Source: https://docs.rs/prost-types/0.14.4/src/prost_types/datetime.rs.html?search=std%3A%3Avec Returns the offset in seconds from the Unix epoch of the start of a year. Returns an i128 because the start of the earliest supported year underflows i64. Based on musl's __year_to_secs converted to Rust via c2rust and cleaned up by hand. ```rust fn year_to_seconds(year: i64) -> (i128, bool) { let is_leap; let year = year - 1900; // Fast path for years 1901 - 2038. if (1..=138).contains(&year) { let mut leaps: i64 = (year - 68) >> 2; if (year - 68).trailing_zeros() >= 2 { leaps -= 1; is_leap = true; } else { is_leap = false; } return ( ``` -------------------------------- ### Create and set up the snazzy crate Source: https://docs.rs/prost-build/0.14.4/prost_build?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Initializes a new library crate named `snazzy` and adds `prost-build` and `prost` as dependencies. The first command creates the crate and changes into its directory; the second adds the build dependency and the runtime dependency. ```shell $ cargo new --lib snazzy && cd snazzy ``` ```shell $ cargo add --build prost-build $ cargo add prost ``` -------------------------------- ### Deserialize a message from Any using Any::to_msg Source: https://docs.rs/prost-types/%5E0.14.4 Deserializes an Any instance back into a Timestamp message. This example is from the Deserialization section and assumes the `any` variable from the serialization example is available. ```rust let message = any.to_msg::().unwrap(); ``` -------------------------------- ### Example of a mixin configuration Source: https://docs.rs/prost-types/0.14.4/prost_types/struct.Mixin.html?search=u32+-%3E+bool YAML configuration showing how to specify a mixin in an API configuration. ```yaml apis: - name: google.storage.v2.Storage mixins: - name: google.acl.v1.AccessControl ``` -------------------------------- ### boxed method example Source: https://docs.rs/prost-build/0.14.4/src/prost_build/config.rs.html?search= Example usage of the boxed method to wrap a matched field in a Box. The path matches a field within a message type. ```rust # let mut config = prost_build::Config::new(); config.boxed(".my_messages.MyMessageType.my_field"); ``` -------------------------------- ### Example of a simple mixin Source: https://docs.rs/prost-types/0.14.4/prost_types/struct.Mixin.html?search=u32+-%3E+bool Proto service definitions showing a simple mixin where AccessControl is mixed into Storage. ```proto package google.acl.v1; service AccessControl { // Get the underlying ACL object. rpc GetAcl(GetAclRequest) returns (Acl) { option (google.api.http).get = "/v1/{resource=**}:getAcl"; } } package google.storage.v2; service Storage { rpc GetAcl(GetAclRequest) returns (Acl); // Get a data record. rpc GetData(GetDataRequest) returns (Data) { option (google.api.http).get = "/v2/{resource=**}"; } } ``` -------------------------------- ### ExtensionRange::start Source: https://docs.rs/prost-types/0.14.4/prost_types/descriptor_proto/struct.ExtensionRange.html?search=std%3A%3Avec Returns the value of the start field, or the default value (0) if unset. This method provides safe access to the start bound of the extension range. ```APIDOC ## Function start ### Description Returns the value of `start`, or the default value if `start` is unset. ### Method `pub fn start(&self) -> i32` ### Return Value - `i32` - The value of the `start` field, or the default value (0) if unset. ``` -------------------------------- ### Generated Rust code (tutorial.rs) Source: https://docs.rs/prost/0.14.4/prost?search= Shows the Rust structs and enums generated from the example .proto file. Demonstrates prost attributes and module nesting. ```rust #[derive(Clone, PartialEq, ::prost::Message)] pub struct Person { #[prost(string, tag="1")] pub name: ::prost::alloc::string::String, /// Unique ID number for this person. #[prost(int32, tag="2")] pub id: i32, #[prost(string, tag="3")] pub email: ::prost::alloc::string::String, #[prost(message, repeated, tag="4")] pub phones: ::prost::alloc::vec::Vec, } /// Nested message and enum types in `Person`. pub mod person { #[derive(Clone, PartialEq, ::prost::Message)] pub struct PhoneNumber { #[prost(string, tag="1")] pub number: ::prost::alloc::string::String, #[prost(enumeration="PhoneType", tag="2")] pub r#type: i32, } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum PhoneType { Mobile = 0, Home = 1, Work = 2, } } /// Our address book file is just one of these. #[derive(Clone, PartialEq, ::prost::Message)] pub struct AddressBook { #[prost(message, repeated, tag="1")] pub people: ::prost::alloc::vec::Vec, } ``` -------------------------------- ### Example: Using compile_fds in build.rs Source: https://docs.rs/prost-build/0.14.4/prost_build/fn.compile_fds.html Example usage of `compile_fds` in a `build.rs` file. It calls `fds()` to obtain a `FileDescriptorSet` and passes it to `compile_fds`. The function returns a `std::io::Result<()>`. ```rust fn main() -> std::io::Result<()> { let file_descriptor_set = fds(); prost_build::compile_fds(file_descriptor_set) } ``` -------------------------------- ### Java example: Pack and unpack a message Source: https://docs.rs/prost-types/0.14.4/prost_types/struct.Any.html?search=u32+-%3E+bool Shows how to pack a message into an `Any` using `Any.pack(foo)` and unpack it with `any.unpack(Foo.class)` after checking `any.is(Foo.class)` in Java. ```java Foo foo = ...; Any any = Any.pack(foo); ... if (any.is(Foo.class)) { foo = any.unpack(Foo.class); } ``` -------------------------------- ### extern_path example: uuid.proto definition Source: https://docs.rs/prost-build/0.14.4/src/prost_build/config.rs.html?search=std%3A%3Avec Example .proto file for a crate named uuid that defines a prost-generated Uuid type. This is used to illustrate how extern_path can substitute types from an external crate. ```proto // uuid.proto syntax = "proto3"; package uuid; message Uuid { string uuid_str = 1; } ``` -------------------------------- ### Python example: Pack and unpack a message Source: https://docs.rs/prost-types/0.14.4/prost_types/struct.Any.html?search=u32+-%3E+bool Shows how to pack a message into an `Any` using `any.Pack(foo)` and unpack it with `any.Unpack(foo)` after checking `any.Is(Foo.DESCRIPTOR)` in Python. ```python foo = Foo(...) any = Any() any.Pack(foo) ... if any.Is(Foo.DESCRIPTOR): any.Unpack(foo) ... ``` -------------------------------- ### Start enumeration derive implementation Source: https://docs.rs/prost-derive/0.14.4/src/prost_derive/lib.rs.html?search=std%3A%3Avec Starts the enumeration derive implementation by parsing the input, extracting attributes, and matching on the data kind. It rejects structs and unions with an error, then begins iterating over variants. ```rust fn try_enumeration(input: TokenStream) -> Result { let input: DeriveInput = syn::parse2(input)?; let ident = input.ident; let Attributes { prost_path, .. } = Attributes::new(input.attrs)?; let generics = &input.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let punctuated_variants = match input.data { Data::Enum(DataEnum { variants, .. }) => variants, Data::Struct(_) => bail!("Enumeration can not be derived for a struct"), Data::Union(..) => bail!("Enumeration can not be derived for a union"), }; // Map the variants into 'fields'. let mut variants: Vec<(Ident, Expr, Option)> = Vec::new(); for Variant { attrs, ident, fields, discriminant, .. } in punctuated_variants { match fields { Fields::Unit => (), Fields::Named(_) | Fields::Unnamed(_) => { ```