feat(luz): implement helper methods for LuzHandle
This commit is contained in:
parent
861db1197d
commit
ead1b25803
|
@ -2,7 +2,10 @@ use std::sync::Arc;
|
|||
|
||||
use stanza::client::Stanza;
|
||||
use thiserror::Error;
|
||||
use tokio::sync::{mpsc::error::SendError, oneshot::error::RecvError};
|
||||
use tokio::{
|
||||
sync::{mpsc::error::SendError, oneshot::error::RecvError},
|
||||
time::error::Elapsed,
|
||||
};
|
||||
|
||||
#[derive(Debug, Error, Clone)]
|
||||
pub enum Error {
|
||||
|
@ -37,6 +40,14 @@ pub enum Error {
|
|||
Disconnected,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error, Clone)]
|
||||
pub enum CommandError<T> {
|
||||
#[error("actor: {0}")]
|
||||
Actor(ActorError),
|
||||
#[error("{0}")]
|
||||
Error(#[from] T),
|
||||
}
|
||||
|
||||
#[derive(Debug, Error, Clone)]
|
||||
pub enum MessageSendError {
|
||||
#[error("could not add to message history: {0}")]
|
||||
|
@ -145,6 +156,12 @@ pub enum ActorError {
|
|||
Receive,
|
||||
}
|
||||
|
||||
impl From<Elapsed> for ActorError {
|
||||
fn from(_e: Elapsed) -> Self {
|
||||
Self::Timeout
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<SendError<T>> for ActorError {
|
||||
fn from(_e: SendError<T>) -> Self {
|
||||
Self::Send
|
||||
|
|
263
luz/src/lib.rs
263
luz/src/lib.rs
|
@ -2,12 +2,16 @@ use std::{
|
|||
collections::HashMap,
|
||||
ops::{Deref, DerefMut},
|
||||
sync::Arc,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use chat::{Body, Chat, Message};
|
||||
use connection::{write::WriteMessage, SupervisorSender};
|
||||
use db::Db;
|
||||
use error::{ConnectionError, DatabaseError, ReadError, RosterError, StatusError, WriteError};
|
||||
use error::{
|
||||
ActorError, CommandError, ConnectionError, DatabaseError, ReadError, RosterError, StatusError,
|
||||
WriteError,
|
||||
};
|
||||
use futures::{future::Fuse, FutureExt};
|
||||
use jabber::JID;
|
||||
use presence::{Offline, Online, Presence};
|
||||
|
@ -20,6 +24,7 @@ use stanza::client::{
|
|||
use tokio::{
|
||||
sync::{mpsc, oneshot, Mutex},
|
||||
task::JoinSet,
|
||||
time::timeout,
|
||||
};
|
||||
use tracing::{debug, info};
|
||||
use user::User;
|
||||
|
@ -1018,12 +1023,14 @@ impl CommandMessage {
|
|||
#[derive(Debug)]
|
||||
pub struct LuzHandle {
|
||||
sender: mpsc::Sender<CommandMessage>,
|
||||
timeout: Duration,
|
||||
}
|
||||
|
||||
impl Clone for LuzHandle {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
sender: self.sender.clone(),
|
||||
timeout: self.timeout,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1071,60 +1078,260 @@ impl LuzHandle {
|
|||
Ok((
|
||||
Self {
|
||||
sender: command_sender,
|
||||
// TODO: configure timeout
|
||||
timeout: Duration::from_secs(10),
|
||||
},
|
||||
update_receiver,
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn connect(&self) {
|
||||
self.send(CommandMessage::Connect).await;
|
||||
pub async fn connect(&self) -> Result<(), ActorError> {
|
||||
self.send(CommandMessage::Connect).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn disconnect(&self, offline: Offline) {
|
||||
self.send(CommandMessage::Disconnect(offline)).await;
|
||||
pub async fn disconnect(&self, offline: Offline) -> Result<(), ActorError> {
|
||||
self.send(CommandMessage::Disconnect(offline)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// pub async fn get_roster(&self) -> Result<Vec<Contact>, RosterError> {
|
||||
// let (send, recv) = oneshot::channel();
|
||||
// self.send(CommandMessage::GetRoster(send)).await.map_err(|e| RosterError::)?;
|
||||
// Ok(recv.await?)
|
||||
// }
|
||||
pub async fn get_roster(&self) -> Result<Vec<Contact>, CommandError<RosterError>> {
|
||||
let (send, recv) = oneshot::channel();
|
||||
self.send(CommandMessage::GetRoster(send))
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
|
||||
let roster = timeout(self.timeout, recv)
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
|
||||
Ok(roster)
|
||||
}
|
||||
|
||||
// pub async fn get_chats(&self) -> Result<Vec<Chat>, Error> {}
|
||||
pub async fn get_chats(&self) -> Result<Vec<Chat>, CommandError<DatabaseError>> {
|
||||
let (send, recv) = oneshot::channel();
|
||||
self.send(CommandMessage::GetChats(send))
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
|
||||
let chats = timeout(self.timeout, recv)
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
|
||||
Ok(chats)
|
||||
}
|
||||
|
||||
// pub async fn get_chat(&self, jid: JID) -> Result<Chat, Error> {}
|
||||
pub async fn get_chat(&self, jid: JID) -> Result<Chat, CommandError<DatabaseError>> {
|
||||
let (send, recv) = oneshot::channel();
|
||||
self.send(CommandMessage::GetChat(jid, send))
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
|
||||
let chat = timeout(self.timeout, recv)
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
|
||||
Ok(chat)
|
||||
}
|
||||
|
||||
// pub async fn get_messages(&self, jid: JID) -> Result<Vec<Message>, Error> {}
|
||||
pub async fn get_messages(
|
||||
&self,
|
||||
jid: JID,
|
||||
) -> Result<Vec<Message>, CommandError<DatabaseError>> {
|
||||
let (send, recv) = oneshot::channel();
|
||||
self.send(CommandMessage::GetMessages(jid, send))
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
|
||||
let messages = timeout(self.timeout, recv)
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
|
||||
Ok(messages)
|
||||
}
|
||||
|
||||
// pub async fn delete_chat(&self, jid: JID) -> Result<(), Error> {}
|
||||
pub async fn delete_chat(&self, jid: JID) -> Result<(), CommandError<DatabaseError>> {
|
||||
let (send, recv) = oneshot::channel();
|
||||
self.send(CommandMessage::DeleteChat(jid, send))
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
|
||||
let result = timeout(self.timeout, recv)
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// pub async fn delete_message(&self, id: Uuid) -> Result<(), Error> {}
|
||||
pub async fn delete_message(&self, id: Uuid) -> Result<(), CommandError<DatabaseError>> {
|
||||
let (send, recv) = oneshot::channel();
|
||||
self.send(CommandMessage::DeleteMessage(id, send))
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
|
||||
let result = timeout(self.timeout, recv)
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// pub async fn get_user(&self, jid: JID) -> Result<User, Error> {}
|
||||
pub async fn get_user(&self, jid: JID) -> Result<User, CommandError<DatabaseError>> {
|
||||
let (send, recv) = oneshot::channel();
|
||||
self.send(CommandMessage::GetUser(jid, send))
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
|
||||
let result = timeout(self.timeout, recv)
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// pub async fn add_contact(&self, jid: JID) -> Result<(), Error> {}
|
||||
pub async fn add_contact(&self, jid: JID) -> Result<(), CommandError<RosterError>> {
|
||||
let (send, recv) = oneshot::channel();
|
||||
self.send(CommandMessage::AddContact(jid, send))
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
|
||||
let result = timeout(self.timeout, recv)
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// pub async fn buddy_request(&self, jid: JID) -> Result<(), Error> {}
|
||||
pub async fn buddy_request(&self, jid: JID) -> Result<(), CommandError<WriteError>> {
|
||||
let (send, recv) = oneshot::channel();
|
||||
self.send(CommandMessage::BuddyRequest(jid, send))
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
|
||||
let result = timeout(self.timeout, recv)
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// pub async fn subscription_request(&self, jid: JID) -> Result<(), Error> {}
|
||||
pub async fn subscription_request(&self, jid: JID) -> Result<(), CommandError<WriteError>> {
|
||||
let (send, recv) = oneshot::channel();
|
||||
self.send(CommandMessage::SubscriptionRequest(jid, send))
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
|
||||
let result = timeout(self.timeout, recv)
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// pub async fn accept_buddy_request(&self, jid: JID) -> Result<(), Error> {}
|
||||
pub async fn accept_buddy_request(&self, jid: JID) -> Result<(), CommandError<WriteError>> {
|
||||
let (send, recv) = oneshot::channel();
|
||||
self.send(CommandMessage::AcceptBuddyRequest(jid, send))
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
|
||||
let result = timeout(self.timeout, recv)
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// pub async fn accept_subscription_request(&self, jid: JID) -> Result<(), Error> {}
|
||||
pub async fn accept_subscription_request(
|
||||
&self,
|
||||
jid: JID,
|
||||
) -> Result<(), CommandError<WriteError>> {
|
||||
let (send, recv) = oneshot::channel();
|
||||
self.send(CommandMessage::AcceptSubscriptionRequest(jid, send))
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
|
||||
let result = timeout(self.timeout, recv)
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// pub async fn unsubscribe_from_contact(&self, jid: JID) -> Result<(), Error> {}
|
||||
pub async fn unsubscribe_from_contact(&self, jid: JID) -> Result<(), CommandError<WriteError>> {
|
||||
let (send, recv) = oneshot::channel();
|
||||
self.send(CommandMessage::UnsubscribeFromContact(jid, send))
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
|
||||
let result = timeout(self.timeout, recv)
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// pub async fn unsubscribe_contact(&self, jid: JID) -> Result<(), Error> {}
|
||||
pub async fn unsubscribe_contact(&self, jid: JID) -> Result<(), CommandError<WriteError>> {
|
||||
let (send, recv) = oneshot::channel();
|
||||
self.send(CommandMessage::UnsubscribeContact(jid, send))
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
|
||||
let result = timeout(self.timeout, recv)
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// pub async fn unfriend_contact(&self, jid: JID) -> Result<(), Error> {}
|
||||
pub async fn unfriend_contact(&self, jid: JID) -> Result<(), CommandError<WriteError>> {
|
||||
let (send, recv) = oneshot::channel();
|
||||
self.send(CommandMessage::UnfriendContact(jid, send))
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
|
||||
let result = timeout(self.timeout, recv)
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// pub async fn delete_contact(&self, jid: JID) -> Result<(), Error> {}
|
||||
pub async fn delete_contact(&self, jid: JID) -> Result<(), CommandError<RosterError>> {
|
||||
let (send, recv) = oneshot::channel();
|
||||
self.send(CommandMessage::DeleteContact(jid, send))
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
|
||||
let result = timeout(self.timeout, recv)
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// pub async fn update_contact(&self, jid: JID, update: ContactUpdate) -> Result<(), Error> {}
|
||||
pub async fn update_contact(
|
||||
&self,
|
||||
jid: JID,
|
||||
update: ContactUpdate,
|
||||
) -> Result<(), CommandError<RosterError>> {
|
||||
let (send, recv) = oneshot::channel();
|
||||
self.send(CommandMessage::UpdateContact(jid, update, send))
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
|
||||
let result = timeout(self.timeout, recv)
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// pub async fn set_status(&self, online: Online) -> Result<(), Error> {}
|
||||
pub async fn set_status(&self, online: Online) -> Result<(), CommandError<StatusError>> {
|
||||
let (send, recv) = oneshot::channel();
|
||||
self.send(CommandMessage::SetStatus(online, send))
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
|
||||
let result = timeout(self.timeout, recv)
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// pub async fn send_message(&self, jid: JID, body: Body) -> Result<(), Error> {}
|
||||
pub async fn send_message(&self, jid: JID, body: Body) -> Result<(), CommandError<WriteError>> {
|
||||
let (send, recv) = oneshot::channel();
|
||||
self.send(CommandMessage::SendMessage(jid, body, send))
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?;
|
||||
let result = timeout(self.timeout, recv)
|
||||
.await
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))?
|
||||
.map_err(|e| CommandError::Actor(Into::<ActorError>::into(e)))??;
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: generate methods for each with a macro
|
||||
|
|
Loading…
Reference in New Issue