feat: better error handling (introduce thiserror)
This commit is contained in:
parent
0692c2325b
commit
00a8cc563c
25
Cargo.lock
generated
25
Cargo.lock
generated
@ -206,7 +206,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"libredox",
|
||||
"thiserror",
|
||||
"thiserror 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -246,6 +246,7 @@ dependencies = [
|
||||
"crossterm",
|
||||
"dirs",
|
||||
"regex",
|
||||
"thiserror 2.0.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -307,7 +308,16 @@ version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
"thiserror-impl 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3ac7f54ca534db81081ef1c1e7f6ea8a3ef428d2fc069097c079443d24124d3"
|
||||
dependencies = [
|
||||
"thiserror-impl 2.0.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -321,6 +331,17 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e9465d30713b56a37ede7185763c3492a91be2f5fa68d958c44e41ab9248beb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.14"
|
||||
|
||||
@ -10,4 +10,5 @@ crossterm = "0.27"
|
||||
regex = "1.11"
|
||||
anyhow = "1.0"
|
||||
dirs = "5.0"
|
||||
thiserror = "2"
|
||||
# clap = { version = "4.5", features = ["derive"] }
|
||||
|
||||
@ -6,7 +6,7 @@ use crossterm::{
|
||||
terminal::DisableLineWrap,
|
||||
};
|
||||
use input::Input;
|
||||
use persist::{Session, SessionName};
|
||||
use persist::Session;
|
||||
use regex::Cache as RegexCache;
|
||||
use render::Render;
|
||||
|
||||
@ -46,7 +46,7 @@ enum Field {
|
||||
TestString,
|
||||
}
|
||||
|
||||
struct Change {
|
||||
pub struct Change {
|
||||
content: bool,
|
||||
cursor: bool,
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ use replay::{App, persist::Session};
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
let session = if let Some(name) = env::args().nth(1) {
|
||||
Session::fetch(name).unwrap()
|
||||
Session::fetch(name)?
|
||||
} else {
|
||||
Session::scratch()
|
||||
};
|
||||
|
||||
@ -19,7 +19,7 @@ impl Display for SessionName {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"-- {} --",
|
||||
"--- {} ---",
|
||||
if let Self::Name(name) = self {
|
||||
name
|
||||
} else {
|
||||
@ -29,10 +29,22 @@ impl Display for SessionName {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error("session name contains invalid char: `{0}`")]
|
||||
InvalidName(char),
|
||||
InvalidFormat,
|
||||
#[error("session file contains invalid format: {0}")]
|
||||
InvalidFormat(FormatError),
|
||||
}
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum FormatError {
|
||||
#[error("session file must include exactly 2 lines")]
|
||||
Lines,
|
||||
#[error("the cursor position and content must be separated with a `:`")]
|
||||
Separator,
|
||||
#[error("cursor position must be a string representation of a `usize`")]
|
||||
Cursor,
|
||||
}
|
||||
|
||||
pub struct Session {
|
||||
@ -94,6 +106,8 @@ impl Session {
|
||||
|
||||
fn validate_name(name: &str) -> Result<(), Error> {
|
||||
if let Some(idx) = name.find(INVALID_CHARS) {
|
||||
// This `unwrap` is okay, because we got that index from the `find`
|
||||
// method, which means it must be in the bounds of the string
|
||||
Err(Error::InvalidName(name.chars().nth(idx).unwrap()))
|
||||
} else {
|
||||
Ok(())
|
||||
@ -104,7 +118,7 @@ fn parse_session(path: &Path) -> Result<(Input, Input), Error> {
|
||||
if let Ok(s) = fs::read_to_string(path) {
|
||||
let lines: Vec<_> = s.split('\n').collect();
|
||||
if lines.len() != 2 {
|
||||
Err(Error::InvalidFormat)
|
||||
Err(Error::InvalidFormat(FormatError::Lines))
|
||||
} else {
|
||||
let regex_query = parse_field(lines[0])?;
|
||||
let test_string = parse_field(lines[1])?;
|
||||
@ -128,8 +142,12 @@ fn get_path(name: &str) -> PathBuf {
|
||||
}
|
||||
|
||||
fn parse_field(s: &str) -> Result<Input, Error> {
|
||||
let (cursor, string) = s.split_once(':').ok_or(Error::InvalidFormat)?;
|
||||
let cursor = cursor.parse().map_err(|_| Error::InvalidFormat)?;
|
||||
let (cursor, string) = s
|
||||
.split_once(':')
|
||||
.ok_or(Error::InvalidFormat(FormatError::Separator))?;
|
||||
let cursor = cursor
|
||||
.parse()
|
||||
.map_err(|_| Error::InvalidFormat(FormatError::Cursor))?;
|
||||
Ok(Input {
|
||||
string: string.to_owned(),
|
||||
cursor,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user