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
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
refactor errors into crate root
  • Loading branch information
4LT committed Feb 16, 2024
commit 5169297f673198224cebd7fbe62f4d53a117fac0
33 changes: 26 additions & 7 deletions src/error/mod.rs
Original file line number Diff line number Diff line change
@@ -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,
@@ -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
@@ -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};
8 changes: 2 additions & 6 deletions src/qmap/mod.rs
Original file line number Diff line number Diff line change
@@ -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"),
@@ -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"))]
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())
}
}
@@ -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();

@@ -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)?;
@@ -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() {
@@ -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() {
@@ -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'{')?;

@@ -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()
@@ -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 {
@@ -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()?)?;
@@ -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()?)?;
@@ -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()?)?;
@@ -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) => {
@@ -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,
@@ -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()),
}
}

29 changes: 3 additions & 26 deletions src/qmap/repr.rs
Original file line number Diff line number Diff line change
@@ -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,
@@ -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>;

@@ -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];
Loading
Loading