forked from projectmoon/tenebrous-dicebot
Localize error enums to modules, better DB error reportng.
This commit is contained in:
parent
6cdc465a2e
commit
4234263ee4
|
@ -1,12 +1,23 @@
|
||||||
use crate::cofd::dice::DicePool;
|
use crate::cofd::dice::DicePool;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
|
use crate::db::DataError;
|
||||||
use crate::dice::ElementExpression;
|
use crate::dice::ElementExpression;
|
||||||
use crate::error::{BotError, CommandError};
|
use crate::error::BotError;
|
||||||
use crate::help::HelpTopic;
|
use crate::help::HelpTopic;
|
||||||
use crate::roll::Roll;
|
use crate::roll::Roll;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum CommandError {
|
||||||
|
#[error("invalid command: {0}")]
|
||||||
|
InvalidCommand(String),
|
||||||
|
|
||||||
|
#[error("ignored command")]
|
||||||
|
IgnoredCommand,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Execution {
|
pub struct Execution {
|
||||||
plain: String,
|
plain: String,
|
||||||
html: String,
|
html: String,
|
||||||
|
@ -104,8 +115,8 @@ impl Command for GetVariableCommand {
|
||||||
fn execute(&self, ctx: &Context) -> Execution {
|
fn execute(&self, ctx: &Context) -> Execution {
|
||||||
let name = &self.0;
|
let name = &self.0;
|
||||||
let value = match ctx.db.get_user_variable(ctx.room_id, ctx.username, name) {
|
let value = match ctx.db.get_user_variable(ctx.room_id, ctx.username, name) {
|
||||||
Ok(Some(num)) => format!("{} = {}", name, num),
|
Ok(num) => format!("{} = {}", name, num),
|
||||||
Ok(None) => format!("{} is not set", name),
|
Err(DataError::KeyDoesNotExist(_)) => format!("{} is not set", name),
|
||||||
Err(e) => format!("error getting {}: {}", name, e),
|
Err(e) => format!("error getting {}: {}", name, e),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -125,16 +136,17 @@ impl Command for SetVariableCommand {
|
||||||
fn execute(&self, ctx: &Context) -> Execution {
|
fn execute(&self, ctx: &Context) -> Execution {
|
||||||
let name = &self.0;
|
let name = &self.0;
|
||||||
let value = self.1;
|
let value = self.1;
|
||||||
let value = match ctx
|
let result = ctx
|
||||||
.db
|
.db
|
||||||
.set_user_variable(ctx.room_id, ctx.username, name, value)
|
.set_user_variable(ctx.room_id, ctx.username, name, value);
|
||||||
{
|
|
||||||
|
let content = match result {
|
||||||
Ok(_) => format!("{} = {}", name, value),
|
Ok(_) => format!("{} = {}", name, value),
|
||||||
Err(e) => format!("error setting {}: {}", name, e),
|
Err(e) => format!("error setting {}: {}", name, e),
|
||||||
};
|
};
|
||||||
|
|
||||||
let plain = format!("Set Variable: {}", value);
|
let plain = format!("Set Variable: {}", content);
|
||||||
let html = format!("<p><strong>Set Variable:</strong> {}", value);
|
let html = format!("<p><strong>Set Variable:</strong> {}", content);
|
||||||
Execution { plain, html }
|
Execution { plain, html }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,6 +162,7 @@ impl Command for DeleteVariableCommand {
|
||||||
let name = &self.0;
|
let name = &self.0;
|
||||||
let value = match ctx.db.delete_user_variable(ctx.room_id, ctx.username, name) {
|
let value = match ctx.db.delete_user_variable(ctx.room_id, ctx.username, name) {
|
||||||
Ok(()) => format!("{} now unset", name),
|
Ok(()) => format!("{} now unset", name),
|
||||||
|
Err(DataError::KeyDoesNotExist(_)) => format!("{} is not currently set", name),
|
||||||
Err(e) => format!("error deleting {}: {}", name, e),
|
Err(e) => format!("error deleting {}: {}", name, e),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,17 @@
|
||||||
use crate::error::ConfigError;
|
|
||||||
use serde::{self, Deserialize, Serialize};
|
use serde::{self, Deserialize, Serialize};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum ConfigError {
|
||||||
|
#[error("i/o error: {0}")]
|
||||||
|
IoError(#[from] std::io::Error),
|
||||||
|
|
||||||
|
#[error("toml parsing error: {0}")]
|
||||||
|
TomlParsingError(#[from] toml::de::Error),
|
||||||
|
}
|
||||||
|
|
||||||
pub fn read_config<P: Into<PathBuf>>(config_path: P) -> Result<Config, ConfigError> {
|
pub fn read_config<P: Into<PathBuf>>(config_path: P) -> Result<Config, ConfigError> {
|
||||||
let config_path = config_path.into();
|
let config_path = config_path.into();
|
||||||
|
|
17
src/db.rs
17
src/db.rs
|
@ -36,17 +36,17 @@ impl Database {
|
||||||
room_id: &str,
|
room_id: &str,
|
||||||
username: &str,
|
username: &str,
|
||||||
variable_name: &str,
|
variable_name: &str,
|
||||||
) -> Result<Option<i32>, DataError> {
|
) -> Result<i32, DataError> {
|
||||||
let key = to_key(room_id, username, variable_name);
|
let key = to_key(room_id, username, variable_name);
|
||||||
|
|
||||||
if let Some(raw_value) = self.db.get(key)? {
|
if let Some(raw_value) = self.db.get(&key)? {
|
||||||
let layout: LayoutVerified<&[u8], I32<LittleEndian>> =
|
let layout: LayoutVerified<&[u8], I32<LittleEndian>> =
|
||||||
LayoutVerified::new_unaligned(&*raw_value).expect("bytes do not fit schema");
|
LayoutVerified::new_unaligned(&*raw_value).expect("bytes do not fit schema");
|
||||||
|
|
||||||
let value: I32<LittleEndian> = *layout;
|
let value: I32<LittleEndian> = *layout;
|
||||||
Ok(Some(value.get()))
|
Ok(value.get())
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Err(DataError::KeyDoesNotExist(String::from_utf8(key).unwrap()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ impl Database {
|
||||||
) -> Result<(), DataError> {
|
) -> Result<(), DataError> {
|
||||||
let key = to_key(room_id, username, variable_name);
|
let key = to_key(room_id, username, variable_name);
|
||||||
let db_value: I32<LittleEndian> = I32::new(value);
|
let db_value: I32<LittleEndian> = I32::new(value);
|
||||||
self.db.insert(key, IVec::from(db_value.as_bytes()))?;
|
self.db.insert(&key, IVec::from(db_value.as_bytes()))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,13 +70,10 @@ impl Database {
|
||||||
variable_name: &str,
|
variable_name: &str,
|
||||||
) -> Result<(), DataError> {
|
) -> Result<(), DataError> {
|
||||||
let key = to_key(room_id, username, variable_name);
|
let key = to_key(room_id, username, variable_name);
|
||||||
if let Some(_) = self.db.remove(key)? {
|
if let Some(_) = self.db.remove(&key)? {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
let mut key = room_id.to_owned();
|
Err(DataError::KeyDoesNotExist(String::from_utf8(key).unwrap()))
|
||||||
key.push_str(username);
|
|
||||||
key.push_str(variable_name);
|
|
||||||
Err(DataError::KeyDoesNotExist(key))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
20
src/error.rs
20
src/error.rs
|
@ -1,24 +1,8 @@
|
||||||
|
use crate::commands::CommandError;
|
||||||
|
use crate::config::ConfigError;
|
||||||
use crate::db::DataError;
|
use crate::db::DataError;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
|
||||||
pub enum ConfigError {
|
|
||||||
#[error("i/o error: {0}")]
|
|
||||||
IoError(#[from] std::io::Error),
|
|
||||||
|
|
||||||
#[error("toml parsing error: {0}")]
|
|
||||||
TomlParsingError(#[from] toml::de::Error),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
|
||||||
pub enum CommandError {
|
|
||||||
#[error("invalid command: {0}")]
|
|
||||||
InvalidCommand(String),
|
|
||||||
|
|
||||||
#[error("ignored command")]
|
|
||||||
IgnoredCommand,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum BotError {
|
pub enum BotError {
|
||||||
#[error("configuration error: {0}")]
|
#[error("configuration error: {0}")]
|
||||||
|
|
Loading…
Reference in New Issue