Switch to anyhow and thiserror

This commit is contained in:
pjht 2022-10-23 17:18:32 -05:00
parent 7782b66582
commit 4aec215c9f
7 changed files with 87 additions and 109 deletions

28
Cargo.lock generated
View File

@ -20,6 +20,12 @@ dependencies = [
"libc",
]
[[package]]
name = "anyhow"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6"
[[package]]
name = "arrayvec"
version = "0.5.2"
@ -431,6 +437,7 @@ dependencies = [
name = "m68k_emu"
version = "0.1.0"
dependencies = [
"anyhow",
"bitvec",
"derive-try-from-primitive",
"elf",
@ -444,6 +451,7 @@ dependencies = [
"reedline-repl-rs",
"serde",
"serde_yaml",
"thiserror",
]
[[package]]
@ -809,6 +817,26 @@ version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16"
[[package]]
name = "thiserror"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "time"
version = "0.1.44"

View File

@ -6,6 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0.66"
bitvec = "1.0.0"
derive-try-from-primitive = "1.0.0"
elf = "0.3.1"
@ -19,3 +20,4 @@ paste = "1.0.9"
reedline-repl-rs = { path = "reedline-repl-rs" }
serde = { version = "1.0.144", features = ["derive"] }
serde_yaml = "0.9.13"
thiserror = "1.0.37"

View File

@ -1,72 +0,0 @@
use crate::{disas::DisassemblyError, m68k::BusError};
use reedline_repl_rs::Error as ReplError;
use std::{fmt::Display, io, num::ParseIntError};
#[derive(Debug)]
pub enum Error {
Repl(ReplError),
InvalidCard(u8),
Bus(BusError),
InvalidPeekFormat,
InvalidPeekSize,
Disassembly(DisassemblyError<BusError>),
Misc(&'static str),
InvalidSymbolTable,
InvalidSymbolName,
Io(io::Error),
ElfParse(elf::ParseError),
}
impl From<elf::ParseError> for Error {
fn from(v: elf::ParseError) -> Self {
Self::ElfParse(v)
}
}
impl From<io::Error> for Error {
fn from(v: io::Error) -> Self {
Self::Io(v)
}
}
impl From<DisassemblyError<BusError>> for Error {
fn from(v: DisassemblyError<BusError>) -> Self {
Self::Disassembly(v)
}
}
impl From<BusError> for Error {
fn from(v: BusError) -> Self {
Self::Bus(v)
}
}
impl From<ReplError> for Error {
fn from(v: ReplError) -> Self {
Self::Repl(v)
}
}
impl From<ParseIntError> for Error {
fn from(v: ParseIntError) -> Self {
Self::Repl(v.into())
}
}
impl Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Repl(e) => e.fmt(f),
Self::InvalidCard(n) => f.write_fmt(format_args!("Card {} does not exist", n)),
Self::Bus(e) => e.fmt(f),
Self::InvalidPeekFormat => f.write_str("Invalid peek format"),
Self::InvalidPeekSize => f.write_str("Invalid peek size"),
Self::Disassembly(e) => e.fmt(f),
Self::Misc(s) => f.write_str(s),
Self::InvalidSymbolTable => f.write_str("Invalid symbol table"),
Self::InvalidSymbolName => f.write_str("Invalid symbol name"),
Self::Io(e) => e.fmt(f),
Self::ElfParse(e) => e.fmt(f),
}
}
}

View File

@ -1,5 +1,8 @@
use bitvec::prelude::*;
use std::fmt::{Debug, Display};
use std::{
error::Error,
fmt::{Debug, Display},
};
use crate::{
backplane::Backplane,
@ -19,6 +22,8 @@ impl Display for BusError {
}
}
impl Error for BusError {}
// pub trait Bus: Debug {
// fn read_word(&mut self, address: u32) -> Result<u16, BusError>;
// fn read_byte(&mut self, address: u32) -> Result<u8, BusError>;

View File

