Compare commits
2 Commits
3aaaf39913
...
3711e7011c
Author | SHA1 | Date |
---|---|---|
Joey Hines | 3711e7011c | |
Joey Hines | 4c1d1cd6d0 |
|
@ -36,7 +36,7 @@ impl Command for AddItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_command(ctx: Arc<Context>, req: Self::Req, user: Option<Player>) -> Result<Self::Resp> {
|
fn run_command(ctx: Arc<Context>, req: &Self::Req, user: Option<Player>) -> Result<Self::Resp> {
|
||||||
let user = user.unwrap();
|
let user = user.unwrap();
|
||||||
|
|
||||||
let shops: Vec<LocationDb> = ctx
|
let shops: Vec<LocationDb> = ctx
|
||||||
|
|
|
@ -26,7 +26,7 @@ impl Command for AddLocation {
|
||||||
CommandLevel::REGISTERED
|
CommandLevel::REGISTERED
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_command(ctx: Arc<Context>, req: Self::Req, user: Option<Player>) -> Result<Self::Resp> {
|
fn run_command(ctx: Arc<Context>, req: &Self::Req, user: Option<Player>) -> Result<Self::Resp> {
|
||||||
let user = user.unwrap();
|
let user = user.unwrap();
|
||||||
|
|
||||||
let location = LocationDb::new(
|
let location = LocationDb::new(
|
||||||
|
|
|
@ -28,7 +28,7 @@ impl Command for AddToken {
|
||||||
CommandLevel::ADMIN
|
CommandLevel::ADMIN
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_command(ctx: Arc<Context>, req: Self::Req, _: Option<Player>) -> Result<Self::Resp> {
|
fn run_command(ctx: Arc<Context>, req: &Self::Req, _: Option<Player>) -> Result<Self::Resp> {
|
||||||
let mut token = Token::default();
|
let mut token = Token::default();
|
||||||
|
|
||||||
let secret: String = rand::thread_rng()
|
let secret: String = rand::thread_rng()
|
||||||
|
@ -39,8 +39,8 @@ impl Command for AddToken {
|
||||||
|
|
||||||
token.secret = secret;
|
token.secret = secret;
|
||||||
|
|
||||||
for permission in req.permissions {
|
for permission in &req.permissions {
|
||||||
token.set_permission(permission);
|
token.set_permission(*permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.db.insert(token).map_err(GeoffreyAPIError::from)
|
ctx.db.insert(token).map_err(GeoffreyAPIError::from)
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
use crate::commands::{Command, RequestType};
|
||||||
|
use crate::context::Context;
|
||||||
|
use crate::Result;
|
||||||
|
use geoffrey_db::helper::load_location;
|
||||||
|
use geoffrey_models::models::locations::{Location, LocationDb};
|
||||||
|
use geoffrey_models::models::parameters::delete_params::DeleteParams;
|
||||||
|
use geoffrey_models::models::player::Player;
|
||||||
|
use geoffrey_models::models::response::api_error::GeoffreyAPIError;
|
||||||
|
use geoffrey_models::models::CommandLevel;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
pub struct Delete {}
|
||||||
|
|
||||||
|
impl Command for Delete {
|
||||||
|
type Req = DeleteParams;
|
||||||
|
type Resp = Location;
|
||||||
|
|
||||||
|
fn command_name() -> String {
|
||||||
|
"delete".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn request_type() -> RequestType {
|
||||||
|
RequestType::POST
|
||||||
|
}
|
||||||
|
|
||||||
|
fn command_level() -> CommandLevel {
|
||||||
|
CommandLevel::REGISTERED
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_command(ctx: Arc<Context>, req: &Self::Req, user: Option<Player>) -> Result<Self::Resp> {
|
||||||
|
let user = user.unwrap();
|
||||||
|
let filter = regex::Regex::new(format!(r"(?i)^{}$", req.location).as_str()).unwrap();
|
||||||
|
|
||||||
|
let location: LocationDb = ctx
|
||||||
|
.db
|
||||||
|
.filter(|_, loc: &LocationDb| {
|
||||||
|
filter.is_match(&loc.name) && loc.owners().contains(&user.id.unwrap())
|
||||||
|
})?
|
||||||
|
.next()
|
||||||
|
.ok_or(GeoffreyAPIError::EntryNotFound)?;
|
||||||
|
|
||||||
|
let location = load_location(&ctx.db, &location).map_err(GeoffreyAPIError::from)?;
|
||||||
|
|
||||||
|
ctx.db.remove::<LocationDb>(location.id)?;
|
||||||
|
|
||||||
|
Ok(location)
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,7 +27,7 @@ impl Command for FindCommand {
|
||||||
CommandLevel::ALL
|
CommandLevel::ALL
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_command(ctx: Arc<Context>, req: Self::Req, _: Option<Player>) -> Result<Self::Resp> {
|
fn run_command(ctx: Arc<Context>, req: &Self::Req, _: Option<Player>) -> Result<Self::Resp> {
|
||||||
let query = req.query.to_lowercase();
|
let query = req.query.to_lowercase();
|
||||||
let players: Vec<u64> = ctx
|
let players: Vec<u64> = ctx
|
||||||
.db
|
.db
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::commands::add_item::AddItem;
|
use crate::commands::add_item::AddItem;
|
||||||
use crate::commands::add_location::AddLocation;
|
use crate::commands::add_location::AddLocation;
|
||||||
|
use crate::commands::delete::Delete;
|
||||||
use crate::commands::find::FindCommand;
|
use crate::commands::find::FindCommand;
|
||||||
use crate::commands::register::Register;
|
use crate::commands::register::Register;
|
||||||
use crate::commands::selling::Selling;
|
use crate::commands::selling::Selling;
|
||||||
|
@ -7,7 +8,7 @@ use crate::commands::set_portal::SetPortal;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::helper::{get_player_from_req, get_token_from_req};
|
use crate::helper::{get_player_from_req, get_token_from_req};
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use geoffrey_models::models::parameters::CommandRequest;
|
use geoffrey_models::models::parameters::{CommandRequest, GeoffreyParam};
|
||||||
use geoffrey_models::models::player::Player;
|
use geoffrey_models::models::player::Player;
|
||||||
use geoffrey_models::models::response::api_error::GeoffreyAPIError;
|
use geoffrey_models::models::response::api_error::GeoffreyAPIError;
|
||||||
use geoffrey_models::models::response::APIResponse;
|
use geoffrey_models::models::response::APIResponse;
|
||||||
|
@ -23,6 +24,7 @@ use warp::Filter;
|
||||||
pub mod add_item;
|
pub mod add_item;
|
||||||
pub mod add_location;
|
pub mod add_location;
|
||||||
pub mod add_token;
|
pub mod add_token;
|
||||||
|
pub mod delete;
|
||||||
pub mod find;
|
pub mod find;
|
||||||
pub mod register;
|
pub mod register;
|
||||||
pub mod selling;
|
pub mod selling;
|
||||||
|
@ -36,13 +38,13 @@ pub enum RequestType {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Command {
|
pub trait Command {
|
||||||
type Req: CommandRequest;
|
type Req: GeoffreyParam + 'static;
|
||||||
type Resp: Serialize + DeserializeOwned + Send;
|
type Resp: Serialize + DeserializeOwned + Send + Debug;
|
||||||
|
|
||||||
fn command_name() -> String;
|
fn command_name() -> String;
|
||||||
fn request_type() -> RequestType;
|
fn request_type() -> RequestType;
|
||||||
fn command_level() -> CommandLevel;
|
fn command_level() -> CommandLevel;
|
||||||
fn run_command(ctx: Arc<Context>, req: Self::Req, user: Option<Player>) -> Result<Self::Resp>;
|
fn run_command(ctx: Arc<Context>, req: &Self::Req, user: Option<Player>) -> Result<Self::Resp>;
|
||||||
|
|
||||||
fn validate_parameters(_: &Self::Req) -> Result<()> {
|
fn validate_parameters(_: &Self::Req) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -75,17 +77,20 @@ pub trait Command {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_command<T: Command>(ctx: Arc<Context>, req: T::Req) -> Result<T::Resp> {
|
pub fn handle_command<T: Command>(
|
||||||
|
ctx: Arc<Context>,
|
||||||
|
req: CommandRequest<T::Req>,
|
||||||
|
) -> Result<T::Resp> {
|
||||||
log::info!("Running command {}", T::command_name());
|
log::info!("Running command {}", T::command_name());
|
||||||
log::debug!("Request: {:?}", req);
|
log::debug!("Request: {:?}", req);
|
||||||
|
|
||||||
let user = get_player_from_req(&ctx.db, &req)?;
|
let user = get_player_from_req::<T::Req>(&ctx.db, &req)?;
|
||||||
let token = get_token_from_req(&ctx.db, &req)?;
|
let token = get_token_from_req::<T::Req>(&ctx.db, &req)?;
|
||||||
|
|
||||||
match T::user_is_authorized(&token, &user) {
|
match T::user_is_authorized(&token, &user) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
T::validate_parameters(&req)?;
|
T::validate_parameters(&req.params)?;
|
||||||
T::run_command(ctx, req, user)
|
T::run_command(ctx, &req.params, user)
|
||||||
}
|
}
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
}
|
}
|
||||||
|
@ -96,7 +101,7 @@ pub fn create_command_filter<T: Command>(ctx: Arc<Context>) -> BoxedFilter<(impl
|
||||||
let filter = warp::path(T::command_name())
|
let filter = warp::path(T::command_name())
|
||||||
.and(warp::any().map(move || ctx.clone()))
|
.and(warp::any().map(move || ctx.clone()))
|
||||||
.and(warp::body::json())
|
.and(warp::body::json())
|
||||||
.map(|ctx: Arc<Context>, req: T::Req| {
|
.map(|ctx: Arc<Context>, req: CommandRequest<T::Req>| {
|
||||||
let reply = handle_command::<T>(ctx, req);
|
let reply = handle_command::<T>(ctx, req);
|
||||||
if let Ok(reply) = reply {
|
if let Ok(reply) = reply {
|
||||||
log::debug!("Successfully processed command");
|
log::debug!("Successfully processed command");
|
||||||
|
@ -125,6 +130,7 @@ pub fn command_filter(
|
||||||
.or(create_command_filter::<Register>(ctx.clone()))
|
.or(create_command_filter::<Register>(ctx.clone()))
|
||||||
.or(create_command_filter::<Selling>(ctx.clone()))
|
.or(create_command_filter::<Selling>(ctx.clone()))
|
||||||
.or(create_command_filter::<AddItem>(ctx.clone()))
|
.or(create_command_filter::<AddItem>(ctx.clone()))
|
||||||
|
.or(create_command_filter::<Delete>(ctx.clone()))
|
||||||
.or(create_command_filter::<SetPortal>(ctx)),
|
.or(create_command_filter::<SetPortal>(ctx)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,10 +26,10 @@ impl Command for Register {
|
||||||
|
|
||||||
fn run_command(
|
fn run_command(
|
||||||
ctx: Arc<Context>,
|
ctx: Arc<Context>,
|
||||||
req: Self::Req,
|
req: &Self::Req,
|
||||||
_: Option<Player>,
|
_: Option<Player>,
|
||||||
) -> crate::Result<Self::Resp> {
|
) -> crate::Result<Self::Resp> {
|
||||||
let player = Player::new(req.username.as_str(), req.new_user_id);
|
let player = Player::new(req.username.as_str(), req.user_id.clone());
|
||||||
|
|
||||||
ctx.db.insert(player).map_err(GeoffreyAPIError::from)
|
ctx.db.insert(player).map_err(GeoffreyAPIError::from)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ impl Command for Selling {
|
||||||
CommandLevel::ALL
|
CommandLevel::ALL
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_command(ctx: Arc<Context>, req: Self::Req, _: Option<Player>) -> Result<Self::Resp> {
|
fn run_command(ctx: Arc<Context>, req: &Self::Req, _: Option<Player>) -> Result<Self::Resp> {
|
||||||
let mut listings: Vec<SellingListing> = ctx
|
let mut listings: Vec<SellingListing> = ctx
|
||||||
.db
|
.db
|
||||||
.filter(|_, loc: &LocationDb| {
|
.filter(|_, loc: &LocationDb| {
|
||||||
|
@ -69,7 +69,7 @@ impl Command for Selling {
|
||||||
.flatten()
|
.flatten()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let sort = req.sort.unwrap_or(ItemSort::Restock);
|
let sort = req.sort.as_ref().unwrap_or(&ItemSort::Restock);
|
||||||
|
|
||||||
match sort {
|
match sort {
|
||||||
ItemSort::Price => {
|
ItemSort::Price => {
|
||||||
|
@ -80,16 +80,16 @@ impl Command for Selling {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let ordering = if let Some(order) = req.order {
|
let ordering = if let Some(order) = &req.order {
|
||||||
order
|
order
|
||||||
} else {
|
} else {
|
||||||
match sort {
|
match sort {
|
||||||
ItemSort::Price => Order::Low,
|
ItemSort::Price => &Order::Low,
|
||||||
ItemSort::Restock => Order::High,
|
ItemSort::Restock => &Order::High,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if ordering == Order::High {
|
if *ordering == Order::High {
|
||||||
listings.reverse();
|
listings.reverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ impl Command for SetPortal {
|
||||||
CommandLevel::REGISTERED
|
CommandLevel::REGISTERED
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_command(ctx: Arc<Context>, req: Self::Req, user: Option<Player>) -> Result<Self::Resp> {
|
fn run_command(ctx: Arc<Context>, req: &Self::Req, user: Option<Player>) -> Result<Self::Resp> {
|
||||||
let user = user.unwrap();
|
let user = user.unwrap();
|
||||||
let filter = regex::Regex::new(format!(r"(?i)^{}$", req.loc_name).as_str()).unwrap();
|
let filter = regex::Regex::new(format!(r"(?i)^{}$", req.loc_name).as_str()).unwrap();
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ impl Command for SetPortal {
|
||||||
.next()
|
.next()
|
||||||
.ok_or(GeoffreyAPIError::EntryNotFound)?;
|
.ok_or(GeoffreyAPIError::EntryNotFound)?;
|
||||||
|
|
||||||
location.portal = Some(req.portal);
|
location.portal = Some(req.portal.clone());
|
||||||
|
|
||||||
let location = ctx.db.insert(location)?;
|
let location = ctx.db.insert(location)?;
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,27 @@
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use geoffrey_db::database::Database;
|
use geoffrey_db::database::Database;
|
||||||
use geoffrey_models::models::parameters::CommandRequest;
|
use geoffrey_models::models::parameters::{CommandRequest, GeoffreyParam};
|
||||||
use geoffrey_models::models::player::Player;
|
use geoffrey_models::models::player::Player;
|
||||||
use geoffrey_models::models::token::Token;
|
use geoffrey_models::models::token::Token;
|
||||||
|
|
||||||
pub fn get_player_from_req<T: CommandRequest>(db: &Database, req: &T) -> Result<Option<Player>> {
|
pub fn get_player_from_req<T: GeoffreyParam>(
|
||||||
if let Some(user_id) = req.user_id() {
|
db: &Database,
|
||||||
|
req: &CommandRequest<T>,
|
||||||
|
) -> Result<Option<Player>> {
|
||||||
|
if let Some(user_id) = &req.user_id {
|
||||||
Ok(db
|
Ok(db
|
||||||
.filter(|_, player: &Player| player.has_user_id(&user_id))?
|
.filter(|_, player: &Player| player.has_user_id(user_id))?
|
||||||
.next())
|
.next())
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_token_from_req<T: CommandRequest>(db: &Database, req: &T) -> Result<Option<Token>> {
|
pub fn get_token_from_req<T: GeoffreyParam>(
|
||||||
|
db: &Database,
|
||||||
|
req: &CommandRequest<T>,
|
||||||
|
) -> Result<Option<Token>> {
|
||||||
Ok(db
|
Ok(db
|
||||||
.filter(|_, token: &Token| token.secret == req.token())?
|
.filter(|_, token: &Token| token.secret == req.token)?
|
||||||
.next())
|
.next())
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,14 +70,7 @@ async fn run_server(ctx: Arc<Context>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_token(ctx: Arc<Context>, perms: Vec<Permissions>) {
|
fn create_token(ctx: Arc<Context>, perms: Vec<Permissions>) {
|
||||||
match AddToken::run_command(
|
match AddToken::run_command(ctx, &AddTokenParams { permissions: perms }, None) {
|
||||||
ctx,
|
|
||||||
AddTokenParams {
|
|
||||||
token: "".to_string(),
|
|
||||||
permissions: perms,
|
|
||||||
},
|
|
||||||
None,
|
|
||||||
) {
|
|
||||||
Ok(token) => {
|
Ok(token) => {
|
||||||
// Don't log this to keep tokens out of the log
|
// Don't log this to keep tokens out of the log
|
||||||
println!("Added admin token with secret: {}", token.secret)
|
println!("Added admin token with secret: {}", token.secret)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Debug, Display, Formatter};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use reqwest::Error;
|
use reqwest::Error;
|
||||||
|
@ -7,7 +7,7 @@ use serde::Serialize;
|
||||||
use serenity::model::interactions::application_command::ApplicationCommandInteraction;
|
use serenity::model::interactions::application_command::ApplicationCommandInteraction;
|
||||||
use serenity::Error as SerenityError;
|
use serenity::Error as SerenityError;
|
||||||
|
|
||||||
use geoffrey_models::models::parameters::CommandRequest;
|
use geoffrey_models::models::parameters::{CommandRequest, GeoffreyParam};
|
||||||
use geoffrey_models::models::player::UserID;
|
use geoffrey_models::models::player::UserID;
|
||||||
use geoffrey_models::models::response::api_error::GeoffreyAPIError;
|
use geoffrey_models::models::response::api_error::GeoffreyAPIError;
|
||||||
use geoffrey_models::models::response::APIResponse;
|
use geoffrey_models::models::response::APIResponse;
|
||||||
|
@ -74,8 +74,8 @@ impl From<reqwest::Error> for CommandError {
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait BotCommand: Send + 'static {
|
pub trait BotCommand: Send + 'static {
|
||||||
type ApiParams: CommandRequest;
|
type ApiParams: GeoffreyParam;
|
||||||
type ApiResp: Serialize + DeserializeOwned + Send;
|
type ApiResp: Serialize + DeserializeOwned + Send + Debug;
|
||||||
|
|
||||||
fn command_name() -> String;
|
fn command_name() -> String;
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ pub trait BotCommand: Send + 'static {
|
||||||
|
|
||||||
async fn run_api_query(
|
async fn run_api_query(
|
||||||
ctx: GeoffreyContext,
|
ctx: GeoffreyContext,
|
||||||
params: Self::ApiParams,
|
params: CommandRequest<Self::ApiParams>,
|
||||||
) -> Result<APIResponse<Self::ApiResp>, CommandError> {
|
) -> Result<APIResponse<Self::ApiResp>, CommandError> {
|
||||||
let command_url = Self::command_url(&ctx.cfg.api.base_url);
|
let command_url = Self::command_url(&ctx.cfg.api.base_url);
|
||||||
let resp: APIResponse<Self::ApiResp> = ctx
|
let resp: APIResponse<Self::ApiResp> = ctx
|
||||||
|
@ -154,7 +154,7 @@ pub trait BotCommand: Send + 'static {
|
||||||
user_id: UserID,
|
user_id: UserID,
|
||||||
command_interact: ApplicationCommandInteraction,
|
command_interact: ApplicationCommandInteraction,
|
||||||
) -> Result<String, CommandError> {
|
) -> Result<String, CommandError> {
|
||||||
let mut args = Self::process_arguments(command_interact).await?;
|
let args = Self::process_arguments(command_interact).await?;
|
||||||
|
|
||||||
log::info!(
|
log::info!(
|
||||||
"Running command {}, with args {:?}",
|
"Running command {}, with args {:?}",
|
||||||
|
@ -162,10 +162,13 @@ pub trait BotCommand: Send + 'static {
|
||||||
args
|
args
|
||||||
);
|
);
|
||||||
|
|
||||||
args.set_token(ctx.cfg.api.token.clone());
|
let request = CommandRequest {
|
||||||
args.set_user_id(user_id);
|
token: ctx.cfg.api.token.clone(),
|
||||||
|
user_id: Some(user_id),
|
||||||
|
params: args,
|
||||||
|
};
|
||||||
|
|
||||||
let resp = Self::run_api_query(ctx, args).await?;
|
let resp = Self::run_api_query(ctx, request).await?;
|
||||||
|
|
||||||
match resp {
|
match resp {
|
||||||
APIResponse::Response(resp) => Ok(Self::build_response(resp)),
|
APIResponse::Response(resp) => Ok(Self::build_response(resp)),
|
||||||
|
|
|
@ -2,12 +2,22 @@ use crate::error::{GeoffreyDBError, Result};
|
||||||
use crate::migration::do_migration;
|
use crate::migration::do_migration;
|
||||||
use geoffrey_models::models::db_metadata::DBMetadata;
|
use geoffrey_models::models::db_metadata::DBMetadata;
|
||||||
use geoffrey_models::GeoffreyDatabaseModel;
|
use geoffrey_models::GeoffreyDatabaseModel;
|
||||||
|
use sled::IVec;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
const DB_VERSION: u64 = 3;
|
const DB_VERSION: u64 = 3;
|
||||||
const DB_METADATA_ID: u64 = 1;
|
const DB_METADATA_ID: u64 = 1;
|
||||||
|
|
||||||
|
fn option_bytes_to_model<T: GeoffreyDatabaseModel>(bytes: Option<IVec>, id: u64) -> Result<T> {
|
||||||
|
if let Some(bytes) = bytes {
|
||||||
|
Ok(T::try_from_bytes(&bytes)?)
|
||||||
|
} else {
|
||||||
|
log::debug!("{} of id {} was not found in the database", T::tree(), id);
|
||||||
|
Err(GeoffreyDBError::NotFound)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Database {
|
pub struct Database {
|
||||||
pub(crate) db: sled::Db,
|
pub(crate) db: sled::Db,
|
||||||
}
|
}
|
||||||
|
@ -66,14 +76,7 @@ impl Database {
|
||||||
T: GeoffreyDatabaseModel,
|
T: GeoffreyDatabaseModel,
|
||||||
{
|
{
|
||||||
let tree = self.get_tree::<T>()?;
|
let tree = self.get_tree::<T>()?;
|
||||||
let id_bytes = id.to_be_bytes();
|
option_bytes_to_model(tree.get(id.to_be_bytes())?, id)
|
||||||
|
|
||||||
if let Some(bytes) = tree.get(id_bytes)? {
|
|
||||||
Ok(T::try_from_bytes(&bytes)?)
|
|
||||||
} else {
|
|
||||||
log::debug!("{} of id {} was not found in the database", T::tree(), id);
|
|
||||||
Err(GeoffreyDBError::NotFound)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_tree<T>(&self) -> Result<()>
|
pub fn clear_tree<T>(&self) -> Result<()>
|
||||||
|
@ -110,6 +113,14 @@ impl Database {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn remove<T>(&self, id: u64) -> Result<T>
|
||||||
|
where
|
||||||
|
T: GeoffreyDatabaseModel,
|
||||||
|
{
|
||||||
|
let tree = self.db.open_tree(T::tree())?;
|
||||||
|
option_bytes_to_model(tree.remove(id.to_be_bytes())?, id)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn tree_iter<T>(&self) -> Result<sled::Iter>
|
pub fn tree_iter<T>(&self) -> Result<sled::Iter>
|
||||||
where
|
where
|
||||||
T: GeoffreyDatabaseModel,
|
T: GeoffreyDatabaseModel,
|
||||||
|
@ -228,6 +239,21 @@ mod tests {
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_remove() {
|
||||||
|
let _lock = LOCK.lock().unwrap();
|
||||||
|
cleanup();
|
||||||
|
let player = Player::new("CoolZero123", UserID::DiscordUUID { discord_uuid: 0u64 });
|
||||||
|
|
||||||
|
let p2 = DB.insert::<Player>(player.clone()).unwrap();
|
||||||
|
|
||||||
|
let p3 = DB.remove::<Player>(p2.id.unwrap()).unwrap();
|
||||||
|
|
||||||
|
assert!(DB.get::<Player>(p3.id.unwrap()).is_err());
|
||||||
|
assert_eq!(p3.id.unwrap(), p2.id.unwrap());
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_insert_speed() {
|
fn test_insert_speed() {
|
||||||
let _lock = LOCK.lock().unwrap();
|
let _lock = LOCK.lock().unwrap();
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
use crate::models::parameters::CommandRequest;
|
use crate::models::parameters::GeoffreyParam;
|
||||||
use crate::models::player::UserID;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct AddItemParams {
|
pub struct AddItemParams {
|
||||||
pub token: String,
|
|
||||||
pub user_id: UserID,
|
|
||||||
pub item_name: String,
|
pub item_name: String,
|
||||||
pub price: u32,
|
pub price: u32,
|
||||||
pub quantity: u32,
|
pub quantity: u32,
|
||||||
|
@ -15,8 +12,6 @@ pub struct AddItemParams {
|
||||||
impl AddItemParams {
|
impl AddItemParams {
|
||||||
pub fn new(item_name: String, price: u32, quantity: u32, shop: String) -> Self {
|
pub fn new(item_name: String, price: u32, quantity: u32, shop: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
token: Default::default(),
|
|
||||||
user_id: Default::default(),
|
|
||||||
item_name,
|
item_name,
|
||||||
price,
|
price,
|
||||||
quantity,
|
quantity,
|
||||||
|
@ -25,20 +20,4 @@ impl AddItemParams {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommandRequest for AddItemParams {
|
impl GeoffreyParam for AddItemParams {}
|
||||||
fn token(&self) -> String {
|
|
||||||
self.token.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn user_id(&self) -> Option<UserID> {
|
|
||||||
Some(self.user_id.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_token(&mut self, token: String) {
|
|
||||||
self.token = token;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_user_id(&mut self, user_id: UserID) {
|
|
||||||
self.user_id = user_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
use crate::models::locations::LocationType;
|
use crate::models::locations::LocationType;
|
||||||
use crate::models::parameters::CommandRequest;
|
use crate::models::parameters::GeoffreyParam;
|
||||||
use crate::models::player::UserID;
|
|
||||||
use crate::models::{Portal, Position};
|
use crate::models::{Portal, Position};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct AddLocationParams {
|
pub struct AddLocationParams {
|
||||||
pub token: String,
|
|
||||||
pub user_id: UserID,
|
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub position: Position,
|
pub position: Position,
|
||||||
pub loc_type: LocationType,
|
pub loc_type: LocationType,
|
||||||
|
@ -22,8 +19,6 @@ impl AddLocationParams {
|
||||||
portal: Option<Portal>,
|
portal: Option<Portal>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
token: Default::default(),
|
|
||||||
user_id: Default::default(),
|
|
||||||
name,
|
name,
|
||||||
position,
|
position,
|
||||||
loc_type,
|
loc_type,
|
||||||
|
@ -32,20 +27,4 @@ impl AddLocationParams {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommandRequest for AddLocationParams {
|
impl GeoffreyParam for AddLocationParams {}
|
||||||
fn token(&self) -> String {
|
|
||||||
self.token.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn user_id(&self) -> Option<UserID> {
|
|
||||||
Some(self.user_id.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_user_id(&mut self, user_id: UserID) {
|
|
||||||
self.user_id = user_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_token(&mut self, token: String) {
|
|
||||||
self.token = token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,28 +1,16 @@
|
||||||
use crate::models::parameters::CommandRequest;
|
use crate::models::parameters::GeoffreyParam;
|
||||||
use crate::models::token::Permissions;
|
use crate::models::token::Permissions;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct AddTokenParams {
|
pub struct AddTokenParams {
|
||||||
pub token: String,
|
|
||||||
pub permissions: Vec<Permissions>,
|
pub permissions: Vec<Permissions>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AddTokenParams {
|
impl AddTokenParams {
|
||||||
fn new(permissions: Vec<Permissions>) -> Self {
|
fn new(permissions: Vec<Permissions>) -> Self {
|
||||||
Self {
|
Self { permissions }
|
||||||
token: Default::default(),
|
|
||||||
permissions,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommandRequest for AddTokenParams {
|
impl GeoffreyParam for AddTokenParams {}
|
||||||
fn token(&self) -> String {
|
|
||||||
self.token.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_token(&mut self, token: String) {
|
|
||||||
self.token = token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
use crate::models::parameters::GeoffreyParam;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct DeleteParams {
|
||||||
|
pub location: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DeleteParams {
|
||||||
|
pub fn new(location: String) -> Self {
|
||||||
|
Self { location }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GeoffreyParam for DeleteParams {}
|
|
@ -1,27 +1,15 @@
|
||||||
use crate::models::parameters::CommandRequest;
|
use crate::models::parameters::GeoffreyParam;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct FindParams {
|
pub struct FindParams {
|
||||||
pub token: String,
|
|
||||||
pub query: String,
|
pub query: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FindParams {
|
impl FindParams {
|
||||||
pub fn new(query: String) -> Self {
|
pub fn new(query: String) -> Self {
|
||||||
Self {
|
Self { query }
|
||||||
token: Default::default(),
|
|
||||||
query,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommandRequest for FindParams {
|
impl GeoffreyParam for FindParams {}
|
||||||
fn token(&self) -> String {
|
|
||||||
self.token.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_token(&mut self, token: String) {
|
|
||||||
self.token = token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,43 +1,22 @@
|
||||||
pub mod add_item_params;
|
pub mod add_item_params;
|
||||||
pub mod add_location_params;
|
pub mod add_location_params;
|
||||||
pub mod add_token_params;
|
pub mod add_token_params;
|
||||||
|
pub mod delete_params;
|
||||||
pub mod find_params;
|
pub mod find_params;
|
||||||
pub mod register_params;
|
pub mod register_params;
|
||||||
pub mod selling_params;
|
pub mod selling_params;
|
||||||
pub mod set_portal_params;
|
pub mod set_portal_params;
|
||||||
|
|
||||||
use crate::models::player::{Player, UserID};
|
use crate::models::player::UserID;
|
||||||
use crate::models::token::{Permissions, Token};
|
|
||||||
use crate::models::CommandLevel;
|
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use serde::Serialize;
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
pub trait CommandRequest:
|
pub trait GeoffreyParam: Serialize + DeserializeOwned + Debug + Clone + Send + Sync {}
|
||||||
Serialize + DeserializeOwned + Debug + Clone + Send + 'static + Sync
|
|
||||||
{
|
|
||||||
fn token(&self) -> String;
|
|
||||||
fn user_id(&self) -> Option<UserID> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_token(&mut self, token: String);
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
fn set_user_id(&mut self, _: UserID) {}
|
pub struct CommandRequest<T> {
|
||||||
|
pub token: String,
|
||||||
fn check_permission(
|
pub user_id: Option<UserID>,
|
||||||
&self,
|
pub params: T,
|
||||||
player: &Player,
|
|
||||||
command_level: &CommandLevel,
|
|
||||||
token: &Token,
|
|
||||||
) -> bool {
|
|
||||||
if player.auth_level >= *command_level {
|
|
||||||
if *command_level == CommandLevel::ADMIN {
|
|
||||||
token.check_permission(Permissions::Admin)
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +1,17 @@
|
||||||
use crate::models::parameters::CommandRequest;
|
use crate::models::parameters::GeoffreyParam;
|
||||||
use crate::models::player::UserID;
|
use crate::models::player::UserID;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct RegisterParameters {
|
pub struct RegisterParameters {
|
||||||
pub token: String,
|
|
||||||
pub new_user_id: UserID,
|
|
||||||
pub username: String,
|
pub username: String,
|
||||||
|
pub user_id: UserID,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RegisterParameters {
|
impl RegisterParameters {
|
||||||
pub fn new(username: String) -> Self {
|
pub fn new(username: String, user_id: UserID) -> Self {
|
||||||
RegisterParameters {
|
RegisterParameters { username, user_id }
|
||||||
token: Default::default(),
|
|
||||||
new_user_id: Default::default(),
|
|
||||||
username,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommandRequest for RegisterParameters {
|
impl GeoffreyParam for RegisterParameters {}
|
||||||
fn token(&self) -> String {
|
|
||||||
self.token.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_user_id(&mut self, user_id: UserID) {
|
|
||||||
self.new_user_id = user_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_token(&mut self, token: String) {
|
|
||||||
self.token = token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::models::parameters::CommandRequest;
|
use crate::models::parameters::GeoffreyParam;
|
||||||
use crate::models::player::UserID;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
@ -35,7 +34,7 @@ impl FromStr for ItemSort {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
|
||||||
pub enum Order {
|
pub enum Order {
|
||||||
High,
|
High,
|
||||||
Low,
|
Low,
|
||||||
|
@ -68,7 +67,6 @@ impl FromStr for Order {
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct SellingParams {
|
pub struct SellingParams {
|
||||||
pub token: String,
|
|
||||||
pub query: String,
|
pub query: String,
|
||||||
pub sort: Option<ItemSort>,
|
pub sort: Option<ItemSort>,
|
||||||
pub order: Option<Order>,
|
pub order: Option<Order>,
|
||||||
|
@ -76,25 +74,8 @@ pub struct SellingParams {
|
||||||
|
|
||||||
impl SellingParams {
|
impl SellingParams {
|
||||||
pub fn new(query: String, sort: Option<ItemSort>, order: Option<Order>) -> Self {
|
pub fn new(query: String, sort: Option<ItemSort>, order: Option<Order>) -> Self {
|
||||||
Self {
|
Self { query, sort, order }
|
||||||
token: Default::default(),
|
|
||||||
query,
|
|
||||||
sort,
|
|
||||||
order,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommandRequest for SellingParams {
|
impl GeoffreyParam for SellingParams {}
|
||||||
fn token(&self) -> String {
|
|
||||||
self.token.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn user_id(&self) -> Option<UserID> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_token(&mut self, token: String) {
|
|
||||||
self.token = token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,41 +1,17 @@
|
||||||
use crate::models::parameters::CommandRequest;
|
use crate::models::parameters::GeoffreyParam;
|
||||||
use crate::models::player::UserID;
|
|
||||||
use crate::models::Portal;
|
use crate::models::Portal;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct SetPortalParams {
|
pub struct SetPortalParams {
|
||||||
pub token: String,
|
|
||||||
pub user_id: UserID,
|
|
||||||
pub loc_name: String,
|
pub loc_name: String,
|
||||||
pub portal: Portal,
|
pub portal: Portal,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SetPortalParams {
|
impl SetPortalParams {
|
||||||
pub fn new(loc_name: String, portal: Portal) -> Self {
|
pub fn new(loc_name: String, portal: Portal) -> Self {
|
||||||
Self {
|
Self { loc_name, portal }
|
||||||
token: Default::default(),
|
|
||||||
user_id: Default::default(),
|
|
||||||
loc_name,
|
|
||||||
portal,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommandRequest for SetPortalParams {
|
impl GeoffreyParam for SetPortalParams {}
|
||||||
fn token(&self) -> String {
|
|
||||||
self.token.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn user_id(&self) -> Option<UserID> {
|
|
||||||
Some(self.user_id.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_user_id(&mut self, user_id: UserID) {
|
|
||||||
self.user_id = user_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_token(&mut self, token: String) {
|
|
||||||
self.token = token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialOrd, PartialEq, Copy)]
|
||||||
pub enum Permissions {
|
pub enum Permissions {
|
||||||
ModelGet = 0,
|
ModelGet = 0,
|
||||||
ModelPost,
|
ModelPost,
|
||||||
|
|
Loading…
Reference in New Issue