I'm trying to use Diesel to query a MySQL database and display the results with a Handlebars template with Rocket.
I have this in models.rs
#[derive(Queryable, Serialize)]
pub struct Post {
pub id: i32,
pub title: String,
pub text: String,
pub published: bool,
}
cargo run
outputs this:
--> 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`
In my Cargo.toml, I have this:
[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"]
I have read that Diesel does not support Serialize
at the moment, but I am not sure.
The general problem is that the code has multiple versions of the crate, each providing a different version of the traits. The fact that Rust allows this is a good thing, but the error messages around it are confusing.
Your crate implements
Serialize
from version A but the library is using version B in a public interface. These traits are not compatible, so when you pass your type implementingSerialize@A
to the function requiringSerialize@B
, the compiler stops you.While your example is about different traits, it's also possible for this to occur for types which have been re-exported from a crate.
cargo tree is highly useful to verify this is your problem. It shows all of your dependencies and their versions. It even has a
-d
flag to show duplicate dependencies! That mode isn't shown here, but is highly useful.The general solution is to manually restrict your version of Serde in your Cargo.toml to match the rest of the dependencies:
This may not always be possible, in which case you may need to hound the crate owners to upgrade their dependencies.
Worked examples
Rocket
rocket_contrib 0.2.8 depends on Serde 0.9, but you have pulled in Serde 1.0. This abridged snippet from
cargo tree
shows the problem:The upcoming version 0.3 of Rocket should allow using Serde 1.0.
Iron / Bson / MongoDB
bodyparser 0.5 depends on Serde 0.8, MongoDB has pulled in 0.9, but the crate and BSON have pulled in Serde 1.0. This abridged snippet from
cargo tree
shows the problem:Bodyparser 0.7.0 should support Serde 1.0. The state of textnonce is less clear, but that dependency might be a private one, so it might not matter in this case.
Diesel / Chrono
The current version of Chrono is 0.4.0, but Diesel only knows how to serialize Chrono 0.3.0.
blowfish / block-cipher-trait
conrod / piston2d-graphics
actix / futures
A bright future?
RFC 1977 proposes to introduce the notion of public and private dependencies to Cargo. If you use a crate that in turn publicly exposes another crate's types, Cargo would ensure that you use a single unified version for the crate with the common types.