Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor errors into crate root #26

Merged
merged 1 commit into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions src/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ impl fmt::Display for BinParse {

impl std::error::Error for BinParse {}

pub type BinParseResult<T> = Result<T, BinParse>;

#[derive(Debug, Clone)]
pub struct Line {
pub message: String,
Expand Down Expand Up @@ -81,21 +79,42 @@ impl TextParse {
}

impl From<io::Error> for TextParse {
fn from(err: io::Error) -> TextParse {
fn from(err: io::Error) -> Self {
TextParse::Io(err)
}
}

impl fmt::Display for TextParse {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
TextParse::Io(msg) => write!(f, "{}", msg),
TextParse::Lexer(err) => write!(f, "{}", err),
TextParse::Parser(err) => write!(f, "{}", err),
Self::Io(msg) => write!(f, "{}", msg),
Self::Lexer(err) => write!(f, "{}", err),
Self::Parser(err) => write!(f, "{}", err),
}
}
}

impl std::error::Error for TextParse {}

pub type TextParseResult<T> = std::result::Result<T, TextParse>;
#[derive(Debug)]
pub enum Write {
Validation(String),
Io(std::io::Error),
}

impl From<io::Error> for Write {
fn from(err: io::Error) -> Self {
Write::Io(err)
}
}

impl fmt::Display for Write {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Validation(msg) => write!(f, "{}", msg),
Self::Io(err) => write!(f, "{}", err),
}
}
}

impl std::error::Error for Write {}
24 changes: 21 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,31 @@ pub use common::{Palette, QUAKE_PALETTE};
#[cfg(feature = "std")]
use common::slice_to_cstring;

#[cfg(feature = "std")]
pub mod error;

#[cfg(feature = "std")]
pub mod lump;

#[cfg(feature = "std")]
pub mod wad;

pub mod qmap;

#[cfg(feature = "std")]
mod error;

#[cfg(feature = "std")]
pub use error::BinParse as BinParseError;

#[cfg(feature = "std")]
pub use error::TextParse as TextParseError;

#[cfg(feature = "std")]
pub use error::Write as WriteError;

#[cfg(feature = "std")]
pub type BinParseResult<T> = Result<T, BinParseError>;

#[cfg(feature = "std")]
pub type TextParseResult<T> = std::result::Result<T, TextParseError>;

