Switch to anyhow and thiserror
This commit is contained in:
parent
7782b66582
commit
4aec215c9f
28
Cargo.lock
generated
28
Cargo.lock
generated
@ -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"
|
||||
|
@ -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"
|
||||
|
72
src/error.rs
72
src/error.rs
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
@ -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>;
|
||||
|
27
src/main.rs
27
src/main.rs
@ -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())?;
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user