为什么没有实现明确实现它的类型的特征?

hah*_*ute 9 rust serde

我正在尝试使用Diesel查询MySQL数据库并使用带有Rocket的Handlebars模板显示结果.

我在models.rs中有这个

#[derive(Queryable, Serialize)]
pub struct Post {
    pub id: i32,
    pub title: String,
    pub text: String,
    pub published: bool,
}
Run Code Online (Sandbox Code Playgroud)

cargo run 输出:

  --> src/main.rs:69:5
   |
69 |     Template::render("index", &results)
   |     ^^^^^^^^^^^^^^^^ the trait `serde::ser::Serialize` is not implemented for `tasty::models::Post`
   |
   = note: required because of the requirements on the impl of `serde::ser::Serialize` for `std::vec::Vec<tasty::models::Post>`
   = note: required by `rocket_contrib::Template::render`
Run Code Online (Sandbox Code Playgroud)

在我的Cargo.toml中,我有这个:

[dependencies]
chrono = "0.3.0"
rocket = "0.2.8"
rocket_codegen = "0.2.8"
serde = "1.0.8"
serde_derive = "1.0.8"
serde_json = "1.0.2"
mysql = "11.1.2"
diesel = { version = "0.13.0", features = ["mysql","chrono"] }
diesel_codegen = { version = "0.13.0", features = ["mysql"] }
dotenv = "0.10.0"

[dependencies.rocket_contrib]
version = "*"
default-features = false
features = ["handlebars_templates"]
Run Code Online (Sandbox Code Playgroud)

我已经读到Diesel目前不支持Serialize,但我不确定.

She*_*ter 20

一般问题是代码具有多个版本的包,每个版本提供不同版本的特征.Rust允许这样做的事实是一件好事,但它周围的错误消息令人困惑.

你的箱子实现了Serialize从版本A,但该库是使用B版在公共接口.这些特性不兼容,因此当您将类型实现传递Serialize@A给需要的函数时Serialize@B,编译器会阻止您.

虽然您的示例是关于不同的特征,但对于已从箱子中重新导出的类型,也可能出现这种情况.

货物树非常有用,可以验证这是您的问题.它显示了所有依赖项及其版本.它甚至有一个-d标志来显示重复的依赖项!此模式未在此处显示,但非常有用.

一般的解决方案是手动限制Cargo.toml中的Serde版本以匹配其余的依赖项:

serde = "0.9"
serde_derive = "0.9"
serde_json = "0.9"
Run Code Online (Sandbox Code Playgroud)

这可能并不总是可能的,在这种情况下,您可能需要追捕包装箱所有者来升级其依赖关系.


工作的例子

火箭

[dependencies]
chrono = "0.3.0"
rocket = "0.2.8"
rocket_codegen = "0.2.8"
serde = "1.0.8"
serde_derive = "1.0.8"
serde_json = "1.0.2"
mysql = "11.1.2"
diesel = { version = "0.13.0", features = ["mysql","chrono"] }
diesel_codegen = { version = "0.13.0", features = ["mysql"] }
dotenv = "0.10.0"

[dependencies.rocket_contrib]
version = "*"
default-features = false
features = ["handlebars_templates"]
Run Code Online (Sandbox Code Playgroud)

rocket_contrib 0.2.8取决于S​​erde 0.9,但是你已经进入了Serde 1.0.这个简略的片段cargo tree显示了问题:

reproduction v0.1.0 (file:///private/tmp/reproduction)
??? rocket_contrib v0.2.8
?   ??? handlebars v0.25.3
?   ?   ??? serde_json v0.9.10
?   ?       ??? serde v0.9.15
?   ??? serde v0.9.15 (*)
?   ??? serde_json v0.9.10 (*)
??? serde v1.0.8 (*)
??? serde_derive v1.0.8
?   ??? serde_derive_internals v0.15.1
??? serde_json v1.0.2 (*)
Run Code Online (Sandbox Code Playgroud)

即将推出的0.3版火箭应该允许使用SERDE 1.0.

Iron/Bson/MongoDB

[dependencies]
bodyparser = "0.5"
bson = "0.8"
iron = "0.5"
jwt = "0.4"
mongodb = "0.3"
router = "0.5"
rust-crypto = "0.2"
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
time = "0.1"
Run Code Online (Sandbox Code Playgroud)

bodyparser 0.5取决于Serde 0.8,MongoDB已经进入0.9,但是板条箱和BSON已经拉入Serde 1.0.这个简略的片段cargo tree显示了问题:

reproduction v0.1.0 (file:///private/tmp/reproduction)
??? bodyparser v0.5.0
?   ??? serde v0.8.23
?   ??? serde_json v0.8.6
?       ??? serde v0.8.23 (*)
??? bson v0.8.0
?   ??? serde v1.0.8
?   ??? serde_json v1.0.2
?   ?   ??? serde v1.0.8 (*)
??? mongodb v0.3.0
?   ??? textnonce v0.6.0
?   ?   ??? serde v0.9.15
?   ?   ??? serde_derive v0.9.15
??? serde v1.0.8 (*)
??? serde_derive v1.0.8
??? serde_json v1.0.2 (*)
Run Code Online (Sandbox Code Playgroud)

Bodyparser 0.7.0应该支持Serde 1.0.textnonce状态不太清楚,但是依赖可能是私有的,所以在这种情况下可能无关紧要.

柴油/计时码表

chrono = "0.4.0"
diesel = { version = "0.13.0", features = [ "chrono", "sqlite" ] }
diesel_codegen = { version = "0.13.0", features = [ "sqlite" ] }
dotenv = "0.9.0"
Run Code Online (Sandbox Code Playgroud)

当前版本的Chrono是0.4.0,但Diesel只知道如何序列化Chrono 0.3.0.

reproduction v0.1.0 (file:///private/tmp/reproduction)
??? chrono v0.4.0
??? diesel v0.13.0
?   ??? chrono v0.3.0
Run Code Online (Sandbox Code Playgroud)

blowfish/block-cipher-trait

[dependencies]
blowfish = "0.2.1"
block-cipher-trait = "0.3.0"
Run Code Online (Sandbox Code Playgroud)
reproduction v0.1.0 (file:///private/tmp/reproduction)
??? block-cipher-trait v0.3.0
??? blowfish v0.2.1
    ??? block-cipher-trait v0.2.0
Run Code Online (Sandbox Code Playgroud)

conrod/piston2d-graphics

[dependencies]
piston_window = "0.74.0"
conrod = { version = "0.56.0", features = ["piston"] }
Run Code Online (Sandbox Code Playgroud)
repro v0.1.0 (file:///private/tmp/repro)
??? conrod v0.56.0
?   ??? piston2d-graphics v0.23.0
??? piston_window v0.74.0
    ??? piston2d-graphics v0.24.0 (*)
Run Code Online (Sandbox Code Playgroud)

actix /期货

[dependencies]
actix-web = "0.6.10"
futures = "0.2.1"
Run Code Online (Sandbox Code Playgroud)
repro v0.1.0 (file:///private/tmp/repro)
??? actix-web v0.6.12
?   ??? actix v0.5.8
?   ?   ??? futures v0.1.21
??? futures v0.2.1
Run Code Online (Sandbox Code Playgroud)

美好的未来?

RFC 1977建议向Cargo 引入公共私有依赖的概念.如果您使用的箱子反过来公开暴露另一个箱子的类型,Cargo将确保您使用单一统一版本的箱子与常见类型.

  • 请注意,您必须首先安装它:`cargo install cargo-tree`(`cmake`是构建工作所必需的)。 (2认同)