use async_trait::async_trait; use crate::client::client_auth_api::ClientAuth; use crate::client::opaque::{ServerConnectionLogin, ServerConnectionRegister}; use crate::shared::models::app::AuthAPI; use crate::shared::email::Email; use crate::shared::opaque::UserSecretKey; use crate::shared::user_api::UserAPI; //https://chatgpt.com/c/69441737-c990-8333-9737-7ac75232da1d struct ClientApp<'a, R, U, C> where R: ServerConnectionRegister + ServerConnectionLogin, U: UserAPI, C: ClientRepo { auth_api: ClientAuth<'a, R, U>, client_repo: C, } impl <'a, R, U, C>ClientApp<'a, R, U, C> where R: ServerConnectionRegister + ServerConnectionLogin, U: UserAPI, C: ClientRepo { fn new(auth_api: ClientAuth<'a, R, U>, client_repo: C) -> Self { Self { auth_api, client_repo } } async fn new_user(&self, email: Email) -> Result { let secret_key = UserSecretKey::new(); self.client_repo.add_secret_key(email.clone(), secret_key.clone()).await?; if let Err(_) = self.auth_api.register_key(&email, &secret_key).await { self.client_repo.remove_secret_key(&email).await.expect("couldn't delete"); } Ok(secret_key) } } #[async_trait] trait ClientRepo { async fn add_secret_key(&self, email: Email, user_secret_key: UserSecretKey) -> Result<(), String>; async fn remove_secret_key(&self, email: &Email) -> Result<(), String>; }