Set up a mock database for the sled example
This commit is contained in:
parent
911f4ad81e
commit
d0f6a042e4
|
@ -756,6 +756,13 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "error-training"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "etcetera"
|
name = "etcetera"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
|
|
@ -7,6 +7,7 @@ members = [
|
||||||
"cyberpunk-splash",
|
"cyberpunk-splash",
|
||||||
"dashboard",
|
"dashboard",
|
||||||
"emseries",
|
"emseries",
|
||||||
|
"error-training",
|
||||||
"file-service",
|
"file-service",
|
||||||
"fluent-ergonomics",
|
"fluent-ergonomics",
|
||||||
"geo-types",
|
"geo-types",
|
||||||
|
|
1
build.sh
1
build.sh
|
@ -10,6 +10,7 @@ RUST_ALL_TARGETS=(
|
||||||
"cyberpunk-splash"
|
"cyberpunk-splash"
|
||||||
"dashboard"
|
"dashboard"
|
||||||
"emseries"
|
"emseries"
|
||||||
|
"error-training"
|
||||||
"file-service"
|
"file-service"
|
||||||
"fluent-ergonomics"
|
"fluent-ergonomics"
|
||||||
"geo-types"
|
"geo-types"
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
[package]
|
||||||
|
name = "error-training"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "error_training"
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "error-training"
|
||||||
|
path = "src/main.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
thiserror = { version = "1" }
|
|
@ -0,0 +1,62 @@
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Error, PartialEq)]
|
||||||
|
pub enum FatalError {
|
||||||
|
#[error("Database corruption detected")]
|
||||||
|
DatabaseCorruption,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Error, PartialEq)]
|
||||||
|
pub enum MathError {
|
||||||
|
#[error("divide by zero is not defined")]
|
||||||
|
DivideByZero,
|
||||||
|
|
||||||
|
#[error("result exceeds maxint")]
|
||||||
|
ExceedsMaxint,
|
||||||
|
|
||||||
|
#[error("result exceeds minint")]
|
||||||
|
ExceedsMinint,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Error, PartialEq)]
|
||||||
|
pub enum DatabaseError {
|
||||||
|
#[error("value not found")]
|
||||||
|
NotFound,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod sled {
|
||||||
|
//! Sled-style error handling is based on Result<Result<Value, LocalError>, FatalError>.
|
||||||
|
//! FatalErrors do not get resolved. LocalErrors get bubbled up until they can be handled.
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
pub struct DB(HashMap<String, i8>);
|
||||||
|
|
||||||
|
impl DB {
|
||||||
|
pub fn new(lst: Vec<(String, i8)>) -> Self {
|
||||||
|
Self(lst.into_iter().collect::<HashMap<String, i8>>())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve a value from the database. Throw a fatal error with the "fail" key, but
|
||||||
|
/// otherwise return either the value or DatabaseError::NotFound.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use error_training::{*, sled::*};
|
||||||
|
///
|
||||||
|
/// let db = DB::new(vec![("a".to_owned(), 15), ("b".to_owned(), 0)]);
|
||||||
|
/// assert_eq!(db.get("fail"), Err(FatalError::DatabaseCorruption));
|
||||||
|
/// assert_eq!(db.get("a"), Ok(Ok(15)));
|
||||||
|
/// assert_eq!(db.get("c"), Ok(Err(DatabaseError::NotFound)));
|
||||||
|
/// ```
|
||||||
|
pub fn get(&self, key: &str) -> Result<Result<i8, DatabaseError>, FatalError> {
|
||||||
|
if key == "fail" {
|
||||||
|
Err(FatalError::DatabaseCorruption)
|
||||||
|
} else {
|
||||||
|
Ok(self.0.get(key).copied().ok_or(DatabaseError::NotFound))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run() {}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
//! Error handling practice.
|
||||||
|
//!
|
||||||
|
//! The purpose of this crate is to demonstrate error handling in a couple of different scenarios
|
||||||
|
//! so that I have clear templates to refer when doing development, instead of hand-waving or
|
||||||
|
//! putting error handling off into the unspecified future.
|
||||||
|
//!
|
||||||
|
//! I am going to demonstrate error handling in the style of [Error Handling in a
|
||||||
|
//! Correctness-Critical Rust Project | sled-rs.github.io](https://sled.rs/errors.html) and in my
|
||||||
|
//! reformulation of it using Flow.
|
||||||
|
//!
|
||||||
|
//! I will also test out additional libraries in the same scenarios:
|
||||||
|
//!
|
||||||
|
//! - anyhow
|
||||||
|
//!
|
||||||
|
//! A database exists with some numbers. Mathmatical calculations will be performed on those
|
||||||
|
//! numbers. Some calculations are invalid and should fail. In some cases, those should be reported
|
||||||
|
//! to the user, and in other cases those can be recovered. Sometimes a calculation needs to be
|
||||||
|
//! performed on a value that doesn't exist, which is also a failure. However, sometimes, the
|
||||||
|
//! database will detect corruption, wich is fatal and should terminate the "app".
|
||||||
|
//!
|
||||||
|
//! In these scenarios, the "app" is a top-level function which runs the scenario. This particular
|
||||||
|
//! app should never crash, just show where crashes would happen.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
|
@ -18,8 +18,6 @@ path = "src/main.rs"
|
||||||
name = "auth-cli"
|
name = "auth-cli"
|
||||||
path = "src/bin/cli.rs"
|
path = "src/bin/cli.rs"
|
||||||
|
|
||||||
[target.auth-cli.dependencies]
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base64ct = { version = "1", features = [ "alloc" ] }
|
base64ct = { version = "1", features = [ "alloc" ] }
|
||||||
build_html = { version = "2" }
|
build_html = { version = "2" }
|
||||||
|
|
Loading…
Reference in New Issue