Alexsandr Startsev
Alexsandr Startsev

Reputation: 123

Can I render a Template in Rocket with my own serialized struct?

I'm using Rocket and I'm trying to create a Layout struct. I've implemented serde::Serialize, because the documentation says the static method Template::render's second argument accepts a struct that implements Serialize:

struct Layout {
    data: String,
    second: String,
}

impl Layout {
    fn new(data: String, second: String) -> Layout {
        Layout { data, second }
    }

    fn render(&self) -> Template {
        Template::render("Layout", &self)
    }
}

impl Serialize for Layout {
    fn serialize<S>(&self, serialize: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        let mut state = serializer.serialize_struct("Layout", 2);
        state.serialize_field("data", &self.data)?;
        state.serialize_field("second", &self.data)?;
        state.end()
    }
}

I get the error

the trait `serde::ser::Serialize` is not implemented for `layout::Layout`

What did I do wrong?

Upvotes: 2

Views: 377

Answers (2)

manonthemat
manonthemat

Reputation: 6251

Just like Lukas explained, there are some dependency issues. Rocket actually has upgraded to the newer Serde versions, but didn't push the changes as a new version of Rocket to crates.io. Therefore I recommend to tell cargo to pull rocket and its related crates from GitHub.

An example dependencies section of the Cargo.toml is provided below:

[dependencies]
chrono = "0.3.1"
rocket = { git = "https://github.com/SergioBenitez/Rocket" }
rocket_codegen = { git = "https://github.com/SergioBenitez/Rocket" }
rocket_contrib = { git = "https://github.com/SergioBenitez/Rocket" }
serde = "1.0.2"
serde_json = "1.0.1"
serde_derive = "1.0.2"

Upvotes: 1

Lukas Kalbertodt
Lukas Kalbertodt

Reputation: 88946

The current version of rocket, v0.2.6, uses serde = "^0.9" and not serde 1.0 yet. This means that if you're saying something like serde = "1" in your Cargo.toml, cargo will download and link two different versions of serde. This leads to the error message.

Furthermore, due to a mistake by the chrono developers, chrono 3.1 uses serde 1.0, while chrono 3.0 uses serde 0.9. But updating a dependency to a new major version should lead to a major version bump in the crate itself (related: What exactly is considered a breaking change to a library crate?). This lead to many breakages. In order to cope with that, you need to say chrono = "=3.0" in your Cargo.toml if you want to use that crate.

This, by the way, is exactly what diesel 0.12 is doing, which is using serde 0.9 as well. Diesel 0.13 is using serde 1.0, so it can depend on chrono = "^0.3.1". So Rocket is probably the last crate which needs to do the transition to serde 1.0. But this shouldn't take too long anymore. Then, everything should be in order again.

Ahhh, nothing beats the smell of dependency hell in the morning.

Upvotes: 3

Related Questions