diff options
Diffstat (limited to 'src/user/app.rs')
| -rw-r--r-- | src/user/app.rs | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/src/user/app.rs b/src/user/app.rs new file mode 100644 index 0000000..2ab356f --- /dev/null +++ b/src/user/app.rs @@ -0,0 +1,56 @@ +use sqlx::sqlite::SqlitePool; + +use super::{ + Password, User, + create::{self, Create}, +}; +use crate::{clock::DateTime, event::Broadcaster, name::Name}; + +pub struct Users<'a> { + db: &'a SqlitePool, + events: &'a Broadcaster, +} + +impl<'a> Users<'a> { + pub const fn new(db: &'a SqlitePool, events: &'a Broadcaster) -> Self { + Self { db, events } + } + + pub async fn create( + &self, + name: &Name, + password: &Password, + created_at: &DateTime, + ) -> Result<User, CreateError> { + let create = Create::begin(name, password, created_at); + let validated = create.validate()?; + + let mut tx = self.db.begin().await?; + let stored = validated.store(&mut tx).await?; + tx.commit().await?; + + let user = stored.publish(self.events); + + Ok(user.as_created()) + } +} + +#[derive(Debug, thiserror::Error)] +pub enum CreateError { + #[error("invalid user name: {0}")] + InvalidName(Name), + #[error(transparent)] + PasswordHash(#[from] password_hash::Error), + #[error(transparent)] + Database(#[from] sqlx::Error), +} + +#[cfg(test)] +impl From<create::Error> for CreateError { + fn from(error: create::Error) -> Self { + match error { + create::Error::InvalidName(name) => Self::InvalidName(name), + create::Error::PasswordHash(error) => Self::PasswordHash(error), + } + } +} |
