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

我在models.rs中有此功能。 >
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`
 


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

评论

寻求调试帮助的问题(“此代码为什么不起作用?”)必须包括所需的行为,特定的问题或错误以及在问题本身中再现该错误所需的最短代码。 —您的错误消息指向您未显示的代码,因此我们不太可能知道问题所在,因此我们不得不猜测,这会浪费您的时间和我们的时间。

#1 楼

普遍的问题是该代码具有多个版本的包装箱,每个版本提供了不同版本的特征。 Rust允许这样做的事实是一件好事,但它周围的错误消息令人困惑。这些特性不兼容,因此,当您将实现Serialize的类型传递给需要Serialize@A的函数时,编译器将停止运行。 -从板条箱导出。
Serialize@B(从Rust 1.44开始可用)对于验证您的问题非常有用。它显示了您的所有依赖关系及其版本。它甚至有一个cargo tree标志来显示重复的依赖项!该模式未在此处显示,但非常有用。
一般的解决方案是在Cargo.toml中手动限制您的Serde版本以匹配其余依赖项:
serde = "0.9"
serde_derive = "0.9"
serde_json = "0.9"

这可能并不总是可能的,在这种情况下,您可能需要束缚板条箱所有者以升级其依赖性。

工作示例
火箭
[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"]

rocket_contrib 0.2。 8取决于S​​erde 0.9,但您已拉入Serde 1.0。来自-d的这个摘要片段显示了问题:
 cargo tree 

即将发布的Rocket 0.3版应该允许使用Serde 1.0。 > Iron / Bson / MongoDB
bodyparser 0.5取决于Serde 0.8,MongoDB提升了0.9,但板条箱和BSON提升了Serde 1.0。来自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 (*) 的节选片段显示了问题:
 cargo tree 

Bodyparser 0.7.0应该支持Serde 1.0。 textnonce的状态不太清楚,但是该依赖关系可能是私有的,因此在这种情况下可能无关紧要。
柴油/计时
[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"

当前版本的Chrono是0.4.0,但是Diesel只知道如何序列化Chrono 0.3.0。
 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 (*)
 

blowfish /块密码特征
chrono = "0.4.0"
diesel = { version = "0.13.0", features = [ "chrono", "sqlite" ] }
diesel_codegen = { version = "0.13.0", features = [ "sqlite" ] }
dotenv = "0.9.0"

 reproduction v0.1.0 (file:///private/tmp/reproduction)
├── chrono v0.4.0
├── diesel v0.13.0
│   ├── chrono v0.3.0
 

连杆/活塞2d图形
[dependencies]
blowfish = "0.2.1"
block-cipher-trait = "0.3.0"

 reproduction v0.1.0 (file:///private/tmp/reproduction)
├── block-cipher-trait v0.3.0
│── blowfish v0.2.1
    ├── block-cipher-trait v0.2.0
 

actix /期货
[dependencies]
piston_window = "0.74.0"
conrod = { version = "0.56.0", features = ["piston"] }

 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 (*)
 

前途光明?
RFC 1977建议将公共和私有依赖项的概念引入Cargo。如果您使用的板条箱又公开显示其他板条箱的类型,则Cargo将确保您对具有普通类型的板条箱使用单个统一版本。

评论


这个答案很好,货树帮助我找到了问题。我阅读了引用的RFC 1977,但看不到如何解决该问题。就我而言,我很幸运,依赖项更改很小,因此我能够克隆冲突项目的github存储库,并用自己的fork更新依赖项。显然,这不是满足大多数情况的解决方案。由于此答案来自2017年,我想知道此问题的当前状况如何。

– palako
12月23日下午2:42

@palako答案的最后编辑时间是17天前;我关注热门话题。

– Shepmaster
12月23日下午2:56



@palako公共/私有依赖项将有所帮助,因为Cargo知道它能够在私有的板条箱集群中选择任意版本,但是可以确保将单个统一版本用于公共依赖项。

– Shepmaster
12月23日下午2:59

感谢Shepmaster。但是公共/私人将取决于板条箱作家,不是吗?如果我在代码中使用了两个库,而这些库又使用了相同依赖项的不同版本,并且存在此问题,那么我将无法解决它。

– palako
12月23日,下午3:06

@palako是的,可能需要板条箱作者才能使用它。但是,可以将其默认实现为public,在这种情况下,需要在所有依赖项之间统一版本。它还可以允许最终用户为未定义的板条箱定义公共/私有边界。对于您的示例,这完全取决于这些板条箱如何使用依赖项

– Shepmaster
12月23日下午3:11