diff --git a/src/api/auth/login.rs b/src/api/auth/login.rs index f7c4fe6..23add11 100644 --- a/src/api/auth/login.rs +++ b/src/api/auth/login.rs @@ -8,7 +8,7 @@ pub mod login { use crate::errors::InstanceServerError; use crate::instance::Instance; - impl Instance { + impl<'a> Instance<'a> { pub async fn login_account( &mut self, login_schema: &LoginSchema, diff --git a/src/api/auth/register.rs b/src/api/auth/register.rs index b932b9f..b4d4fd1 100644 --- a/src/api/auth/register.rs +++ b/src/api/auth/register.rs @@ -8,7 +8,7 @@ pub mod register { instance::{Instance, Token}, }; - impl Instance { + impl<'a> Instance<'a> { /** Registers a new user on the Spacebar server. # Arguments diff --git a/src/api/channels/messages.rs b/src/api/channels/messages.rs index cbfcdc5..dae8a9e 100644 --- a/src/api/channels/messages.rs +++ b/src/api/channels/messages.rs @@ -1 +1,66 @@ -pub mod messages {} +pub mod messages { + use reqwest::{Client, Response}; + use serde_json::to_string; + + use crate::api::limits::Limits; + use crate::api::types::Message; + use crate::api::User; + use crate::errors::InstanceServerError; + use crate::limit::LimitedRequester; + + impl Message { + /** + Sends a message to the Spacebar server. + # Arguments + * `url_api` - The URL of the Spacebar server's API. + * `message` - The [`Message`] that will be sent to the Spacebar server. + * `limits_user` - The [`Limits`] of the user. + * `limits_instance` - The [`Limits`] of the instance. + * `requester` - The [`LimitedRequester`] that will be used to make requests to the Spacebar server. + # Errors + * [`InstanceServerError`] - If the message cannot be sent. + */ + pub async fn send( + url_api: &String, + message: &Message, + limits_user: &mut Limits, + limits_instance: &mut Limits, + requester: &mut LimitedRequester, + ) -> Result { + let request = Client::new() + .post(format!( + "{}/channels/{}/messages", + url_api, message.channel_id + )) + .body(to_string(message).unwrap()); + match requester + .send_request( + request, + crate::api::limits::LimitType::Channel, + limits_instance, + limits_user, + ) + .await + { + Ok(result) => Ok(result), + Err(e) => Err(e), + } + } + } + + impl<'a> User<'a> { + pub async fn send_message( + &mut self, + message: &Message, + ) -> Result { + Message::send( + &self.belongs_to().urls.get_api().to_string(), + message, + self.rate_limits.get_as_mut(), + &mut self.belongs_to.limits.get_as_mut(), + &mut LimitedRequester::new().await, + ) + .await + } + } +} diff --git a/src/api/policies/instance/instance.rs b/src/api/policies/instance/instance.rs index 7c1a48a..f7a5653 100644 --- a/src/api/policies/instance/instance.rs +++ b/src/api/policies/instance/instance.rs @@ -5,7 +5,7 @@ pub mod instance { use crate::errors::InstanceServerError; use crate::{api::types::InstancePolicies, instance::Instance}; - impl Instance { + impl<'a> Instance<'a> { /** Gets the instance policies schema. # Errors diff --git a/src/api/policies/instance/limits.rs b/src/api/policies/instance/limits.rs index 7c4b624..58d55c5 100644 --- a/src/api/policies/instance/limits.rs +++ b/src/api/policies/instance/limits.rs @@ -304,6 +304,10 @@ pub mod limits { map } + pub fn get_as_mut(&mut self) -> &mut Limits { + self + } + /// check_limits uses the API to get the current request limits of the instance. /// It returns a `Limits` struct containing all the limits. /// If the rate limit is disabled, then the limit is set to `u64::MAX`. diff --git a/src/api/types.rs b/src/api/types.rs index 2efbc1a..9cba561 100644 --- a/src/api/types.rs +++ b/src/api/types.rs @@ -4,11 +4,9 @@ https://discord.com/developers/docs . I do not feel like re-documenting all of this, as everything is already perfectly explained there. */ -use std::fmt; - use serde::{Deserialize, Serialize}; -use crate::{api::limits::Limits, URLBundle}; +use crate::{api::limits::Limits, instance::Instance}; pub trait WebSocketEvent {} @@ -154,22 +152,22 @@ pub struct UserObject { } #[derive(Debug)] -pub struct User { - logged_in: bool, - belongs_to: URLBundle, +pub struct User<'a> { + pub logged_in: bool, + pub belongs_to: &'a mut Instance<'a>, token: String, - rate_limits: Limits, + pub rate_limits: Limits, pub settings: UserSettings, pub object: UserObject, } -impl User { +impl<'a> User<'a> { pub fn is_logged_in(&self) -> bool { self.logged_in } - pub fn belongs_to(&self) -> URLBundle { - self.belongs_to.clone() + pub fn belongs_to(&mut self) -> &mut Instance<'a> { + self.belongs_to } pub fn token(&self) -> String { @@ -186,12 +184,12 @@ impl User { pub fn new( logged_in: bool, - belongs_to: URLBundle, + belongs_to: &'a mut Instance<'a>, token: String, rate_limits: Limits, settings: UserSettings, object: UserObject, - ) -> User { + ) -> User<'a> { User { logged_in, belongs_to, @@ -206,7 +204,7 @@ impl User { #[derive(Debug, Serialize, Deserialize, Default)] pub struct Message { id: String, - channel_id: String, + pub channel_id: String, author: UserObject, content: String, timestamp: String, diff --git a/src/gateway.rs b/src/gateway.rs index 818d14b..a9f6ffb 100644 --- a/src/gateway.rs +++ b/src/gateway.rs @@ -1,5 +1,7 @@ -use std::sync::Arc; -use std::thread; + + + + use crate::api::types::*; use crate::api::WebSocketEvent; @@ -7,14 +9,13 @@ use crate::errors::ObserverError; use crate::gateway::events::Events; use crate::URLBundle; -use futures_util::stream::{FilterMap, SplitSink, SplitStream}; -use futures_util::SinkExt; use futures_util::StreamExt; use native_tls::TlsConnector; use reqwest::Url; use serde::Deserialize; use serde::Serialize; -use serde_json::from_str; + + use tokio::io; use tokio::net::TcpStream; use tokio::sync::mpsc::{channel, Receiver, Sender}; @@ -94,21 +95,14 @@ impl<'a> WebSocketConnection { while let Some(msg) = shared_channel_read.lock().await.recv().await { write_tx.send(msg).await.unwrap(); } + }; - let event = while let Some(msg) = write_rx.next().await { - shared_channel_write - .lock() - .await - .send(msg.unwrap()) - .await - .unwrap(); - }; - }); - - WebSocketConnection { - tx: clone_shared_channel_write, - rx: clone_shared_channel_read, - } + Ok(Gateway { + url: websocket_url, + token, + events: Events::default(), + socket: ws_stream, + }) } } @@ -172,7 +166,6 @@ impl<'a, T: WebSocketEvent> GatewayEvent<'a, T> { // pointer value than observable. self.observers.retain(|obs| !std::ptr::eq(*obs, observable)); self.is_observed = !self.observers.is_empty(); - return; } /** @@ -266,7 +259,7 @@ mod example { #[tokio::test] async fn test_gateway() { - let gateway = Gateway::new("ws://localhost:3001/".to_string(), "none".to_string()) + let _gateway = Gateway::new("ws://localhost:3001/".to_string(), "none".to_string()) .await .unwrap(); } diff --git a/src/instance.rs b/src/instance.rs index 3e52e88..ad877f0 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -11,16 +11,16 @@ use std::fmt; /** The [`Instance`] what you will be using to perform all sorts of actions on the Spacebar server. */ -pub struct Instance { +pub struct Instance<'a> { pub urls: URLBundle, pub instance_info: InstancePolicies, pub requester: LimitedRequester, pub limits: Limits, //pub gateway: Gateway, - pub users: HashMap, + pub users: HashMap>, } -impl Instance { +impl<'a> Instance<'a> { /// Creates a new [`Instance`]. /// # Arguments /// * `urls` - The [`URLBundle`] that contains all the URLs that are needed to connect to the Spacebar server. @@ -30,7 +30,7 @@ impl Instance { pub async fn new( urls: URLBundle, requester: LimitedRequester, - ) -> Result { + ) -> Result, InstanceServerError> { let users: HashMap = HashMap::new(); let mut instance = Instance { urls: urls.clone(), diff --git a/src/limit.rs b/src/limit.rs index 84e6d17..0dfbbd3 100644 --- a/src/limit.rs +++ b/src/limit.rs @@ -261,7 +261,7 @@ mod rate_limit { #[tokio::test] async fn create_limited_requester() { - let urls = URLBundle::new( + let _urls = URLBundle::new( String::from("http://localhost:3001/api/"), String::from("wss://localhost:3001/"), String::from("http://localhost:3001/cdn"),