move error from roxy-cli to roxy-core

This commit is contained in:
KitsuneCafe 2024-02-04 05:48:18 -05:00
parent 8121a30b0c
commit dc17ebdb5d
3 changed files with 93 additions and 12 deletions

77
src/error.rs Normal file
View File

@ -0,0 +1,77 @@
use std::{
fmt::Display,
io::{Error as IOError, ErrorKind},
path::StripPrefixError,
};
#[derive(Debug)]
pub struct Error {
message: String,
source: Option<Box<dyn std::error::Error>>,
}
impl Error {
fn wrap<E: std::error::Error + 'static>(value: E) -> Option<Box<dyn std::error::Error>> {
Some(Box::new(value))
}
}
impl Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", &self.message)?;
if let Some(source) = &self.source {
write!(f, " ({})", &source)?;
}
Ok(())
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.source.as_deref()
}
}
impl From<String> for Error {
fn from(value: String) -> Self {
Self {
message: value,
source: None,
}
}
}
impl From<StripPrefixError> for Error {
fn from(value: StripPrefixError) -> Self {
Self {
message: value.to_string(),
source: Self::wrap(value),
}
}
}
impl From<IOError> for Error {
fn from(value: IOError) -> Self {
Self {
message: value.to_string(),
source: Self::wrap(value),
}
}
}
impl From<Error> for IOError {
fn from(value: Error) -> Self {
IOError::new(ErrorKind::Other, value.message)
}
}
impl From<&'static dyn std::error::Error> for Error {
fn from(value: &'static dyn std::error::Error) -> Self {
Self {
message: value.to_string(),
source: Self::wrap(value),
}
}
}

View File

@ -1,2 +1,3 @@
pub mod roxy;
pub mod error;

View File

@ -4,8 +4,10 @@ use std::{
path::Path,
};
use crate::error::Error;
pub trait Parse {
fn parse(&mut self, path: &str, src: &[u8], dst: &mut Vec<u8>) -> std::io::Result<()>;
fn parse(&mut self, path: &str, src: &[u8], dst: &mut Vec<u8>) -> Result<(), Error>;
}
pub trait AndThenParser<P> {
@ -21,13 +23,13 @@ impl<'a> Parser<'a> {
Parser { steps: Vec::new() }
}
pub fn push<P: Parse>(&mut self, parser: &'a mut P) {
pub fn push<P: Parse>(&mut self, parser: &'a mut P) {
self.steps.push(parser);
}
}
impl<'a> Parse for Parser<'a> {
fn parse(&mut self, path: &str, src: &[u8], dst: &mut Vec<u8>) -> std::io::Result<()> {
fn parse(&mut self, path: &str, src: &[u8], dst: &mut Vec<u8>) -> Result<(), Error> {
let mut buf_1 = Vec::from(src);
let mut buf_2 = Vec::from(dst.as_slice());
@ -37,7 +39,9 @@ impl<'a> Parse for Parser<'a> {
dst.clear();
p.parse(path, src.as_slice(), &mut dst).map(|()| (dst, src))
})
.map(|(a, _)| dst.write_all(a))?
.map(|(a, _)| dst.write_all(a))??;
Ok(())
}
}
@ -53,12 +57,13 @@ impl<'a, R> Asset<'a, R> {
}
impl<'a> TryFrom<&'a str> for Asset<'a, BufReader<File>> {
type Error = std::io::Error;
type Error = Error;
fn try_from(value: &'a str) -> Result<Self, Self::Error> {
File::open(value)
.map(BufReader::new)
.map(|data| Self::new(value, data))
.map_err(Error::from)
}
}
@ -81,14 +86,14 @@ impl<'a, R: BufRead> BufRead for Asset<'a, R> {
pub struct Roxy;
impl Roxy {
pub fn load(path: &str) -> std::io::Result<Asset<BufReader<File>>> {
pub fn load(path: &str) -> Result<Asset<BufReader<File>>, Error> {
path.try_into()
}
fn read_asset(
asset: &mut Asset<BufReader<File>>,
parser: &mut Parser,
) -> std::io::Result<Vec<u8>> {
) -> Result<Vec<u8>, Error> {
let mut src = Vec::new();
let mut dst = Vec::new();
@ -105,10 +110,9 @@ impl Roxy {
.ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, "{path} is invalid"))
}
pub fn parse<P: AsRef<Path>>(path: &P, parser: &mut Parser) -> std::io::Result<Vec<u8>> {
Self::path_to_str(path)
.and_then(Self::load)
.and_then(|mut a| Self::read_asset(&mut a, parser))
pub fn parse<P: AsRef<Path>>(path: &P, parser: &mut Parser) -> Result<Vec<u8>, Error> {
let path = Self::path_to_str(path)?;
Self::load(path).and_then(|mut a| Self::read_asset(&mut a, parser))
}
fn mkdir_and_open<P: AsRef<Path>>(path: &P) -> std::io::Result<File> {
@ -126,4 +130,3 @@ impl Roxy {
Self::mkdir_and_open(&output).and_then(|mut f| f.write_all(&buf))
}
}