implement chat api in client

This commit is contained in:
DSeeLP 2025-04-17 12:25:01 +02:00
parent 0c0828e3c8
commit 609f2bd001
2 changed files with 119 additions and 7 deletions

View File

@ -2,8 +2,9 @@ use std::sync::Arc;
use async_lock::RwLock; use async_lock::RwLock;
use bank_core::{ use bank_core::{
ApiError, TokenResponse, ApiError, NameOrUuid, TokenResponse,
account::{AccountInfo, UserAccountInfo}, account::{Account, UserAccountInfo},
chat::{Chat, ChatInfo, ChatMessage, SendMessage, StartChat},
pagination::{Pagination, RequestPagination}, pagination::{Pagination, RequestPagination},
transaction::{Direction, Transaction}, transaction::{Direction, Transaction},
user::{User, UserAccounts, UserBalance}, user::{User, UserAccounts, UserBalance},
@ -134,6 +135,11 @@ impl ApiClient {
pub const fn accounts(&self) -> AccountsApi { pub const fn accounts(&self) -> AccountsApi {
AccountsApi { api: self } AccountsApi { api: self }
} }
#[inline]
pub const fn chats(&self) -> ChatsApi {
ChatsApi { api: self }
}
} }
pub async fn handle_response<T: DeserializeOwned>( pub async fn handle_response<T: DeserializeOwned>(
@ -223,11 +229,7 @@ pub struct AccountsApi<'a> {
} }
impl AccountsApi<'_> { impl AccountsApi<'_> {
pub async fn list( pub async fn list(&self, limit: u64, offset: u64) -> Result<Pagination<Account>, ClientError> {
&self,
limit: u64,
offset: u64,
) -> Result<Pagination<AccountInfo>, ClientError> {
let response = request!( let response = request!(
self.api, self.api,
get, 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<Pagination<ChatInfo>, 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<NameOrUuid>) -> Result<Chat, ClientError> {
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<ChatInfo, ClientError> {
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<Pagination<ChatMessage>, 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<Pagination<ChatMessage>, 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<Pagination<ChatMessage>, 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 { trait RequestBuilderExt {
async fn auth(self, api: &ApiClient) -> Self; async fn auth(self, api: &ApiClient) -> Self;
} }
@ -288,6 +382,12 @@ impl<'a> MakeUrl for &'a [&'a str] {
Ok(base) Ok(base)
} }
} }
impl<'a, const N: usize> MakeUrl for [&'a str; N] {
fn make_url(self, mut base: Url) -> Result<Url, url::ParseError> {
base.path_segments_mut().unwrap().extend(self);
Ok(base)
}
}
impl<'a, P, S, Q, K, V> MakeUrl for (P, Q) impl<'a, P, S, Q, K, V> MakeUrl for (P, Q)
where where

View File

@ -67,6 +67,18 @@ pub enum NameOrUuid {
Name(#[garde(dive)] Name), Name(#[garde(dive)] Name),
} }
impl From<Name> for NameOrUuid {
fn from(value: Name) -> Self {
Self::Name(value)
}
}
impl From<Uuid> for NameOrUuid {
fn from(value: Uuid) -> Self {
Self::Id(value)
}
}
#[derive(Debug, Clone, Deserialize, Serialize, Validate, PartialEq, Eq)] #[derive(Debug, Clone, Deserialize, Serialize, Validate, PartialEq, Eq)]
#[cfg_attr(feature = "schemas", derive(schemars::JsonSchema))] #[cfg_attr(feature = "schemas", derive(schemars::JsonSchema))]
pub struct ChangePassword { pub struct ChangePassword {