提问人:Lu_ 提问时间:10/27/2023 最后编辑:John KugelmanLu_ 更新时间:11/3/2023 访问量:68
尝试在 Cloudflare Workers 中使用 serde 进行零复制反序列化时出错
Error trying to zero-copy deserialize using serde in Cloudflare workers
问:
我有一个结构,其中包含与结构本身具有相同生存期注释的结构。当我尝试调用该方法时,该方法应该查询我的数据库并将值解析为类型,我得到“'反序列化'的实现不够通用”。&str
first::<T>(None)
worker::d1::D1PreparedStatement
T
这是我的一些代码:
use worker::;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct User<'a> {
#[serde(with = "uuid_as_string")]
uuid: Uuid,
name: &'a str,
display_name: &'a str,
profile_text: &'a str,
profile_picture_url: &'a str,
email_address: &'a str,
password: &'a str,
created: usize,
deleted: usize,
timezone: isize,
}
mod uuid_as_string {
use serde::{self, Deserialize, Deserializer, Serializer};
use uuid::Uuid;
pub fn serialize<S>(uuid: &Uuid, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&uuid.to_string())
}
pub fn deserialize<'a, D>(deserializer: D) -> Result<Uuid, D::Error>
where
D: Deserializer<'a>,
{
let s = String::deserialize(deserializer)?;
Uuid::parse_str(&s).map_err(serde::de::Error::custom)
}
}
#[event(fetch, respond_with_errors)]
pub async fn main(request: Request, env: Env, _ctx: Context) -> Result<Response> {
Router::new()
.getasync("/", |, ctx| async move {
let d1 = ctx.env.d1("D1_DATABASE")?;
let statement = d1.prepare("SELECT FROM users");
match statement.first::<User>(None).await? {
Some(user) => Response::from_json(&user),
None => Response::error("Not found", 404),
}
})
.run(request, env)
.await
}
我尝试完全删除字段和用于处理它的模块,但它没有改变任何东西。Uuid
答:
1赞
Anders Evensen
11/3/2023
#1
问题是在这种情况下,您不能进行零拷贝反序列化。workers::d 1::D 1PreparedStatement::first()
的签名如下:
pub async fn first<T>(&self, col_name: Option<&str>) -> Result<Option<T>>
where
T: for<'a> Deserialize<'a>,
{
// ...
}
这意味着必须拥有反序列化(请注意,这正是实现方式),因此“可以在不从反序列化程序中借用任何数据的情况下进行反序列化”。where T: for<'a> Deserialize<'a>
DeserializeOwned
您必须从结构中删除借用才能在此上下文中使用它,也许可以通过将字段替换为 owned s。&'a str
String
评论
cargo check
工人
板条箱吗?worker
uuid
serde
uuid_as_string