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.
80 lines
2.4 KiB
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),
|
|
}
|
|
}
|
|
}
|
|
|