Change to anyhow in cards

This commit is contained in:
pjht 2022-10-23 17:42:19 -05:00
parent 4dd7dba8d5
commit 4123b1c2ee
7 changed files with 65 additions and 104 deletions

View File

@ -1,7 +1,6 @@
use std::fmt::Display;
use nullable_result::GeneralIterExt; use nullable_result::GeneralIterExt;
use serde_yaml::Mapping; use serde_yaml::Mapping;
use thiserror::Error;
use crate::{ use crate::{
card::{Card, CardType}, card::{Card, CardType},
@ -13,21 +12,14 @@ pub struct Backplane {
cards: Vec<Box<dyn Card>>, cards: Vec<Box<dyn Card>>,
} }
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone, Error)]
pub enum CardAddError { pub enum CardAddError {
#[error["Backplane full, could not add card"]]
BackplaneFull, BackplaneFull,
#[error("Invalid card type")]
InvalidType, InvalidType,
} }
impl Display for CardAddError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::BackplaneFull => f.write_str("Backplane full, could not add card"),
Self::InvalidType => f.write_str("Invalid card type"),
}
}
}
impl Backplane { impl Backplane {
pub fn new() -> Self { pub fn new() -> Self {
Self { cards: Vec::new() } Self { cards: Vec::new() }
@ -42,15 +34,15 @@ impl Backplane {
&mut self.cards &mut self.cards
} }
pub fn add_card(&mut self, type_name: &str, config: &Mapping) -> Result<usize, CardAddError> { pub fn add_card(&mut self, type_name: &str, config: &Mapping) -> anyhow::Result<usize> {
if self.cards.len() >= 255 { if self.cards.len() >= 255 {
return Err(CardAddError::BackplaneFull); return Err(CardAddError::BackplaneFull.into());
} }
self.cards.push( self.cards.push(
inventory::iter::<CardType>() inventory::iter::<CardType>()
.find(|card_type| card_type.name == type_name) .find(|card_type| card_type.name == type_name)
.ok_or(CardAddError::InvalidType)? .ok_or(CardAddError::InvalidType)?
.new_card(config), .new_card(config)?,
); );
Ok(self.cards.len() - 1) Ok(self.cards.len() - 1)
} }

View File

@ -5,7 +5,7 @@ use std::fmt::{Debug, Display};
pub struct CardType { pub struct CardType {
pub name: &'static str, pub name: &'static str,
new: fn(data: &Mapping) -> Box<dyn Card>, new: fn(data: &Mapping) -> anyhow::Result<Box<dyn Card>>,
} }
impl CardType { impl CardType {
@ -16,7 +16,7 @@ impl CardType {
} }
} }
pub fn new_card(&self, data: &Mapping) -> Box<dyn Card> { pub fn new_card(&self, data: &Mapping) -> anyhow::Result<Box<dyn Card>> {
(self.new)(data) (self.new)(data)
} }
} }
@ -24,14 +24,14 @@ impl CardType {
inventory::collect!(CardType); inventory::collect!(CardType);
pub trait Card: Debug + Display { pub trait Card: Debug + Display {
fn new(data: &Mapping) -> Self fn new(data: &Mapping) -> anyhow::Result<Self>
where where
Self: Sized; Self: Sized;
fn new_dyn(data: &Mapping) -> Box<dyn Card> fn new_dyn(data: &Mapping) -> anyhow::Result<Box<dyn Card>>
where where
Self: Sized + 'static, Self: Sized + 'static,
{ {
Box::new(Self::new(data)) Ok(Box::new(Self::new(data)?))
} }
fn display(&self) -> String { fn display(&self) -> String {
String::new() String::new()
@ -80,7 +80,9 @@ pub trait Card: Debug + Display {
NullableResult::Ok(()) NullableResult::Ok(())
} }
fn cmd(&mut self, _cmd: &[&str]) {} fn cmd(&mut self, _cmd: &[&str]) -> anyhow::Result<()> {
Ok(())
}
fn reset(&mut self) {} fn reset(&mut self) {}
} }

View File

@ -64,10 +64,7 @@ fn main() -> Result<(), anyhow::Error> {
.map_err(|e| anyhow!("Could not parse config file ({})", e))?; .map_err(|e| anyhow!("Could not parse config file ({})", e))?;
let mut backplane = Backplane::new(); let mut backplane = Backplane::new();
for card in config.cards { for card in config.cards {
match backplane.add_card(card.typ, &card.config) { backplane.add_card(card.typ, &card.config)?;
Ok(_) => (),
Err(e) => panic!("{}", e),
};
} }
let mut symbol_tables = SymbolTables::new(); let mut symbol_tables = SymbolTables::new();
if let Some(initial_tables) = config.symbol_tables { if let Some(initial_tables) = config.symbol_tables {
@ -113,7 +110,7 @@ fn main() -> Result<(), anyhow::Error> {
.unwrap() .unwrap()
.map(String::as_str) .map(String::as_str)
.collect_vec(), .collect_vec(),
); )?;
Ok(None) Ok(None)
}, },
) )

View File

