Invite struct has been simplified
Invite::as_json_str/from_tuple changed to reflect new field changes + insert_new_invite: short and sweet error handling by the caller for now * create_invite now named `create` + reduced code complexity in invites::create so its very straight forward to read(imo)
This commit is contained in:
parent
3e91d42f94
commit
8a91d51dc6
@ -9,10 +9,13 @@ use hyper::{Response, Body, StatusCode};
|
||||
|
||||
use chrono::Utc;
|
||||
use rand::random;
|
||||
struct InviteRow {
|
||||
id: u64,
|
||||
expires: u64,
|
||||
uses: i32,
|
||||
|
||||
use crate::db_types::{BigInt, Integer};
|
||||
|
||||
struct Invite {
|
||||
id: BigInt,
|
||||
uses: Option<BigInt>, // optional because some links are permanent
|
||||
expires: bool,
|
||||
}
|
||||
/*
|
||||
* Error handling:
|
||||
@ -20,29 +23,22 @@ struct InviteRow {
|
||||
* are of the enum mysql_async::error::Error
|
||||
*/
|
||||
|
||||
impl InviteRow {
|
||||
pub fn new() -> InviteRow {
|
||||
let dt = Utc::now() + chrono::Duration::minutes(30);
|
||||
// TODO:[maybe] ensure no collisions by doing a quick database check here
|
||||
let invite = InviteRow {
|
||||
id: random::<u64>(), // hopefully there won't ever be collision with this size of pool
|
||||
uses: 1, // default/hardcorded for now
|
||||
expires: dt.timestamp() as u64
|
||||
};
|
||||
invite
|
||||
}
|
||||
pub fn from_tuple(tup: (u64, u64, i32)) -> InviteRow {
|
||||
InviteRow {
|
||||
impl Invite {
|
||||
pub fn from_tuple(tup: (BigInt, Option<Integer>, bool)) -> Invite {
|
||||
/*
|
||||
* Let's us convert tuples from mysql into convenient invite structs */
|
||||
Invite {
|
||||
id: tup.0,
|
||||
expires: tup.1,
|
||||
uses: tup.2,
|
||||
uses: tup.1,
|
||||
expires: tup.2
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_json_str(&self) -> String {
|
||||
// TODO: Deprecate
|
||||
let id = format!("\"id\":{}", self.id);
|
||||
let expires = format!("\"expires\":{}", self.expires);
|
||||
let uses = format!("\"uses\":{}", self.uses);
|
||||
let uses = format!("\"uses\":{:?}", self.uses);
|
||||
|
||||
let mut data = String::from("{");
|
||||
data.push_str(&format!("{},", id));
|
||||
@ -52,14 +48,14 @@ impl InviteRow {
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_invite_by_code(pool: &Pool, value: Option<&str>) -> Result<Option<InviteRow>, Error> {
|
||||
async fn get_invite_by_code(pool: &Pool, value: Option<&str>) -> Result<Option<Invite>, Error> {
|
||||
if let Some(val) = value {
|
||||
let conn = pool.get_conn().await?;
|
||||
let db_row_result: (Conn, Option<(u64, u64, i32)>) = conn
|
||||
let db_row_result: (Conn, Option<(BigInt, Option<Integer>, bool)>) = conn
|
||||
.first_exec(r"SELECT * FROM", mysql_async::params!{"code"=>val})
|
||||
.await?;
|
||||
if let Some(tup) = db_row_result.1 {
|
||||
Ok(Some(InviteRow::from_tuple(tup)))
|
||||
Ok(Some(Invite::from_tuple(tup)))
|
||||
}
|
||||
else {
|
||||
// basically nothing was found but nothing bad happened
|
||||
@ -70,7 +66,7 @@ async fn get_invite_by_code(pool: &Pool, value: Option<&str>) -> Result<Option<I
|
||||
else {Ok(None)}
|
||||
}
|
||||
|
||||
async fn record_invite_usage(pool: &Pool, data: &InviteRow) -> Result<(), Error>{
|
||||
async fn record_invite_usage(pool: &Pool, data: &Invite) -> Result<(), Error>{
|
||||
/*
|
||||
* By this this is called we really don't care about what happens as we've
|
||||
* already been querying the db and the likely hood of this seriously failing
|
||||
@ -87,7 +83,7 @@ async fn record_invite_usage(pool: &Pool, data: &InviteRow) -> Result<(), Error>
|
||||
}
|
||||
|
||||
pub async fn route_join_invite_code(pool: &Pool, response: &mut Response<Body>, params: Value) -> Result<(), Error> {
|
||||
// First check that the code is there
|
||||
// collect some things first
|
||||
if let Some(code) = params.get("code") {
|
||||
if let Some(row) = get_invite_by_code(pool, code.as_str()).await? {
|
||||
// since we have a row make sure the invite is valid
|
||||
@ -107,17 +103,42 @@ pub async fn route_join_invite_code(pool: &Pool, response: &mut Response<Body>,
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn create_invite(pool: &Pool, response: &mut Response<Body>) -> Result<(), Error> {
|
||||
let invite = InviteRow::new();
|
||||
async fn insert_new_invite(pool: &Pool, invite: &Invite) -> Result<(), Error>{
|
||||
let conn = pool.get_conn().await?;
|
||||
conn.prep_exec(r"INSERT INTO invites (id, expires, uses) VALUES (:id, :expires, :uses",
|
||||
mysql_async::params!{
|
||||
"id" => invite.id,
|
||||
"expires" => invite.expires,
|
||||
"uses" => invite.uses,
|
||||
}).await?;
|
||||
conn.prep_exec(
|
||||
"INSERT INTO invites (id, uses, expires)
|
||||
VALUES (:id, :uses, :expires)", params!{
|
||||
"id" => invite.id,
|
||||
"uses" => invite.uses,
|
||||
"expires" => invite.expires
|
||||
}).await?;
|
||||
|
||||
*response.body_mut() = Body::from(invite.as_json_str());
|
||||
*response.status_mut() = StatusCode::OK;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn create(pool: &Pool, response: &mut Response<Body>, params: Value) {
|
||||
/*
|
||||
* Creates a new invite
|
||||
*/
|
||||
|
||||
let use_count = match params.get("uses") {
|
||||
Some(val) => val.as_i64(),
|
||||
None => None
|
||||
};
|
||||
|
||||
let expires = match params.get("expires") {
|
||||
Some(val) => val.as_bool().unwrap(),
|
||||
None => true
|
||||
};
|
||||
|
||||
let invite = Invite {
|
||||
id: (Utc::now() + chrono::Duration::minutes(30)).timestamp(),
|
||||
uses: use_count,
|
||||
expires: expires
|
||||
};
|
||||
|
||||
match insert_new_invite(&pool, &invite).await {
|
||||
Ok(_) => *response.body_mut() = Body::from("yes"),
|
||||
Err(mysqle) => *response.status_mut() = StatusCode::BAD_REQUEST
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user