#[cfg(feature = "std")]
pub type WriteAttempt = Result<(), WriteError>;
2 changes: 1 addition & 1 deletion src/lump/parse.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::common::Palette;
use crate::error;
use crate::lump::{Image, MipTexture, MipTextureHead};
use error::BinParseResult;
use crate::BinParseResult;
use std::boxed::Box;
use std::io::{Read, Seek, SeekFrom};
use std::mem::{size_of, transmute, MaybeUninit};
Expand Down
8 changes: 2 additions & 6 deletions src/qmap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@
//! #
//! # let mut dest = Vec::<u8>::new();
//! #
//! use quake_util::qmap;
//! use qmap::{Entity, WriteError};
//! use quake_util::error::TextParse as TextParseError;
//! use quake_util::{qmap, WriteError, TextParseError};
//! use qmap::Entity;
//!
//! let mut map = qmap::parse(&mut source).map_err(|err| match err {
//! TextParseError::Io(_) => String::from("Failed to read map"),
Expand Down Expand Up @@ -67,9 +66,6 @@ pub use repr::{
#[cfg(feature = "std")]
pub use parser::parse;

#[cfg(feature = "std")]
pub use repr::{WriteAttempt, WriteError};

// test suites

#[cfg(all(test, feature = "std"))]
Expand Down
59 changes: 29 additions & 30 deletions src/qmap/parser.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,36 @@
#[cfg(feature = "std")]
extern crate std;

use std::{
cell::Cell, io::Read, iter::Peekable, num::NonZeroU8, str::FromStr,
vec::Vec,
};

use crate::{common, error, qmap};
use crate::{common, qmap, TextParseError, TextParseResult};
use common::CellOptionExt;
use qmap::lexer::{Token, TokenIterator};
use qmap::repr::{Alignment, Brush, Edict, Entity, Point, QuakeMap, Surface};

type TokenPeekable<R> = Peekable<TokenIterator<R>>;

trait Extract {
fn extract(&mut self) -> Result<Option<Token>, error::TextParse>;
fn extract(&mut self) -> TextParseResult<Option<Token>>;
}

impl<R> Extract for TokenPeekable<R>
where
R: Read,
{
fn extract(&mut self) -> Result<Option<Token>, error::TextParse> {
fn extract(&mut self) -> Result<Option<Token>, TextParseError> {
self.next().transpose().map_err(|e| e.into_unwrapped())
}
}

trait Normalize {
fn normalize(&self) -> Result<&Option<Token>, error::TextParse>;
fn normalize(&self) -> TextParseResult<&Option<Token>>;
}

impl Normalize for Result<Option<Token>, Cell<Option<error::TextParse>>> {
fn normalize(&self) -> Result<&Option<Token>, error::TextParse> {
impl Normalize for Result<Option<Token>, Cell<Option<TextParseError>>> {
fn normalize(&self) -> Result<&Option<Token>, TextParseError> {
self.as_ref().map_err(|e| e.steal())
}
}
Expand All @@ -44,7 +43,7 @@ const MIN_BRUSH_SURFACES: usize = 4;
/// `brushDef`s/`patchDef`s are not presently supported) but may have texture
/// alignment in either "Valve220" format or the "legacy" predecessor (i.e.
/// without texture axes)
pub fn parse<R: Read>(reader: &mut R) -> error::TextParseResult<QuakeMap> {
pub fn parse<R: Read>(reader: &mut R) -> TextParseResult<QuakeMap> {
let mut entities: Vec<Entity> = Vec::new();
let mut peekable_tokens = TokenIterator::new(reader).peekable();

Expand All @@ -58,7 +57,7 @@ pub fn parse<R: Read>(reader: &mut R) -> error::TextParseResult<QuakeMap> {

fn parse_entity<R: Read>(
tokens: &mut TokenPeekable<R>,
) -> error::TextParseResult<Entity> {
) -> TextParseResult<Entity> {
expect_byte(&tokens.extract()?, b'{')?;

let edict = parse_edict(tokens)?;
Expand All @@ -71,7 +70,7 @@ fn parse_entity<R: Read>(

fn parse_edict<R: Read>(
tokens: &mut TokenPeekable<R>,
) -> error::TextParseResult<Edict> {
) -> TextParseResult<Edict> {
let mut edict = Edict::new();

while let Some(tok_res) = tokens.peek() {
Expand All @@ -98,7 +97,7 @@ fn parse_edict<R: Read>(

fn parse_brushes<R: Read>(
tokens: &mut TokenPeekable<R>,
) -> error::TextParseResult<Vec<Brush>> {
) -> TextParseResult<Vec<Brush>> {
let mut brushes = Vec::new();

while let Some(tok_res) = tokens.peek() {
Expand All @@ -114,7 +113,7 @@ fn parse_brushes<R: Read>(

fn parse_brush<R: Read>(
tokens: &mut TokenPeekable<R>,
) -> error::TextParseResult<Brush> {
) -> TextParseResult<Brush> {
let mut surfaces = Vec::with_capacity(MIN_BRUSH_SURFACES);
expect_byte(&tokens.extract()?, b'{')?;

Expand All @@ -132,14 +131,14 @@ fn parse_brush<R: Read>(

fn parse_surface<R: Read>(
tokens: &mut TokenPeekable<R>,
) -> error::TextParseResult<Surface> {
) -> TextParseResult<Surface> {
let pt1 = parse_point(tokens)?;
let pt2 = parse_point(tokens)?;
let pt3 = parse_point(tokens)?;

let half_space = [pt1, pt2, pt3];

let texture_token = &tokens.extract()?.ok_or_else(error::TextParse::eof)?;
let texture_token = &tokens.extract()?.ok_or_else(TextParseError::eof)?;

let texture = if b'"' == (&texture_token.text)[0].into() {
strip_quoted(&texture_token.text[..]).to_vec().into()
Expand All @@ -154,7 +153,7 @@ fn parse_surface<R: Read>(
parse_legacy_alignment(tokens)?
}
} else {
return Err(error::TextParse::eof());
return Err(TextParseError::eof());
};

Ok(Surface {
Expand All @@ -166,7 +165,7 @@ fn parse_surface<R: Read>(

fn parse_point<R: Read>(
tokens: &mut TokenPeekable<R>,
) -> error::TextParseResult<Point> {
) -> TextParseResult<Point> {
expect_byte(&tokens.extract()?, b'(')?;
let x = expect_float(&tokens.extract()?)?;
let y = expect_float(&tokens.extract()?)?;
Expand All @@ -178,7 +177,7 @@ fn parse_point<R: Read>(

fn parse_legacy_alignment<R: Read>(
tokens: &mut TokenPeekable<R>,
) -> error::TextParseResult<Alignment> {
) -> TextParseResult<Alignment> {
let offset_x = expect_float(&tokens.extract()?)?;
let offset_y = expect_float(&tokens.extract()?)?;
let rotation = expect_float(&tokens.extract()?)?;
Expand All @@ -195,7 +194,7 @@ fn parse_legacy_alignment<R: Read>(

fn parse_valve_alignment<R: Read>(
tokens: &mut TokenPeekable<R>,
) -> error::TextParseResult<Alignment> {
) -> TextParseResult<Alignment> {
expect_byte(&tokens.extract()?, b'[')?;
let u_x = expect_float(&tokens.extract()?)?;
let u_y = expect_float(&tokens.extract()?)?;
Expand All @@ -222,26 +221,26 @@ fn parse_valve_alignment<R: Read>(
})
}

fn expect_byte(token: &Option<Token>, byte: u8) -> error::TextParseResult<()> {
fn expect_byte(token: &Option<Token>, byte: u8) -> TextParseResult<()> {
match token.as_ref() {
Some(payload) if payload.match_byte(byte) => Ok(()),
Some(payload) => Err(error::TextParse::from_parser(
Some(payload) => Err(TextParseError::from_parser(
format!(
"Expected `{}`, got `{}`",
char::from(byte),
payload.text_as_string()
),
payload.line_number,
)),
_ => Err(error::TextParse::eof()),
_ => Err(TextParseError::eof()),
}
}

fn expect_byte_or(
token: &Option<Token>,
byte: u8,
rest: &[u8],
) -> error::TextParseResult<()> {
) -> TextParseResult<()> {
match token.as_ref() {
Some(payload) if payload.match_byte(byte) => Ok(()),
Some(payload) => {
Expand All @@ -252,7 +251,7 @@ fn expect_byte_or(
.collect::<Vec<_>>()[..]
.join(", ");

Err(error::TextParse::from_parser(
Err(TextParseError::from_parser(
format!(
"Expected {} or `{}`, got `{}`",
rest_str,
Expand All @@ -262,31 +261,31 @@ fn expect_byte_or(
payload.line_number,
))
}
_ => Err(error::TextParse::eof()),
_ => Err(TextParseError::eof()),
}
}

fn expect_quoted(token: &Option<Token>) -> error::TextParseResult<()> {
fn expect_quoted(token: &Option<Token>) -> TextParseResult<()> {
match token.as_ref() {
Some(payload) if payload.match_quoted() => Ok(()),
Some(payload) => Err(error::TextParse::from_parser(
Some(payload) => Err(TextParseError::from_parser(
format!("Expected quoted, got `{}`", payload.text_as_string()),
payload.line_number,
)),
_ => Err(error::TextParse::eof()),
_ => Err(TextParseError::eof()),
}
}

fn expect_float(token: &Option<Token>) -> error::TextParseResult<f64> {
fn expect_float(token: &Option<Token>) -> TextParseResult<f64> {
match token.as_ref() {
Some(payload) => match f64::from_str(&payload.text_as_string()) {
Ok(num) => Ok(num),
Err(_) => Err(error::TextParse::from_parser(
Err(_) => Err(TextParseError::from_parser(
format!("Expected number, got `{}`", payload.text_as_string()),
payload.line_number,
)),
},
None => Err(error::TextParse::eof()),
None => Err(TextParseError::eof()),
}
}

Expand Down
29 changes: 3 additions & 26 deletions src/qmap/repr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ extern crate alloc;
#[cfg(feature = "std")]
use std::{
collections::HashMap,
error,
ffi::{CStr, CString},
fmt,
fmt::{Display, Formatter},
io,
string::String,
vec::Vec,
Expand All @@ -22,6 +19,9 @@ use {
core::ffi::CStr, hashbrown::HashMap,
};

#[cfg(feature = "std")]
use crate::{WriteAttempt, WriteError};

/// Return type for validating writability of entities and other items
pub type ValidationResult = Result<(), String>;

Expand All @@ -36,29 +36,6 @@ pub trait CheckWritable {
fn check_writable(&self) -> ValidationResult;
}

#[cfg(feature = "std")]
#[derive(Debug)]
pub enum WriteError {
Validation(String),
Io(std::io::Error),
}

#[cfg(feature = "std")]
impl Display for WriteError {
fn fmt(&self, formatter: &mut Formatter) -> Result<(), fmt::Error> {
match self {
Self::Validation(msg) => write!(formatter, "Validation: {}", msg),
Self::Io(err) => write!(formatter, "I/O: {}", err),
}
}
}

#[cfg(feature = "std")]
impl error::Error for WriteError {}

#[cfg(feature = "std")]
pub type WriteAttempt = Result<(), WriteError>;

/// 3-dimensional point used to determine the half-space a surface lies on
pub type Point = [f64; 3];
pub type Vec3 = [f64; 3];
Expand Down
Loading
Loading