@ -1,5 +1,6 @@
use std::fmt::Display; use std::fmt::Display;
use anyhow::anyhow;
use human_repr::HumanCount; use human_repr::HumanCount;
use nullable_result::NullableResult; use nullable_result::NullableResult;
use serde_yaml::Mapping; use serde_yaml::Mapping;
@ -20,17 +21,17 @@ pub struct Ram {
impl Ram {} impl Ram {}
impl Card for Ram { impl Card for Ram {
fn new(data: &Mapping) -> Self { fn new(data: &Mapping) -> anyhow::Result<Self> {
let size = data let size = data
.get("size") .get("size")
.expect("No size value for RAM") .ok_or_else(|| anyhow!("No size value for RAM"))?
.as_u64() .as_u64()
.expect("Size value not positive integer"); .ok_or_else(|| anyhow!("Size value not a positive integer"))?;
Self { Ok(Self {
data: vec![0; size as usize], data: vec![0; size as usize],
start: 0, start: 0,
enabled: false, enabled: false,
} })
} }
fn read_byte(&mut self, address: u32) -> NullableResult<u8, BusError> { fn read_byte(&mut self, address: u32) -> NullableResult<u8, BusError> {
if !self.enabled { if !self.enabled {

View File

@ -1,5 +1,6 @@
use std::{fmt::Display, fs::File, io::Read}; use std::{fmt::Display, fs::File, io::Read};
use anyhow::anyhow;
use human_repr::HumanCount; use human_repr::HumanCount;
use nullable_result::NullableResult; use nullable_result::NullableResult;
use serde_yaml::Mapping; use serde_yaml::Mapping;
@ -22,24 +23,26 @@ pub struct Rom {
impl Rom {} impl Rom {}
impl Card for Rom { impl Card for Rom {
fn new(data: &Mapping) -> Self { fn new(data: &Mapping) -> anyhow::Result<Self> {
let file_name = data let file_name = data
.get("image") .get("image")
.map(|name| name.as_str().expect("File name not string").to_string()); .map(|name| name.as_str().ok_or_else(|| anyhow!("File name not string")))
.transpose()?
.map(|name| name.to_string());
let mut data = Vec::new(); let mut data = Vec::new();
if let Some(file_name) = file_name.as_ref() { if let Some(file_name) = file_name.as_ref() {
File::open(file_name) File::open(file_name)
.unwrap_or_else(|e| panic!("Could not open ROM image file {} ({})", file_name, e)) .map_err(|e| anyhow!("Could not open ROM image file {} ({})", file_name, e))?
.read_to_end(&mut data) .read_to_end(&mut data)
.unwrap_or_else(|e| panic!("Failed to read ROM image file {} ({})", file_name, e)); .map_err(|e| anyhow!("Failed to read ROM image file {} ({})", file_name, e))?;
}; };
Self { Ok(Self {
data, data,
enabled: true, enabled: true,
ram: [0; 32 * 1024], ram: [0; 32 * 1024],
file_name, file_name,
start: 0, start: 0,
} })
} }
fn read_byte(&mut self, address: u32) -> NullableResult<u8, BusError> { fn read_byte(&mut self, address: u32) -> NullableResult<u8, BusError> {
@ -92,47 +95,28 @@ impl Card for Rom {
NullableResult::Ok(()) NullableResult::Ok(())
} }
fn cmd(&mut self, cmd: &[&str]) { fn cmd(&mut self, cmd: &[&str]) -> anyhow::Result<()> {
if cmd[0] == "load" && cmd.len() >= 2 { if cmd[0] == "load" && cmd.len() >= 2 {
let mut file = match File::open(cmd[1]) { let mut file = File::open(cmd[1])
Ok(file) => file, .map_err(|e| anyhow!("Couldn't open ROM image file {} ({})", cmd[1], e))?;
Err(e) => {
println!("Could not open ROM image file {} ({})", cmd[1], e);
return;
}
};
self.data.clear(); self.data.clear();
match file.read_to_end(&mut self.data) { file.read_to_end(&mut self.data)
Ok(_) => (), .map_err(|e| anyhow!("Failed to read ROM image file {} ({})", cmd[1], e))?;
Err(e) => {
println!("Failed to read ROM image file {} ({})", cmd[1], e);
return;
}
};
self.file_name = Some(cmd[1].into()); self.file_name = Some(cmd[1].into());
println!("Read ROM image file {}", cmd[1]); println!("Read ROM image file {}", cmd[1]);
} else if cmd[0] == "reload" { } else if cmd[0] == "reload" {
if let Some(file_name) = &self.file_name { if let Some(file_name) = &self.file_name {
let mut file = match File::open(file_name) { let mut file = File::open(cmd[1])
Ok(file) => file, .map_err(|e| anyhow!("Couldn't open ROM image file {} ({})", cmd[1], e))?;
Err(e) => {
println!("Could not open ROM image file {} ({})", file_name, e);
return;
}
};
self.data.clear(); self.data.clear();
match file.read_to_end(&mut self.data) { file.read_to_end(&mut self.data)
Ok(_) => (), .map_err(|e| anyhow!("Failed to read ROM image file {} ({})", cmd[1], e))?;
Err(e) => {
println!("Failed to read ROM image file {} ({})", file_name, e);
return;
}
};
println!("Reloaded ROM image file {}", file_name); println!("Reloaded ROM image file {}", file_name);
} else { } else {
println!("No ROM image file to reload"); println!("No ROM image file to reload");
} }
} }
Ok(())
} }
fn reset(&mut self) { fn reset(&mut self) {

View File

@ -1,5 +1,6 @@
use std::{fmt::Display, fs::File, io::Read}; use std::{fmt::Display, fs::File, io::Read};
use anyhow::anyhow;
use human_repr::HumanCount; use human_repr::HumanCount;
use nullable_result::NullableResult; use nullable_result::NullableResult;
use serde_yaml::Mapping; use serde_yaml::Mapping;
@ -21,23 +22,26 @@ pub struct Storage {
} }
impl Card for Storage { impl Card for Storage {
fn new(data: &Mapping) -> Self { fn new(data: &Mapping) -> anyhow::Result<Self> {
let file_name = data let file_name = data
.get("disk") .get("image")
.map(|name| name.as_str().expect("File name not string").to_string()); .map(|name| name.as_str().ok_or_else(|| anyhow!("File name not string")))
.transpose()?
.map(|name| name.to_string());
let mut data = Vec::new(); let mut data = Vec::new();
if let Some(file_name) = file_name.as_ref() { if let Some(file_name) = file_name.as_ref() {
File::open(file_name) File::open(file_name)
.unwrap_or_else(|e| panic!("Could not open disk image file {} ({})", file_name, e)) .map_err(|e| anyhow!("Could not open disk image file {} ({})", file_name, e))?
.read_to_end(&mut data) .read_to_end(&mut data)
.unwrap_or_else(|e| panic!("Failed to read disk image file {} ({})", file_name, e)); .map_err(|e| anyhow!("Failed to read disk image file {} ({})", file_name, e))?;
}; };
Self {
Ok(Self {
data, data,
file_name, file_name,
sector: 0, sector: 0,
offset: 0, offset: 0,
} })
} }
fn read_byte_io(&mut self, address: u8) -> NullableResult<u8, BusError> { fn read_byte_io(&mut self, address: u8) -> NullableResult<u8, BusError> {
@ -65,47 +69,28 @@ impl Card for Storage {
NullableResult::Ok(()) NullableResult::Ok(())
} }
fn cmd(&mut self, cmd: &[&str]) { fn cmd(&mut self, cmd: &[&str]) -> anyhow::Result<()> {
if cmd[0] == "load" && cmd.len() >= 2 { if cmd[0] == "load" && cmd.len() >= 2 {
let mut file = match File::open(cmd[1]) { let mut file = File::open(cmd[1])
Ok(file) => file, .map_err(|e| anyhow!("Couldn't open disk image file {} ({})", cmd[1], e))?;
Err(e) => {
println!("Could not open disk image file {} ({})", cmd[1], e);
return;
}
};
self.data.clear(); self.data.clear();
match file.read_to_end(&mut self.data) { file.read_to_end(&mut self.data)
Ok(_) => (), .map_err(|e| anyhow!("Failed to read disk image file {} ({})", cmd[1], e))?;
Err(e) => {
println!("Failed to read disk image file {} ({})", cmd[1], e);
return;
}
};
self.file_name = Some(cmd[1].into()); self.file_name = Some(cmd[1].into());
println!("Read disk image file {}", cmd[1]); println!("Read disk image file {}", cmd[1]);
} else if cmd[0] == "reload" { } else if cmd[0] == "reload" {
if let Some(file_name) = &self.file_name { if let Some(file_name) = &self.file_name {
let mut file = match File::open(cmd[1]) { let mut file = File::open(cmd[1])
Ok(file) => file, .map_err(|e| anyhow!("Couldn't open disk image file {} ({})", cmd[1], e))?;
Err(e) => {
println!("Could not open disk image file {} ({})", cmd[1], e);
return;
}
};
self.data.clear(); self.data.clear();
match file.read_to_end(&mut self.data) { file.read_to_end(&mut self.data)
Ok(_) => (), .map_err(|e| anyhow!("Failed to read disk image file {} ({})", cmd[1], e))?;
Err(e) => {
println!("Failed to read disk image file {} ({})", cmd[1], e);
return;
}
};
println!("Reloaded disk image file {}", file_name); println!("Reloaded disk image file {}", file_name);
} else { } else {
println!("No disk image file to reload"); println!("No disk image file to reload");
} }
} }
Ok(())
} }
} }

View File

@ -15,11 +15,11 @@ impl Display for Term {
} }
impl Card for Term { impl Card for Term {
fn new(_data: &Mapping) -> Self fn new(_data: &Mapping) -> anyhow::Result<Self>
where where
Self: Sized, Self: Sized,
{ {
Self Ok(Self)
} }
fn read_byte_io(&mut self, address: u8) -> NullableResult<u8, BusError> { fn read_byte_io(&mut self, address: u8) -> NullableResult<u8, BusError> {