rust 尝试在Cloudflare工作进程中使用serde进行零拷贝重复化时出错

cl25kdpy  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(89)

我有一个包含&str的结构体,其生命周期注解与结构体本身相同。当我试图在worker::d1::D1PreparedStatement上调用first::<T>(None)方法时,该方法应该查询我的数据库并将值解析为T类型,我得到“'Aprixialize'的实现不够通用”。
下面是我的一些代码:

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字段和处理它的模块,但没有改变任何东西。

qeeaahzv

qeeaahzv1#

问题是在这种情况下你不能做零拷贝的镜像化。workers::d1::D1PreparedStatement::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的实现方式),因此“可以在不从验证器借用任何数据的情况下进行验证”。
您必须从您的结构中删除借用才能在此上下文中使用它,可能是通过将&'a str字段替换为拥有的String s。

相关问题