Merge pull request #6 from polyphony-chat/feature/register-login

Replace Custom Error boilerplate with macro
This commit is contained in:
Flori 2023-04-21 15:32:56 +02:00 committed by GitHub
commit 128aaa5103
5 changed files with 33 additions and 105 deletions

View File

@ -4,8 +4,6 @@ version = "0.1.0"
license = "AGPL-3" license = "AGPL-3"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
tokio = {version = "1.27.0", features = ["rt", "macros"]} tokio = {version = "1.27.0", features = ["rt", "macros"]}
serde = {version = "1.0.159", features = ["derive"]} serde = {version = "1.0.159", features = ["derive"]}
@ -13,4 +11,5 @@ serde_json = "1.0.95"
reqwest = "0.11.16" reqwest = "0.11.16"
url = "2.3.1" url = "2.3.1"
chrono = "0.4.24" chrono = "0.4.24"
regex = "1.7.3" regex = "1.7.3"
custom_error = "1.9.2"

View File

@ -1,6 +1,5 @@
pub mod register { pub mod register {
use std::fmt; use custom_error::custom_error;
use reqwest::Client; use reqwest::Client;
use serde_json::json; use serde_json::json;
@ -16,23 +15,4 @@ pub mod register {
// TODO // TODO
} }
} }
#[derive(Debug, PartialEq, Eq)]
pub struct RegisterError {
pub message: String,
}
impl RegisterError {
fn new(message: String) -> Self {
RegisterError { message }
}
}
impl fmt::Display for RegisterError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.message)
}
}
impl std::error::Error for RegisterError {}
} }

View File

