如何从仅返回1或0条记录的Diesel查询中获取Option <T>而不是Option <Vec <T >>?

dch*_*dch 4 rust rust-diesel

我在查询称为表的现有记录messages;然后,此查询将用作“查找或创建”功能的一部分:

fn find_msg_by_uuid<'a>(conn: &PgConnection, msg_uuid: &Uuid) -> Option<Vec<Message>> {
    use schema::messages::dsl::*;
    use diesel::OptionalExtension;

    messages.filter(uuid.eq(msg_uuid))
        .limit(1)
        .load::<Message>(conn)
        .optional().unwrap()
}
Run Code Online (Sandbox Code Playgroud)

我已经将此设置为可选,因为在这种情况下查找记录和查找都不是有效的结果,因此,此查询可能返回Vec带有一个Message或空值的a Vec,因此我总是最终检查as 是否Vec为空或不使用像这样的代码:

let extant_messages = find_msg_by_uuid(conn, message_uuid);

if !extant_messages.unwrap().is_empty() { ... }
Run Code Online (Sandbox Code Playgroud)

然后如果它不是空的Message,则Vec使用如下代码将第一个作为我找到的消息

let found_message = find_msg_by_uuid(conn, message_uuid).unwrap()[0];
Run Code Online (Sandbox Code Playgroud)

Vec由于记录是唯一的,因此我总是采用第一个元素,因此查询将仅返回1或0条记录。

这种感觉那种凌乱的我,似乎采取步骤太多,我觉得如果有一个查询记录,那么它应该返回Option<Message>不能Option<Vec<Message>>或者None如果没有记录匹配查询。

She*_*ter 5

如评论中所述,使用first

尝试加载单个记录。Ok(record)如果找到Err(NotFound)则返回,并且不返回任何结果。如果查询确实是可选的,则可以调用此查询.optional()的结果以获取Result<Option<U>>

fn find_msg_by_uuid<'a>(conn: &PgConnection, msg_uuid: &Uuid) -> Option<Message> {
    use schema::messages::dsl::*;
    use diesel::OptionalExtension;

    messages
        .filter(uuid.eq(msg_uuid))
        .first(conn)
        .optional()
        .unwrap()
}
Run Code Online (Sandbox Code Playgroud)