prost

repository·master·Indexed 26 days ago

https://github.com/tokio-rs/prost

A Protocol Buffers implementation for Rust that generates idiomatic Rust code from proto2 and proto3 files. It includes prost-build for build-time code generation, prost-types for well-known types, and prost-derive for encoding/decoding implementations. The library supports no_std environments, custom attribute injection, and efficient serialization using the bytes crate.

Tokens
14.2K
Snippets
41
Records
102
Agent score
86%

What's inside prost

  1. Overview of prost-derive

    master

    prost-derive is a crate responsible for generating encoding and decoding implementations for Rust types that are annotated with prost attributes.

    Note: Most users of the prost ecosystem do not need to interact with prost-derive directly, as its functionality is typically invoked via the main prost crate or through code generation tools like prost-build.

  2. Use `prost-types` for Protocol Buffers well-known types

    master
    prost-types provides Rust definitions for Protocol Buffers well-known types. Use this crate when your Protobuf messages include standard Google types such as Timestamp, Duration, Struct, Value, Any, Empty, or Wrappers.
  3. Generate Rust code from .proto files with prost-build

    master
    prost-build is a build-time utility that automates the generation of Rust code from Protocol Buffers (.proto) files during a Cargo build process. It is typically used within a build.rs script to ensure that your Rust types stay in sync with your protobuf definitions.
  4. Install `prost` in a Cargo project

    master

    To use prost in your Rust project, add it and its dependencies to your Cargo.toml. If you are using Protobuf well-known types, you must also include prost-types.

    [dependencies]
    prost = "0.14"
    # Only necessary if using Protobuf well-known types:
    prost-types = "0.14"
  5. Set up development environment with Nix

    master

    The prost project supports Nix flakes for development.

    To enter a shell with all dependencies configured to build the entire project, run:

    nix develop

    To develop using the Minimum Supported Rust Version (MSRV) as required by project policy, run:

    nix develop .#rust_minimum_version
  6. Configure `prost` for `no_std` environments

    master

    To use prost in a no_std crate, disable the default std features for both prost and prost-types. You must also configure prost-build to use BTreeMap instead of HashMap for all Protobuf map fields in your build.rs to avoid dependency on std::collections::HashMap.

    [dependencies]
    prost = { version = "0.14.4", default-features = false, features = ["derive"] }
    # Only necessary if using Protobuf well-known types:
    prost-types = { version = "0.14.4", default-features = false }

    In build.rs:

    let mut config = prost_build::Config::new();
    config.btree_map(&["."]);
  7. Run Kani verification harnesses

    master

    After installation, cargo kani automatically detects and runs kani::proof harnesses within your crate.

    You can refine your execution using the following flags:

    • --harness <NAME>: Run a specific harness.
    • -p <SUB-CRATE>: Run verification for a specific sub-crate.
  8. Install and use Kani for software verification

    master

    Kani is a software verification tool used to prove the absence of bugs such as unwrap exceptions, overflows, and assertion failures.

    To install Kani, follow the official Kani install guide.

    Once installed, you can use it in two ways:

    • For Cargo projects: Use cargo kani.
    • For individual Rust files: Use kani.
  9. Use `prost-build` for `.proto` compilation

    master
    The recommended way to compile .proto files into Rust code is by using the prost-build library in a build.rs script. Note that prost-build requires protoc (the Protocol Buffers compiler) to be installed on your system unless skip_protoc is enabled.
  10. Run AFL fuzz tests

    master

    To run the AFL fuzz tests for prost, you must first install cargo-afl. Once installed, navigate to the specific target directory, build the fuzz target, and execute the fuzzer using the provided input and output directories.

    # Install cargo-afl
    cargo install -f afl
    
    # Build and run a specific target
    cd fuzz/afl/<target>/
    cargo afl build --bin fuzz-target
    cargo afl fuzz -i in -o out target/debug/fuzz-target
  11. Serialize existing Rust types with prost

    master

    You can use prost to serialize and deserialize existing Rust types by adding the Message derive macro and appropriate field annotations.

    Tag Inference

    prost automatically infers tags sequentially starting from 1. To handle gaps or reserved tags, use the tag attribute on the first field following the gap to specify the next tag number. Subsequent fields will then be tagged sequentially from that value.

    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,
    }
  12. Reproduce an AFL fuzzing crash

    master

    If a crash is detected during AFL fuzzing, you can reproduce it by building the reproduce binary within the target directory and passing the specific crash file from the output directory as an argument.

    cd fuzz/afl/<target>/
    cargo build --bin reproduce
    cargo run --bin reproduce -- out/crashes/<crashfile>