Merge pull request #58 from polyphony-chat/main
Bring full-gateway-coverage up to date from main
This commit is contained in:
commit
32d160db64
|
@ -5,7 +5,6 @@ pub mod messages {
|
|||
use serde_json::to_string;
|
||||
|
||||
use crate::api::types::{Message, PartialDiscordFileAttachment, User};
|
||||
use crate::errors::InstanceServerError;
|
||||
use crate::limit::LimitedRequester;
|
||||
|
||||
impl Message {
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
use serde_json::from_str;
|
||||
use serde_json::to_string;
|
||||
|
||||
use crate::api::schemas;
|
||||
use crate::api::types;
|
||||
use crate::errors::InstanceServerError;
|
||||
|
||||
impl<'a> types::Guild {
|
||||
/// Creates a new guild with the given parameters.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `user` - A mutable reference to the user creating the guild.
|
||||
/// * `instance` - A mutable reference to the instance where the guild will be created.
|
||||
/// * `guild_create_schema` - A reference to the schema containing the guild creation parameters.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `Result<String>` containing the ID of the newly created guild, or an error if the request fails.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an `InstanceServerError` if the request fails.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rs
|
||||
/// let guild_create_schema = chorus::api::schemas::GuildCreateSchema::new(insert args here);
|
||||
///
|
||||
/// let result = Guild::create(&mut user, &mut instance, &guild_create_schema).await;
|
||||
///
|
||||
/// match result {
|
||||
/// Ok(guild_id) => println!("Created guild with ID {}", guild_id),
|
||||
/// Err(e) => println!("Failed to create guild: {}", e),
|
||||
/// }
|
||||
/// ```
|
||||
pub async fn create(
|
||||
user: &mut types::User<'a>,
|
||||
url_api: &str,
|
||||
guild_create_schema: schemas::GuildCreateSchema,
|
||||
) -> Result<String, crate::errors::InstanceServerError> {
|
||||
let url = format!("{}/guilds/", url_api);
|
||||
let limits_user = user.limits.get_as_mut();
|
||||
let limits_instance = &mut user.belongs_to.limits;
|
||||
let request = reqwest::Client::new()
|
||||
.post(url.clone())
|
||||
.bearer_auth(user.token.clone())
|
||||
.body(to_string(&guild_create_schema).unwrap());
|
||||
let mut requester = crate::limit::LimitedRequester::new().await;
|
||||
let result = match requester
|
||||
.send_request(
|
||||
request,
|
||||
crate::api::limits::LimitType::Guild,
|
||||
limits_instance,
|
||||
limits_user,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(result) => result,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
let id: types::GuildCreateResponse = from_str(&result.text().await.unwrap()).unwrap();
|
||||
Ok(id.id)
|
||||
}
|
||||
|
||||
/// Deletes a guild.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `user` - A mutable reference to a `User` instance.
|
||||
/// * `instance` - A mutable reference to an `Instance` instance.
|
||||
/// * `guild_id` - A `String` representing the ID of the guild to delete.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// An `Option` containing an `InstanceServerError` if an error occurred during the request, otherwise `None`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rs
|
||||
/// let mut user = User::new();
|
||||
/// let mut instance = Instance::new();
|
||||
/// let guild_id = String::from("1234567890");
|
||||
///
|
||||
/// match Guild::delete(&mut user, &mut instance, guild_id) {
|
||||
/// Some(e) => println!("Error deleting guild: {:?}", e),
|
||||
/// None => println!("Guild deleted successfully"),
|
||||
/// }
|
||||
/// ```
|
||||
pub async fn delete(
|
||||
user: &mut types::User<'a>,
|
||||
url_api: &str,
|
||||
guild_id: String,
|
||||
) -> Option<InstanceServerError> {
|
||||
let url = format!("{}/guilds/{}/delete/", url_api, guild_id);
|
||||
let limits_user = user.limits.get_as_mut();
|
||||
let limits_instance = &mut user.belongs_to.limits;
|
||||
let request = reqwest::Client::new()
|
||||
.post(url.clone())
|
||||
.bearer_auth(user.token.clone());
|
||||
let mut requester = crate::limit::LimitedRequester::new().await;
|
||||
let result = requester
|
||||
.send_request(
|
||||
request,
|
||||
crate::api::limits::LimitType::Guild,
|
||||
limits_instance,
|
||||
limits_user,
|
||||
)
|
||||
.await;
|
||||
if result.is_err() {
|
||||
Some(result.err().unwrap())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::api::schemas;
|
||||
use crate::api::types;
|
||||
use crate::instance::Instance;
|
||||
|
||||
#[tokio::test]
|
||||
async fn guild_creation_deletion() {
|
||||
let mut instance = Instance::new(
|
||||
crate::URLBundle {
|
||||
api: "http://localhost:3001/api".to_string(),
|
||||
wss: "ws://localhost:3001/".to_string(),
|
||||
cdn: "http://localhost:3001".to_string(),
|
||||
},
|
||||
crate::limit::LimitedRequester::new().await,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let login_schema: schemas::LoginSchema = schemas::LoginSchema::new(
|
||||
schemas::AuthUsername::new("user@test.xyz".to_string()).unwrap(),
|
||||
"transrights".to_string(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
let mut user = instance.login_account(&login_schema).await.unwrap();
|
||||
|
||||
let guild_create_schema = schemas::GuildCreateSchema {
|
||||
name: Some("test".to_string()),
|
||||
region: None,
|
||||
icon: None,
|
||||
channels: None,
|
||||
guild_template_code: None,
|
||||
system_channel_id: None,
|
||||
rules_channel_id: None,
|
||||
};
|
||||
|
||||
let guild =
|
||||
types::Guild::create(&mut user, "http://localhost:3001/api", guild_create_schema)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
println!("{}", guild);
|
||||
|
||||
match types::Guild::delete(&mut user, "http://localhost:3001/api", guild).await {
|
||||
None => assert!(true),
|
||||
Some(_) => assert!(false),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
pub mod guilds;
|
||||
|
||||
use guilds::*;
|
|
@ -1,11 +1,13 @@
|
|||
pub mod auth;
|
||||
pub mod channels;
|
||||
pub mod guilds;
|
||||
pub mod policies;
|
||||
pub mod schemas;
|
||||
pub mod types;
|
||||
pub mod users;
|
||||
|
||||
pub use channels::messages::*;
|
||||
pub use guilds::*;
|
||||
pub use policies::instance::instance::*;
|
||||
pub use policies::instance::limits::*;
|
||||
pub use schemas::*;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
pub mod limits {
|
||||
use std::{collections::HashMap};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use reqwest::Client;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -20,6 +20,23 @@ pub mod limits {
|
|||
Webhook,
|
||||
}
|
||||
|
||||
impl ToString for LimitType {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
LimitType::AuthRegister => "AuthRegister".to_string(),
|
||||
LimitType::AuthLogin => "AuthLogin".to_string(),
|
||||
LimitType::AbsoluteMessage => "AbsoluteMessage".to_string(),
|
||||
LimitType::AbsoluteRegister => "AbsoluteRegister".to_string(),
|
||||
LimitType::Global => "Global".to_string(),
|
||||
LimitType::Ip => "Ip".to_string(),
|
||||
LimitType::Channel => "Channel".to_string(),
|
||||
LimitType::Error => "Error".to_string(),
|
||||
LimitType::Guild => "Guild".to_string(),
|
||||
LimitType::Webhook => "Webhook".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[allow(non_snake_case)]
|
||||
pub struct User {
|
||||
|
|
|
@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use crate::errors::FieldFormatError;
|
||||
|
||||
use super::Embed;
|
||||
use super::{Channel, Embed};
|
||||
|
||||
/**
|
||||
A struct that represents a well-formed email address.
|
||||
|
@ -287,6 +287,18 @@ impl MessageSendSchema {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct GuildCreateSchema {
|
||||
pub name: Option<String>,
|
||||
pub region: Option<String>,
|
||||
pub icon: Option<String>,
|
||||
pub channels: Option<Vec<Channel>>,
|
||||
pub guild_template_code: Option<String>,
|
||||
pub system_channel_id: Option<String>,
|
||||
pub rules_channel_id: Option<String>,
|
||||
}
|
||||
|
||||
// I know that some of these tests are... really really basic and unneccessary, but sometimes, I
|
||||
// just feel like writing tests, so there you go :) -@bitfl0wer
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -1841,3 +1841,8 @@ pub struct Webhook {
|
|||
pub source_guild: Option<Guild>,
|
||||
pub id: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||
pub struct GuildCreateResponse {
|
||||
pub id: String,
|
||||
}
|
||||
|
|
|
@ -17,8 +17,11 @@ custom_error! {
|
|||
ReceivedErrorCodeError{error_code:String} = "Received the following error code while requesting from the route: {error_code}",
|
||||
CantGetInfoError{error:String} = "Something seems to be wrong with the instance. Cannot get information about the instance: {error}",
|
||||
InvalidFormBodyError{error_type: String, error:String} = "The server responded with: {error_type}: {error}",
|
||||
RateLimited = "Ratelimited.",
|
||||
RateLimited{bucket:String} = "Ratelimited on Bucket {bucket}",
|
||||
MultipartCreationError{error: String} = "Got an error whilst creating the form: {}",
|
||||
TokenExpired = "Token expired, invalid or not found.",
|
||||
NoPermission = "You do not have the permissions needed to perform this action.",
|
||||
NotFound{error: String} = "The provided resource hasn't been found: {}",
|
||||
}
|
||||
|
||||
custom_error! {
|
||||
|
|
39
src/limit.rs
39
src/limit.rs
|
@ -57,7 +57,8 @@ impl LimitedRequester {
|
|||
|
||||
## Errors
|
||||
|
||||
This method will panic, if:
|
||||
This method will error, if:
|
||||
- The request does not return a success status code (200-299)
|
||||
- The supplied [`RequestBuilder`](reqwest::RequestBuilder) contains invalid or incomplete
|
||||
information
|
||||
- There has been an error with processing (unwrapping) the [`Response`](`reqwest::Response`)
|
||||
|
@ -72,13 +73,23 @@ impl LimitedRequester {
|
|||
user_rate_limits: &mut Limits,
|
||||
) -> Result<Response, InstanceServerError> {
|
||||
if self.can_send_request(limit_type, instance_rate_limits, user_rate_limits) {
|
||||
let built_request = request
|
||||
.build()
|
||||
.unwrap_or_else(|e| panic!("Error while building the Request for sending: {}", e));
|
||||
let built_request = match request.build() {
|
||||
Ok(request) => request,
|
||||
Err(e) => {
|
||||
return Err(InstanceServerError::RequestErrorError {
|
||||
url: "".to_string(),
|
||||
error: e.to_string(),
|
||||
})
|
||||
}
|
||||
};
|
||||
let result = self.http.execute(built_request).await;
|
||||
let response = match result {
|
||||
Ok(is_response) => is_response,
|
||||
Err(e) => panic!("An error occured while processing the response: {}", e),
|
||||
Err(e) => {
|
||||
return Err(InstanceServerError::ReceivedErrorCodeError {
|
||||
error_code: e.to_string(),
|
||||
})
|
||||
}
|
||||
};
|
||||
self.update_limits(
|
||||
&response,
|
||||
|
@ -86,13 +97,27 @@ impl LimitedRequester {
|
|||
instance_rate_limits,
|
||||
user_rate_limits,
|
||||
);
|
||||
Ok(response)
|
||||
if !response.status().is_success() {
|
||||
match response.status().as_u16() {
|
||||
401 => return Err(InstanceServerError::TokenExpired),
|
||||
403 => return Err(InstanceServerError::TokenExpired),
|
||||
_ => {
|
||||
return Err(InstanceServerError::ReceivedErrorCodeError {
|
||||
error_code: response.status().as_str().to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Ok(response)
|
||||
}
|
||||
} else {
|
||||
self.requests.push_back(TypedRequest {
|
||||
request,
|
||||
limit_type,
|
||||
});
|
||||
Err(InstanceServerError::RateLimited)
|
||||
Err(InstanceServerError::RateLimited {
|
||||
bucket: limit_type.to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue