You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust项目中neoeinstein-prost生成protobuf代码的规范存放与引用咨询

Rust项目中Protobuf生成代码的惯用存放与引用方案

我在Rust项目中使用neoeinstein-prost buf插件生成protobuf代码,插件本身符合需求,但不确定生成的.rs文件的惯用存放位置、引用方式,以及这种场景是否需要用到工作区(当前项目未使用工作区)。我自己有两个备选方案,想知道是否符合惯例:

我的两个备选方案

方案1

优点:生成代码与手写代码物理分离,边界清晰;缺点:需要使用跨目录的#[path]指令,路径写法繁琐。

- examples (依赖lib)
- gen
  |- src
  |  |- my_model.v1.rs
  |  |- my_model.v1.serde.rs (被my_model.v1.rs通过!include引入)
- proto
  |- my_model
  |  |- v1
  |  |  |- my_model.proto
- src
  |- main.rs (依赖lib)
  |- lib
  |  |- lib.rs (通过#[path = "../../gen/src/my_model.v1.rs"]导出"model"模块)

方案2

优点:所有库代码(手写/生成)都在src目录下,封装统一;缺点:生成代码位置不直观,查找麻烦。

- examples (依赖lib)
- proto
  |- my_model
  |  |- v1
  |  |  |- my_model.proto
- src
  |- main.rs (依赖lib)
  |- lib
  |  |- lib.rs (通过#[path = "gen/src/my_model.v1.rs"]导出"model"模块)
  |  |- gen
  |  |  |- src (多余层级?)
  |  |  |  |- my_model.v1.rs
  |  |  |  |- my_model.v1.serde.rs (被my_model.v1.rs通过!include引入)

惯用方案与建议

1. 存放位置的惯例

Rust社区最常用的做法是将生成代码放在项目根目录的独立目录下,比如gen、proto-gen或prost-gen,和src、proto同级。这种方式的核心是把自动生成代码与手写代码物理隔离,避免生成文件污染手写源码目录,同时方便用.gitignore直接忽略整个生成目录(仅需添加/gen/)。

不推荐方案2的做法——把生成代码放在src内部,因为自动生成的代码会被插件频繁覆盖,和手写代码混放容易误操作,也不符合“源码目录只放人工维护代码”的惯例。

2. 引用方式的优化

你当前用#[path]硬编码路径的方式不够优雅,更规范的做法是把生成代码做成本地依赖的子crate:

  1. 在gen目录下创建Cargo.toml,配置为lib crate:
[package]
name = "my-model-v1"
version = "0.1.0"
edition = "2021"

[dependencies]
prost = "0.12"
prost-types = "0.12"
serde = { version = "1.0", features = ["derive"] }
# 添加其他需要的依赖
  1. 主项目的Cargo.toml中添加这个本地依赖:
[dependencies]
my-model-v1 = { path = "./gen" }
  1. 在主库的lib.rs中直接引入并导出:
pub use my_model_v1::*;

这种方式完全不需要#[path],引用逻辑和普通第三方依赖一致,更符合Rust模块系统的惯例。

3. 是否需要工作区?

如果你的项目规模不大,目前完全不需要工作区。工作区主要用于拆分多个关联crate的大型项目,当前仅需处理生成代码的场景,用本地依赖子crate的方式就足够简洁。如果后续项目拆分出多个独立模块,再考虑引入工作区统一管理即可。


内容的提问来源于stack exchange,提问作者Goldie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 16:24:54