Croissant Runtime
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
crsn/crsn/src/asm/patches/mod.rs

80 lines
2.4 KiB

use sexp::SourcePosition;
use crate::asm::error::CrsnError;
pub trait TryRemove {
type Item;
fn try_remove(&mut self, index: usize) -> Option<Self::Item>;
fn remove_or_err(&mut self, index: usize, pos: &SourcePosition, err: &'static str) -> Result<Self::Item, CrsnError>;
}
impl<T> TryRemove for Vec<T> {
type Item = T;
fn try_remove(&mut self, index: usize) -> Option<T> {
if self.is_empty() {
None
} else {
Some(self.remove(index))
}
}
fn remove_or_err(&mut self, index: usize, pos: &SourcePosition, err: &'static str) -> Result<Self::Item, CrsnError> {
match self.try_remove(index) {
None => {
Err(CrsnError::Parse(err.into(), pos.clone()))
}
Some(removed) => Ok(removed)
}
}
}
pub trait NextOrErr<T> {
fn next_or_err(&mut self, pos: SourcePosition, err: &'static str) -> Result<T, CrsnError>;
}
impl<T, K: Iterator<Item=T>> NextOrErr<T> for K {
fn next_or_err(&mut self, pos: SourcePosition, err: &'static str) -> Result<T, CrsnError> {
match self.next() {
None => {
Err(CrsnError::Parse(err.into(), pos))
}
Some(removed) => Ok(removed)
}
}
}
pub trait ErrWithPos<T> {
fn err_pos(self, pos: &SourcePosition) -> Result<T, CrsnError>;
}
impl<T, E: std::error::Error + Send + Sync + 'static> ErrWithPos<T> for Result<T, E> {
fn err_pos(self, pos: &SourcePosition) -> Result<T, CrsnError> {
match self {
Ok(v) => Ok(v),
Err(e) => Err(CrsnError::ParseOther(Box::new(e), pos.clone()))
}
}
}
pub trait ErrSetFile<T> {
fn err_file(self, file: u32) -> Result<T, CrsnError>;
}
impl<T> ErrSetFile<T> for Result<T, CrsnError> {
/// Set file context in the error
fn err_file(self, file: u32) -> Result<T, CrsnError> {
match self {
Ok(v) => Ok(v),
Err(CrsnError::Parse(a, p)) => Err(CrsnError::Parse(a, p.with_file(file))),
Err(CrsnError::ParseOther(a, p)) => Err(CrsnError::ParseOther(a, p.with_file(file))),
Err(CrsnError::Asm(a, p)) => Err(CrsnError::Asm(a, p.with_file(file))),
Err(CrsnError::Sexp(mut se)) => {
se.pos.file = file;
Err(CrsnError::Sexp(se))
},
Err(other @ CrsnError::IOError(_)) => Err(other),
}
}
}