@ -3,7 +3,7 @@
mod backplane;
mod card;
mod disas;
mod error;
// mod error;
mod instruction;
mod location;
mod m68k;
@ -16,10 +16,10 @@ mod symbol_tables;
mod term;
use crate::{
backplane::Backplane,
error::Error,
location::Location,
m68k::{BusError, M68K},
};
use anyhow::anyhow;
use disas::DisassemblyError;
use indexmap::IndexSet;
use itertools::Itertools;
@ -32,6 +32,7 @@ use serde::Deserialize;
use serde_yaml::Mapping;
use std::{convert::TryFrom, fs, path::Path, process};
use symbol_tables::SymbolTables;
use thiserror::Error;
#[derive(Copy, Clone, Debug)]
enum PeekFormat {
@ -61,8 +62,12 @@ impl PeekFormat {
}
}
#[derive(Debug, Copy, Clone, Error)]
#[error("Invalid peek format")]
struct InvalidPeekFormat;
impl TryFrom<char> for PeekFormat {
type Error = Error;
type Error = InvalidPeekFormat;
fn try_from(value: char) -> Result<Self, Self::Error> {
match value {
@ -71,7 +76,7 @@ impl TryFrom<char> for PeekFormat {
'd' => Ok(Self::Decimal),
'u' => Ok(Self::UnsignedDecimal),
'b' => Ok(Self::Binary),
_ => Err(Error::InvalidPeekFormat),
_ => Err(InvalidPeekFormat),
}
}
}
@ -101,15 +106,19 @@ impl PeekSize {
}
}
#[derive(Debug, Copy, Clone, Error)]
#[error("Invalid peek size")]
struct InvalidPeekSize;
impl TryFrom<char> for PeekSize {
type Error = Error;
type Error = InvalidPeekSize;
fn try_from(value: char) -> Result<Self, Self::Error> {
match value {
'b' => Ok(Self::Byte),
'w' => Ok(Self::Word),
'l' => Ok(Self::LongWord),
_ => Err(Error::InvalidPeekSize),
_ => Err(InvalidPeekSize),
}
}
}
@ -152,7 +161,7 @@ fn main() -> Result<(), ReplError> {
symbol_tables.load_table(path, true).unwrap();
}
}
Repl::<_, Error>::new(EmuState {
Repl::<_, anyhow::Error>::new(EmuState {
cpu: M68K::new(backplane),
symbol_tables,
address_breakpoints: IndexSet::new(),
@ -183,7 +192,7 @@ fn main() -> Result<(), ReplError> {
.bus_mut()
.cards_mut()
.get_mut(num as usize)
.ok_or(Error::InvalidCard(num))?
.ok_or_else(|| anyhow!("Card {} does not exist", num))?
.cmd(
&args
.get_many::<String>("args")
@ -318,7 +327,7 @@ fn main() -> Result<(), ReplError> {
|args, state| {
let fmt_str = args.get_one::<String>("fmt").unwrap();
if fmt_str.len() != 2 {
return Err(Error::Misc("Peek format length must be 2"));
return Err(anyhow!("Peek format length must be 2"));
}
let fmt = PeekFormat::try_from(fmt_str.chars().next().unwrap())?;
let size = PeekSize::try_from(fmt_str.chars().nth(1).unwrap())?;

View File

@ -1,4 +1,5 @@
use crate::{error::Error, symbol::Symbol};
use crate::symbol::Symbol;
use anyhow::anyhow;
use elf::gabi::{STT_FILE, STT_SECTION};
use elf::CachedReadBytes;
use indexmap::IndexSet;
@ -21,12 +22,12 @@ impl SymbolTable {
}
}
pub fn read_from_file(path: &str) -> Result<Self, Error> {
pub fn read_from_file(path: &str) -> anyhow::Result<Self> {
let mut cached_reader = CachedReadBytes::new(File::open(path)?);
let mut file = elf::File::open_stream(&mut cached_reader)?;
let (symtab, symstrtab) = file
.symbol_table()?
.ok_or(Error::Misc("No symbol table in file"))?;
.ok_or_else(|| anyhow!("No symbol table in file"))?;
let symbols = symtab
.iter()
.skip(1)

View File

@ -1,9 +1,10 @@
use std::{fmt::Display, path::Path};
use crate::{error::Error, location::Location, symbol::Symbol, symbol_table::SymbolTable};
use crate::{location::Location, symbol::Symbol, symbol_table::SymbolTable};
use indexmap::IndexMap;
use itertools::Itertools;
use parse_int::parse;
use thiserror::Error;
pub struct SymbolDisplayer<'a>(&'a SymbolTables);
@ -40,6 +41,14 @@ impl Display for SymbolDisplayer<'_> {
}
}
#[derive(Debug, Copy, Clone, Error)]
#[error("Invalid symbol table")]
struct InvalidSymbolTable;
#[derive(Debug, Copy, Clone, Error)]
#[error("Invalid symbol name")]
struct InvalidSymbolName;
pub struct BreakpointDisplayer<'a>(&'a SymbolTables);
impl Display for BreakpointDisplayer<'_> {
@ -75,21 +84,16 @@ impl SymbolTables {
})
}
pub fn delete(&mut self, table: &str) -> Result<SymbolTable, Error> {
self.tables
.shift_remove(table)
.ok_or(Error::InvalidSymbolTable)
pub fn delete(&mut self, table: &str) -> anyhow::Result<SymbolTable> {
Ok(self.tables.shift_remove(table).ok_or(InvalidSymbolTable)?)
}
pub fn set_active(&mut self, table: &str, active: bool) -> Result<(), Error> {
self.tables
.get_mut(table)
.ok_or(Error::InvalidSymbolTable)?
.active = active;
pub fn set_active(&mut self, table: &str, active: bool) -> anyhow::Result<()> {
self.tables.get_mut(table).ok_or(InvalidSymbolTable)?.active = active;
Ok(())
}
pub fn load_table(&mut self, path: &str, append: bool) -> Result<(), Error> {
pub fn load_table(&mut self, path: &str, append: bool) -> anyhow::Result<()> {
let new_table = SymbolTable::read_from_file(path)?;
let table_name = Path::new(&path).file_name().unwrap().to_str().unwrap();
if let Some(table) = self.tables.get_mut(table_name) {
@ -105,20 +109,20 @@ impl SymbolTables {
Ok(())
}
pub fn set_breakpoint(&mut self, table: &str, symbol: String) -> Result<(), Error> {
pub fn set_breakpoint(&mut self, table: &str, symbol: String) -> anyhow::Result<()> {
self.tables
.get_mut(table)
.ok_or(Error::InvalidSymbolTable)?
.ok_or(InvalidSymbolTable)?
.breakpoints
.insert(symbol);
Ok(())
}
pub fn delete_breakpoint(&mut self, table: &str, symbol: &str) -> Result<bool, Error> {
pub fn delete_breakpoint(&mut self, table: &str, symbol: &str) -> anyhow::Result<bool> {
Ok(self
.tables
.get_mut(table)
.ok_or(Error::InvalidSymbolTable)?
.ok_or(InvalidSymbolTable)?
.breakpoints
.shift_remove(symbol))
}
@ -135,16 +139,17 @@ impl SymbolTables {
self.tables.is_empty()
}
pub fn get(&self, table: &str, symbol: &str) -> Result<&Symbol, Error> {
self.tables
pub fn get(&self, table: &str, symbol: &str) -> anyhow::Result<&Symbol> {
Ok(self
.tables
.get(table)
.ok_or(Error::InvalidSymbolTable)?
.ok_or(InvalidSymbolTable)?
.symbols
.get(symbol)
.ok_or(Error::InvalidSymbolName)
.ok_or(InvalidSymbolName)?)
}
pub fn parse_location(&self, location: &str) -> Result<Location, Error> {
pub fn parse_location(&self, location: &str) -> anyhow::Result<Location> {
parse::<u32>(location).map(Location::Address).or_else(|_| {
let (mut table_name, symbol_name) = location.split_once(':').unwrap_or(("", location));
if table_name.is_empty() {
@ -152,16 +157,16 @@ impl SymbolTables {
.tables
.iter()
.find(|(_, table)| table.symbols.contains_key(symbol_name))
.ok_or(Error::InvalidSymbolName)?
.ok_or(InvalidSymbolName)?
.0;
} else if !self
.tables
.get(table_name)
.ok_or(Error::InvalidSymbolTable)?
.ok_or(InvalidSymbolTable)?
.symbols
.contains_key(symbol_name)
{
return Err(Error::InvalidSymbolName);
return Err(InvalidSymbolName.into());
}
Ok(Location::Symbol((
table_name.to_string(),
@ -170,7 +175,7 @@ impl SymbolTables {
})
}
pub fn parse_location_address(&self, location: &str) -> Result<u32, Error> {
pub fn parse_location_address(&self, location: &str) -> anyhow::Result<u32> {
self.parse_location(location).map(|l| l.addr(self))
}
}