use sqlx::{sqlite::Sqlite, SqliteConnection, Transaction}; use crate::login::{self, password::StoredHash, Login}; pub trait Provider { fn auth(&mut self) -> Auth; } impl<'c> Provider for Transaction<'c, Sqlite> { fn auth(&mut self) -> Auth { Auth(self) } } pub struct Auth<'t>(&'t mut SqliteConnection); impl<'t> Auth<'t> { // Retrieves a login by name, plus its stored password hash for // verification. If there's no login with the requested name, this will // return [None]. pub async fn for_name( &mut self, name: &str, ) -> Result, sqlx::Error> { let found = sqlx::query!( r#" select id as "id: login::Id", name, password_hash as "password_hash: StoredHash" from login where name = $1 "#, name, ) .map(|rec| { ( Login { id: rec.id, name: rec.name, }, rec.password_hash, ) }) .fetch_optional(&mut *self.0) .await?; Ok(found) } }