我可以使用自己的序列化结构在 Rocket 中渲染模板吗?
Can I render a Template in Rocket with my own serialized struct?
我正在使用 Rocket 并且正在尝试创建一个 Layout
结构。我已经实现了 serde::Serialize
,因为文档说静态方法 Template::render
的第二个参数接受一个实现 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()
}
}
我收到错误
the trait `serde::ser::Serialize` is not implemented for `layout::Layout`
我做错了什么?
火箭的当前版本 v0.2.6
使用 serde = "^0.9"
而不是 serde 1.0。这意味着如果您在 Cargo.toml
中说类似 serde = "1"
的内容,cargo 将下载和 link 两个不同版本的 serde。这会导致错误消息。
此外,由于chrono
开发者的失误,chrono
3.1使用serde 1.0,而chrono
3.0使用serde 0.9。但是将依赖项更新到新的主要版本应该会导致板条箱本身出现主要版本冲突(相关:)。这会导致许多破损。为了解决这个问题,如果你想使用那个箱子,你需要在 Cargo.toml
中说 chrono = "=3.0"
。
顺便说一句,这正是 diesel 0.12 正在做的事情,它也使用 serde 0.9。 Diesel 0.13 使用的是 serde 1.0,所以它可以依赖 chrono = "^0.3.1"
。所以 Rocket 可能是最后一个需要过渡到 serde 1.0 的箱子。但这应该不会再花太长时间了。然后,一切都应该恢复正常。
啊哈,没有什么能比得上早上依赖地狱的味道了。
就像 Lukas 解释的那样,存在一些依赖性问题。 Rocket其实有upgraded to the newer Serde versions,但是没有把作为新版Rocket的改动推送到crates.io。因此我建议告诉 cargo 从 GitHub.
中拉出火箭及其相关的板条箱
下面提供了 Cargo.toml 的示例依赖项部分:
[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"
我正在使用 Rocket 并且正在尝试创建一个 Layout
结构。我已经实现了 serde::Serialize
,因为文档说静态方法 Template::render
的第二个参数接受一个实现 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()
}
}
我收到错误
the trait `serde::ser::Serialize` is not implemented for `layout::Layout`
我做错了什么?
火箭的当前版本 v0.2.6
使用 serde = "^0.9"
而不是 serde 1.0。这意味着如果您在 Cargo.toml
中说类似 serde = "1"
的内容,cargo 将下载和 link 两个不同版本的 serde。这会导致错误消息。
此外,由于chrono
开发者的失误,chrono
3.1使用serde 1.0,而chrono
3.0使用serde 0.9。但是将依赖项更新到新的主要版本应该会导致板条箱本身出现主要版本冲突(相关:Cargo.toml
中说 chrono = "=3.0"
。
顺便说一句,这正是 diesel 0.12 正在做的事情,它也使用 serde 0.9。 Diesel 0.13 使用的是 serde 1.0,所以它可以依赖 chrono = "^0.3.1"
。所以 Rocket 可能是最后一个需要过渡到 serde 1.0 的箱子。但这应该不会再花太长时间了。然后,一切都应该恢复正常。
啊哈,没有什么能比得上早上依赖地狱的味道了。
就像 Lukas 解释的那样,存在一些依赖性问题。 Rocket其实有upgraded to the newer Serde versions,但是没有把作为新版Rocket的改动推送到crates.io。因此我建议告诉 cargo 从 GitHub.
中拉出火箭及其相关的板条箱下面提供了 Cargo.toml 的示例依赖项部分:
[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"