diff --git a/bank_client/src/lib.rs b/bank_client/src/lib.rs index d8876fa..a1c81a0 100644 --- a/bank_client/src/lib.rs +++ b/bank_client/src/lib.rs @@ -2,8 +2,9 @@ use std::sync::Arc; use async_lock::RwLock; use bank_core::{ - ApiError, TokenResponse, - account::{AccountInfo, UserAccountInfo}, + ApiError, NameOrUuid, TokenResponse, + account::{Account, UserAccountInfo}, + chat::{Chat, ChatInfo, ChatMessage, SendMessage, StartChat}, pagination::{Pagination, RequestPagination}, transaction::{Direction, Transaction}, user::{User, UserAccounts, UserBalance}, @@ -134,6 +135,11 @@ impl ApiClient { pub const fn accounts(&self) -> AccountsApi { AccountsApi { api: self } } + + #[inline] + pub const fn chats(&self) -> ChatsApi { + ChatsApi { api: self } + } } pub async fn handle_response( @@ -223,11 +229,7 @@ pub struct AccountsApi<'a> { } impl AccountsApi<'_> { - pub async fn list( - &self, - limit: u64, - offset: u64, - ) -> Result, ClientError> { + pub async fn list(&self, limit: u64, offset: u64) -> Result, ClientError> { let response = request!( self.api, get, @@ -262,6 +264,98 @@ impl AccountsApi<'_> { } } +pub struct ChatsApi<'a> { + api: &'a ApiClient, +} + +impl ChatsApi<'_> { + pub async fn list(&self, limit: u64, offset: u64) -> Result, ClientError> { + let response = request!( + self.api, + get, + RequestUrl::simple(["api", "chats"], limit, offset) + ) + .send() + .await?; + let body = handle_response(response).await?; + Ok(body) + } + + pub async fn start(&self, user: impl Into) -> Result { + let response = request!(self.api, get, "/api/chats") + .json(&StartChat { user: user.into() }) + .send() + .await?; + let body = handle_response(response).await?; + Ok(body) + } + + pub async fn info(&self, id: Uuid) -> Result { + let response = request!(self.api, get, ["api", "chats", &id.to_string()]) + .send() + .await?; + let body = handle_response(response).await?; + Ok(body) + } + + pub async fn messages( + &self, + chat: Uuid, + limit: u64, + offset: u64, + ) -> Result, ClientError> { + let response = request!( + self.api, + get, + RequestUrl::simple(["api", "chats", &chat.to_string()], limit, offset) + ) + .send() + .await?; + let body = handle_response(response).await?; + Ok(body) + } + + pub async fn send( + &self, + chat: Uuid, + message: &SendMessage, + ) -> Result, ClientError> { + let response = request!( + self.api, + get, + ["api", "chats", &chat.to_string(), "messages"] + ) + .json(message) + .send() + .await?; + let body = handle_response(response).await?; + Ok(body) + } + + pub async fn mark_read( + &self, + chat: Uuid, + message: Uuid, + ) -> Result, ClientError> { + let response = request!( + self.api, + get, + [ + "api", + "chats", + &chat.to_string(), + "messages", + &message.to_string(), + "read" + ] + ) + .send() + .await?; + let body = handle_response(response).await?; + Ok(body) + } +} + trait RequestBuilderExt { async fn auth(self, api: &ApiClient) -> Self; } @@ -288,6 +382,12 @@ impl<'a> MakeUrl for &'a [&'a str] { Ok(base) } } +impl<'a, const N: usize> MakeUrl for [&'a str; N] { + fn make_url(self, mut base: Url) -> Result { + base.path_segments_mut().unwrap().extend(self); + Ok(base) + } +} impl<'a, P, S, Q, K, V> MakeUrl for (P, Q) where diff --git a/bank_core/src/util.rs b/bank_core/src/util.rs index 801c9b8..ed35bab 100644 --- a/bank_core/src/util.rs +++ b/bank_core/src/util.rs @@ -67,6 +67,18 @@ pub enum NameOrUuid { Name(#[garde(dive)] Name), } +impl From for NameOrUuid { + fn from(value: Name) -> Self { + Self::Name(value) + } +} + +impl From for NameOrUuid { + fn from(value: Uuid) -> Self { + Self::Id(value) + } +} + #[derive(Debug, Clone, Deserialize, Serialize, Validate, PartialEq, Eq)] #[cfg_attr(feature = "schemas", derive(schemars::JsonSchema))] pub struct ChangePassword {