【问题标题】:How to export traits from a separate cargo workspace github repo如何从单独的货物工作区 github 存储库中导出特征
【发布时间】:2025-12-15 06:40:01
【问题描述】:

我对 rust 还很陌生,我正在尝试了解如何最好地创建可重用的共享库组件。我有一个名为 rust-libs 的 github 存储库,它被设置为货物工作区。此 repo 的项目树如下所示:

├── Cargo.lock
├── Cargo.toml
├── describable
│   ├── Cargo.toml
│   └── src
│       ├── describable.rs
│       └── lib.rs
└── health_check
    ├── Cargo.toml
    └── src
        ├── health_check.rs
        └── lib.rs

* Cargo.toml 文件包含:

[workspace]
members = [
    "describable",
    "health_check"
]

每个成员中的 Cargo.toml 文件只定义了该成员的依赖关系及其版本 - 例如可描述/Cargo.toml

[package]
name = "lib_describable"
version = "1.0.0"
authors = ["my-name <me@email.com>"]
edition = "2018"

[lib]
name = "lib_describable"
path = "src/lib.rs"

health_check/Cargo.toml

[package]
name = "lib_health_check"
version = "1.0.0"
authors = ["my-name <me@email.com>"]
edition = "2018"

[dependencies]
lib_describable = { path = "../describable" }

[lib]
name = "lib_health_check"
path = "src/lib.rs"

请注意,我使用 lib_ 前缀命名库,以避免与其他 rust 库发生任何冲突。

每个工作区成员中的 lib.rs 文件只定义了我要导出的公共模块 - 例如可描述/src/lib.rs

pub mod describable;

实现在 describable/src/describable.rs 中:

pub trait Describable {
  fn describe(&self) -> String;
}

health_check/src/health_check.rs中的实现是:

use lib_describable::describable::Describable;

pub trait HealthCheckable: Describable {
  fn check_health(&mut self) -> Result<(), String>;
}

对特定成员进行任何更改时,我总是在其 Cargo.toml 文件中更新其版本号。 CircleCI 用于自动构建这个 repo。如果构建成功,则 CircleCI 作业使用多个 git 标签(工作区中的每个成员一个)标记此 repo,这些标签的格式为 &lt;member-name&gt;_&lt;member-version-from-its-cargo-toml&gt;_&lt;git-short-commit-sha&gt;,例如对于上述两个成员,它可能会用这些标签标记构建:

describable_1.0.0_d2db9ff
health_check_1.0.0_d2db9ff

然后我有一个单独的 git 存储库,其中包含一个使用这些共享库成员构建的 rust 二进制文件。该项目在其 Config.toml 中引用共享库成员如下:

...
[dependencies]
...
lib_describable = { git = "ssh://git@github.com/xxx/rust-libs.git", tag = "describable_1.0.0_d2db9ff" }
lib_health_check = { git = "ssh://git@github.com/xxx/rust-libs.git", tag = "health_check_1.0.0_d2db9ff" }
...
[[bin]]
name = "my-app"
path = "src/bin/main.rs"

xxx 只是我的 github 帐户的混淆名称。该项目中的文件 src/bin/main.rs 包含以下形式的代码:

extern crate lib_describable;
extern crate lib_health_check;

use lib_describable::describable::Describable;
use lib_health_check::health_check::HealthCheckable;

pub trait MyDb: Describable + HealthCheckable {
  // some functions defined here that are not important for this issue
}

pub struct MySpecialDb { ... }

impl Describable for MySpecialDb {
  fn describe(&self) -> String {
    // returns a description of this DB
  }
}

impl HealthCheckable for MySpecialDb {
  fn check_health(&mut self) -> Result<(), String> {
    // performs some health check specific to this DB and returns either Ok(()) if its healthy or Err("...some error message...") if it is unhealthy
  }
}

impl MyDb for MySpecialDb { ... }

我发现的问题是 rust 编译器似乎不喜欢 impl HealthCheckable for MySpecialDb 行,并报告以下形式的错误:

the trait bound `...::MySpecialDb: lib_describable::describable::Describable` is not satisfied

the trait `lib_describable::describable::Describable` is not implemented for `...::MySpecialDb`

note: perhaps two different versions of crate `lib_describable` are being used?rustc(E0277)

有什么明显的地方我做错了导致这个错误吗?

【问题讨论】:

  • 我很确定 cargo 认为 lib_describable(git)lib_health_check(git) -&gt; lib_describable(path) 不同,您也许可以 override depenedencies 让它们对齐
  • @kmdreko 文档的那部分描述了如何在其他版本的 crate 中打补丁。我也无法让它与我的场景一起使用。如果您能详细说明如何解决此问题,将不胜感激。

标签: rust rust-cargo lib


【解决方案1】:

不幸的是,这似乎不是 Cargo 中受支持的配置,从我在这里提出的问题得到的回复中可以看出:https://github.com/rust-lang/cargo/issues/8956

因此,我已将我的 Cargo 工作区 repo 转换为 Cargo lib repo,我的所有库现在共享一个版本。

【讨论】:

    最近更新 更多