Custom schema violation error for DB value retrieval.

This commit is contained in:
projectmoon 2020-10-16 13:07:19 +00:00 committed by ProjectMoon
parent 4234263ee4
commit 4856360c6a
1 changed files with 15 additions and 4 deletions

View File

@ -4,6 +4,11 @@ use thiserror::Error;
use zerocopy::byteorder::I32; use zerocopy::byteorder::I32;
use zerocopy::{AsBytes, LayoutVerified}; use zerocopy::{AsBytes, LayoutVerified};
/// User variables are stored as little-endian 32-bit integers in the
/// database. This type alias makes the database code more pleasant to
/// read.
type LittleEndianI32Layout<'a> = LayoutVerified<&'a [u8], I32<LittleEndian>>;
#[derive(Clone)] #[derive(Clone)]
pub struct Database { pub struct Database {
db: Db, db: Db,
@ -14,6 +19,9 @@ pub enum DataError {
#[error("value does not exist for key: {0}")] #[error("value does not exist for key: {0}")]
KeyDoesNotExist(String), KeyDoesNotExist(String),
#[error("key violates expected schema: {0}")]
SchemaViolation(String),
#[error("internal database error: {0}")] #[error("internal database error: {0}")]
InternalError(#[from] sled::Error), InternalError(#[from] sled::Error),
} }
@ -40,11 +48,14 @@ impl Database {
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 = LittleEndianI32Layout::new_unaligned(raw_value.as_ref());
LayoutVerified::new_unaligned(&*raw_value).expect("bytes do not fit schema");
if let Some(layout) = layout {
let value: I32<LittleEndian> = *layout; let value: I32<LittleEndian> = *layout;
Ok(value.get()) Ok(value.get())
} else {
Err(DataError::SchemaViolation(String::from_utf8(key).unwrap()))
}
} else { } else {
Err(DataError::KeyDoesNotExist(String::from_utf8(key).unwrap())) Err(DataError::KeyDoesNotExist(String::from_utf8(key).unwrap()))
} }