Skip to content

Commit

Permalink
Add 'assert' module and assertion errors
Browse files Browse the repository at this point in the history
  • Loading branch information
maxkofler committed Dec 9, 2023
1 parent 1eaa74e commit 9073461
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 2 deletions.
88 changes: 88 additions & 0 deletions src/assert.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
//! Assertion functions

use std::path::Path;

use crate::error::{
assert::{AssertionError, AssertionErrorType},
Error, Throwable,
};

/// Asserts that a path is relative
/// # Arguments
/// * `path` - The path to check
/// # Returns
/// The path or an assertion error
#[macro_export]
macro_rules! assert_relative {
($path: expr) => {
$crate::assert::assert_relative_raw($path, || (line!(), file!()))
};
}

/// Asserts that a path is relative
///
/// Consider using the `assert_relative!()` macro
/// # Arguments
/// * `path` - The path to check
/// * `callback` - The callback to provide the following tuple: (line, file)
/// # Returns
/// The path or an assertion error
pub fn assert_relative_raw<'a, F: Fn() -> (u32, &'a str)>(
path: &'a Path,
callback: F,
) -> Result<&'a Path, Error> {
if path.is_relative() {
Ok(path)
} else {
let info = callback();
let error = AssertionError {
error: AssertionErrorType::RelativePath(path.to_owned()),
line: info.0,
file: info.1.to_string(),
};
Err(error.throw(format!(
"Asserting '{}' is relative",
path.to_string_lossy()
)))
}
}

/// Asserts that a path is absolute
/// # Arguments
/// * `path` - The path to check
/// # Returns
/// The path or an assertion error
#[macro_export]
macro_rules! assert_absolute {
($path: expr) => {
$crate::assert::assert_absolute_raw($path, || (line!(), file!()))
};
}

/// Asserts that a path is absolute
///
/// Consider using the `assert_absolute!()` macro
/// # Arguments
/// * `path` - The path to check
/// * `callback` - The callback to provide the following tuple: (line, file)
/// # Returns
/// The path or an assertion error
pub fn assert_absolute_raw<'a, F: Fn() -> (u32, &'a str)>(
path: &'a Path,
callback: F,
) -> Result<&'a Path, Error> {
if path.is_absolute() {
Ok(path)
} else {
let info = callback();
let error = AssertionError {
error: AssertionErrorType::AbsolutePath(path.to_owned()),
line: info.0,
file: info.1.to_string(),
};
Err(error.throw(format!(
"Asserting '{}' is absolute",
path.to_string_lossy()
)))
}
}
6 changes: 5 additions & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ use std::collections::LinkedList;

use crate::{tools::builder::BuilderError, validators::ValidationError};

use self::support::TOMLError;
use self::{assert::AssertionError, support::TOMLError};

mod support;

pub mod assert;

/// The type of error at hand
#[derive(Debug)]
pub enum ErrorType {
Assert(AssertionError),
IO(std::io::Error),
ELFParse(elf::ParseError),
TOML(TOMLError),
Expand Down Expand Up @@ -76,6 +79,7 @@ impl Error {
impl std::fmt::Display for ErrorType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Assert(e) => e.fmt(f),
Self::IO(e) => e.fmt(f),
Self::ELFParse(e) => e.fmt(f),
Self::TOML(e) => e.fmt(f),
Expand Down
67 changes: 67 additions & 0 deletions src/error/assert.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//! Assertion errors
use std::path::PathBuf;

use crate::GIT_COMMIT_HASH;

/// An error for an assertion, includes the path to where the assertion has been made
#[derive(Debug)]
pub struct AssertionError {
/// The error
pub error: AssertionErrorType,
/// The line number where the assertion has been made
pub line: u32,
/// The file where the assertion has been made
pub file: String,
}

/// All the possible assertion errors
#[derive(Debug)]
pub enum AssertionErrorType {
/// A path was expected to be relative
RelativePath(PathBuf),
/// A path was expected to be absolute
AbsolutePath(PathBuf),
}

impl std::fmt::Display for AssertionError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let msg = match &self.error {
AssertionErrorType::RelativePath(path) => {
format!("Expected '{}' to be relative", path.to_string_lossy())
}
AssertionErrorType::AbsolutePath(path) => {
format!("Expected '{}' to be absolute", path.to_string_lossy())
}
};

let msg = format!(
"[GIT: {}] {}:{} - {}",
GIT_COMMIT_HASH, self.file, self.line, msg
);
let len = msg.len();

writeln!(f, "{}", msg)?;

writeln!(f, "!!!!{}!!!!", "!".repeat(len))?;
writeln!(
f,
"!! {:^width$} !!",
"ASSERTION ERROR - THIS IS A BUG!",
width = len
)?;
writeln!(
f,
"!! {:^width$} !!",
"Please report this error to",
width = len
)?;
writeln!(
f,
"!! {:^width$} !!",
"https://github.com/AcaciaLinux/tooling/issues",
width = len
)?;
writeln!(f, "!! {:^width$} !!", msg, width = len)?;
write!(f, "!!!!{}!!!!", "!".repeat(len))
}
}
17 changes: 16 additions & 1 deletion src/error/support.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
use super::{Error, ErrorExt, ErrorType, Throwable};
use super::{AssertionError, Error, ErrorExt, ErrorType, Throwable};

impl<T> ErrorExt<T> for Result<T, AssertionError> {
fn e_context<F: Fn() -> String>(self, context: F) -> Result<T, Error> {
match self {
Ok(v) => Ok(v),
Err(e) => Err(Error::new_context(ErrorType::Assert(e), context())),
}
}
}

impl Throwable for AssertionError {
fn throw(self, context: String) -> Error {
Error::new_context(ErrorType::Assert(self), context)
}
}

impl<T> ErrorExt<T> for Result<T, std::io::Error> {
fn e_context<F: Fn() -> String>(self, context: F) -> Result<T, Error> {
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
/// The commit hash of the commit this binary was built from
const GIT_COMMIT_HASH: &str = env!("GIT_COMMIT_HASH");

pub mod assert;
pub mod env;
pub mod error;
pub mod files;
Expand Down

0 comments on commit 9073461

Please sign in to comment.