Как экспортировать черты из отдельного репозитория github в грузовой рабочей области

#rust #rust-cargo #lib

#Ржавчина #rust-cargo #библиотека

Вопрос:

Я довольно новичок в rust и пытаюсь понять, как лучше всего создавать повторно используемые компоненты разделяемой библиотеки. У меня есть репозиторий github с именем rust-libs, который настроен как грузовое рабочее пространство. Дерево проекта для этого репозитория выглядит следующим образом:

 ├── 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 в каждом элементе просто определяет зависимости этого элемента и его версию — например, describable/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.

The lib.rs файл в каждом элементе рабочей области просто определяет общедоступные модули, которые я хочу экспортировать — например, describable/src/lib.rs:

 pub mod describable;
 

Реализация для этого находится в describable/src/describable.rs:

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

Реализация в health_check/ src /health_check.rs:

 use lib_describable::describable::Describable;

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

При внесении каких-либо изменений в конкретный элемент я всегда обновляю его номер версии в файле Cargo.toml. CircleCI используется для автоматического создания этого репозитория. Если сборка прошла успешно, задание CircleCI помечает это репозиторий несколькими тегами git (по одному на каждого участника в рабочей области), и эти теги имеют вид <member-name>_<member-version-from-its-cargo-toml>_<git-short-commit-sha> , например, для двух вышеупомянутых участников он может пометить сборку этими тегами:

 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(amp;self) -> String {
    // returns a description of this DB
  }
}

impl HealthCheckable for MySpecialDb {
  fn check_health(amp;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, похоже, не нравится строка implementcheckable для 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)
 

Есть ли что-то очевидное, что я делаю неправильно, чтобы вызвать эту ошибку?

Комментарии:

1. Я почти уверен, что cargo думает lib_describable(git) иначе, чем lib_health_check(git) -> lib_describable(path) , возможно, вы сможете переопределить зависимости, чтобы привести их в соответствие

2. @kmdreko В этом разделе документации описывается, как вносить исправления в другие версии ящика. Я тоже не мог заставить это сработать в моем сценарии. Был бы очень признателен, если бы вы могли, пожалуйста, набросать, как это исправить.

Ответ №1:

К сожалению, похоже, что это не поддерживаемая конфигурация в Cargo, как видно из ответов, которые я получил по вопросу, который я поднял здесь: https://github.com/rust-lang/cargo/issues/8956

Поэтому я преобразовал свое репозиторий рабочей области в репозиторий грузовой библиотеки, где все мои библиотеки теперь имеют одну версию.