Protocol Buffers 的 Rust 实现提供了惯用的 Rust 绑定,使开发人员能够在 Rust 项目中使用 Protocol Buffers。本文档涵盖了 Rust Protocol Buffers 实现的架构、设计原则、代码生成和运行时组件。
Protocol Buffers 的 Rust 实现包含两个主要部分:
protoc) 的 Rust 代码生成器。Rust 实现支持两种不同的内核(底层实现):
这两种内核向用户提供相同的 API,但具有不同的内部实现和性能特征。
来源:rust/BUILD31-43 rust/BUILD80-173 src/google/protobuf/compiler/rust/generator.cc136-271
Rust 实现的中心是一个类型系统,它允许高效且安全地与 Protocol Buffers 进行交互。该架构遵循几个关键的设计原则:
该实现支持两种内核:
| 内核 | 描述 | Rust 目标 |
|---|---|---|
| C++ | 通过 FFI 使用 C++ Protocol Buffers 实现。 | protobuf_cpp |
| upb (µprotobuf) | 通过 FFI 使用 upb C 实现。 | protobuf_upb |
内核选择由 rust_proto_library_kernel 构建标志控制,默认为 "cpp"。
来源:rust/BUILD31-43 rust/BUILD246-261 rust/defs.bzl23-63
Rust 实现的核心组件包括:
.proto 文件生成 Rust 代码。来源:rust/shared.rs1-113 rust/cpp.rs1-107 rust/upb.rs8-136 src/google/protobuf/compiler/rust/generator.cc136-271
Rust 实现的一个关键架构特性是其代理系统,它提供了一种安全有效地处理 Protocol Buffer 值的方法。
代理系统围绕“代理”类型这一概念构建。代理类型允许间接访问 Protocol Buffer 值,类似于 Rust 的引用,但具有 Protocol Buffer 操作所需的额外运行时信息。
来源:rust/proxied.rs8-47 rust/proxied.rs50-75 rust/proxied.rs80-93
代理系统提供两种主要方式与 Protocol Buffer 值进行交互:
View<T>):提供对 Protocol Buffer 值的只读访问。Mut<T>):提供对 Protocol Buffer 值的读写访问。这种方法允许高效且安全地访问 Protocol Buffer 值,同时保持与两种内核的兼容性。
来源:src/google/protobuf/compiler/rust/message.cc810-1113 rust/proxied.rs95-204 src/google/protobuf/compiler/rust/message.cc815-1106
每个 Protocol Buffer 消息由三个 Rust 类型表示:
Message):消息的所有者类型。MessageView):消息的借用的只读视图。MessageMut):消息的借用的可变视图。来源:src/google/protobuf/compiler/rust/message.cc30-207 src/google/protobuf/compiler/rust/message.cc299-374
消息支持以下关键操作:
| 操作 | 描述 |
|---|---|
| 创建 | 创建具有默认值的新消息。 |
| 序列化 | 将消息转换为线格式字节。 |
| 反序列化 | 将线格式字节解析到消息中。 |
| Clear | 清除消息中的所有字段。 |
| 复制/克隆 | 创建消息的深层副本。 |
| 合并 | 将字段从一个消息合并到另一个消息。 |
| 字段访问 | 获取和设置字段值。 |
来源:src/google/protobuf/compiler/rust/message.cc30-207 src/google/protobuf/compiler/rust/message.cc30-207
标量字段(整数、浮点数、布尔值)直接由其 Rust 等效项表示。
字符串和字节由 ProtoString 和 ProtoBytes 类型表示,它们是 Protocol Buffers 的所有者字符串和字节数组类型。
来源:rust/string.rs31-82 rust/string.rs101-217
重复字段由 Repeated<T> 类型表示,它提供了一个类型为 T 的值的集合。
来源:rust/repeated.rs23-113 rust/repeated.rs114-247 rust/repeated.rs307-356
Map 由 Map<K, V> 类型表示,它提供了一个从类型为 K 的键到类型为 V 的值的映射。
来源: rust/map.rs16-57 rust/map.rs63-77 rust/map.rs86-108
枚举由封装整数值的自定义 Rust 类型表示。
来源: src/google/protobuf/compiler/rust/enum.cc138-346
Rust 代码生成器集成到 Protocol Compiler (protoc) 中。它处理 .proto 文件并为消息、枚举和服务生成 Rust 代码。
来源: src/google/protobuf/compiler/rust/generator.cc136-271
Rust 实现通过 rust_proto_library 规则与 Bazel 构建系统集成,该规则根据构建配置选择合适的内核。
来源: rust/defs.bzl23-63 rust/defs.bzl144-163
两种内核之间的内存管理方式不同
这种差异通过通用 API 被抽象化了,但对于理解性能特征很重要。
来源: rust/cpp.rs346-396 rust/upb.rs76-140
两种内核都提供序列化和反序列化功能,但实现不同
来源: src/google/protobuf/compiler/rust/message.cc59-91 src/google/protobuf/compiler/rust/message.cc114-157
来源: rust/test/shared/serialization_test.rs16-52
来源: rust/test/shared/accessors_repeated_test.rs13-53
来源: rust/test/shared/accessors_map_test.rs16-41
Protocol Buffers 的 Rust 实现为 Rust 项目提供了安全、高效且符合惯用的 Protocol Buffers 使用方式。它支持两种不同的内核(C++ 和 upb),API 相同,使开发人员可以选择最适合其需求的实现。
该实现利用 Rust 的类型系统来提供安全高效的 API,同时保持与现有 Protocol Buffers 生态系统的兼容性。