@ -1,29 +1,17 @@
pub mod instance { pub mod instance {
use std::fmt; use custom_error::custom_error;
use reqwest::Client; use reqwest::Client;
use serde_json::from_str; use serde_json::from_str;
use crate::{api::schemas::schemas::InstancePoliciesSchema, instance::Instance}; use crate::{api::schemas::schemas::InstancePoliciesSchema, instance::Instance};
#[derive(Debug, PartialEq, Eq)] custom_error! {
pub struct InstancePoliciesError { #[derive(PartialEq, Eq)]
pub message: String, pub InstancePoliciesError
RequestErrorError{url:String, error:String} = "An error occured while trying to GET from {url}: {error}",
ReceivedErrorCodeError{error_code:String} = "Received the following error code while requesting from the route: {error_code}"
} }
impl InstancePoliciesError {
fn new(message: String) -> Self {
InstancePoliciesError { message }
}
}
impl fmt::Display for InstancePoliciesError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.message)
}
}
impl std::error::Error for InstancePoliciesError {}
impl Instance { impl Instance {
/** /**
Gets the instance policies schema. Gets the instance policies schema.
@ -38,21 +26,16 @@ pub mod instance {
let request = match client.get(&endpoint_url).send().await { let request = match client.get(&endpoint_url).send().await {
Ok(result) => result, Ok(result) => result,
Err(e) => { Err(e) => {
return Err(InstancePoliciesError { return Err(InstancePoliciesError::RequestErrorError {
message: format!( url: endpoint_url,
"An error occured while trying to GET from {}: {}", error: e.to_string(),
endpoint_url, e
),
}); });
} }
}; };
if request.status().as_str().chars().next().unwrap() != '2' { if request.status().as_str().chars().next().unwrap() != '2' {
return Err(InstancePoliciesError { return Err(InstancePoliciesError::ReceivedErrorCodeError {
message: format!( error_code: request.status().to_string(),
"Received the following error code while requesting from the route: {}",
request.status().as_str()
),
}); });
} }

View File

@ -1,6 +1,7 @@
pub mod schemas { pub mod schemas {
use std::fmt; use std::fmt;
use custom_error::custom_error;
use regex::Regex; use regex::Regex;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -19,25 +20,15 @@ pub mod schemas {
promotional_email_opt_in: Option<bool>, promotional_email_opt_in: Option<bool>,
} }
#[derive(Debug, PartialEq, Eq)] custom_error! {
pub struct RegisterSchemaError { #[derive(PartialEq, Eq)]
pub message: String, pub RegisterSchemaError
PasswordError = "Password must be between 1 and 72 characters.",
UsernameError = "Username must be between 2 and 32 characters.",
ConsentError = "Consent must be 'true' to register.",
EmailError = "The provided email address is in an invalid format."
} }
impl RegisterSchemaError {
fn new(message: String) -> Self {
RegisterSchemaError { message }
}
}
impl fmt::Display for RegisterSchemaError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.message)
}
}
impl std::error::Error for RegisterSchemaError {}
impl RegisterSchema { impl RegisterSchema {
/** /**
Returns a new [`Result<RegisterSchema, RegisterSchemaError>`]. Returns a new [`Result<RegisterSchema, RegisterSchemaError>`].
@ -64,28 +55,20 @@ pub mod schemas {
promotional_email_opt_in: Option<bool>, promotional_email_opt_in: Option<bool>,
) -> Result<RegisterSchema, RegisterSchemaError> { ) -> Result<RegisterSchema, RegisterSchemaError> {
if username.len() < 2 || username.len() > 32 { if username.len() < 2 || username.len() > 32 {
return Err(RegisterSchemaError::new( return Err(RegisterSchemaError::UsernameError);
"Username must be between 2 and 32 characters".to_string(),
));
} }
if password.is_some() if password.is_some()
&& (password.as_ref().unwrap().len() < 1 || password.as_ref().unwrap().len() > 72) && (password.as_ref().unwrap().len() < 1 || password.as_ref().unwrap().len() > 72)
{ {
return Err(RegisterSchemaError { return Err(RegisterSchemaError::PasswordError);
message: "Password must be between 1 and 72 characters.".to_string(),
});
} }
if !consent { if !consent {
return Err(RegisterSchemaError { return Err(RegisterSchemaError::ConsentError);
message: "Consent must be 'true' to register.".to_string(),
});
} }
let regex = Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$").unwrap(); let regex = Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$").unwrap();
if email.clone().is_some() && !regex.is_match(email.clone().unwrap().as_str()) { if email.clone().is_some() && !regex.is_match(email.clone().unwrap().as_str()) {
return Err(RegisterSchemaError { return Err(RegisterSchemaError::EmailError);
message: "The provided email address is in an invalid format.".to_string(),
});
} }
return Ok(RegisterSchema { return Ok(RegisterSchema {
@ -199,9 +182,7 @@ mod schemas_tests {
None, None,
None, None,
), ),
Err(RegisterSchemaError { Err(RegisterSchemaError::PasswordError)
message: "Password must be between 1 and 72 characters.".to_string()
})
); );
} }
@ -224,9 +205,7 @@ mod schemas_tests {
None, None,
None, None,
), ),
Err(RegisterSchemaError { Err(RegisterSchemaError::PasswordError)
message: "Password must be between 1 and 72 characters.".to_string()
})
); );
} }
@ -245,9 +224,7 @@ mod schemas_tests {
None, None,
None, None,
), ),
Err(RegisterSchemaError { Err(RegisterSchemaError::UsernameError)
message: "Username must be between 2 and 32 characters".to_string()
})
); );
} }
@ -259,9 +236,7 @@ mod schemas_tests {
} }
assert_eq!( assert_eq!(
RegisterSchema::new(long_un, None, true, None, None, None, None, None, None, None,), RegisterSchema::new(long_un, None, true, None, None, None, None, None, None, None,),
Err(RegisterSchemaError { Err(RegisterSchemaError::UsernameError)
message: "Username must be between 2 and 32 characters".to_string()
})
); );
} }
@ -280,9 +255,7 @@ mod schemas_tests {
None, None,
None, None,
), ),
Err(RegisterSchemaError { Err(RegisterSchemaError::ConsentError)
message: "Consent must be 'true' to register.".to_string()
})
); );
} }
@ -301,9 +274,7 @@ mod schemas_tests {
None, None,
None, None,
), ),
Err(RegisterSchemaError { Err(RegisterSchemaError::EmailError)
message: "The provided email address is in an invalid format.".to_string()
})
) )
} }
@ -321,11 +292,6 @@ mod schemas_tests {
None, None,
None, None,
); );
assert_ne!( assert_ne!(reg, Err(RegisterSchemaError::EmailError));
reg,
Err(RegisterSchemaError {
message: "The provided email address is in an invalid format.".to_string()
})
);
} }
} }

View File