Skip to content
Open
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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ name = "throw"
version = "0.1.7"
authors = ["David Ross <daboross@daboross.net>"]
description = "Efficiently add statically-calculated stack traces to errors."
edition = "2024"

documentation = "https://docs.rs/throw/"
repository = "https://github.com/daboross/rust-throw/"
Expand Down
2 changes: 1 addition & 1 deletion benches/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ fn throws_throw_ok() -> Result<&'static str, &'static str> {

#[inline(never)]
fn throws_try_ok() -> StdResult<&'static str, &'static str> {
let ok_msg = test::black_box(try!(gives_ok()));
let ok_msg = test::black_box(gives_ok()?);
Ok(ok_msg)
}

Expand Down
152 changes: 69 additions & 83 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(alloc))]
#![deny(missing_docs)]
#![warn(missing_docs)]
#![doc(html_root_url = "https://docs.rs/throw/0.1.7")]
//! Throw!
//! ------
Expand Down Expand Up @@ -223,14 +222,8 @@ use serde::ser::{Serialize, SerializeStruct, Serializer};

/// Types allowed to be value in the context vector
#[derive(Debug, Clone)]
#[cfg_attr(
any(feature = "serde-1", feature = "serde-1-std"),
derive(Serialize)
)]
#[cfg_attr(
any(feature = "serde-1", feature = "serde-1-std"),
serde(untagged)
)]
#[cfg_attr(any(feature = "serde-1", feature = "serde-1-std"), derive(Serialize))]
#[cfg_attr(any(feature = "serde-1", feature = "serde-1-std"), serde(untagged))]
pub enum ThrowContextValues {
/// Boolean context value
Bool(bool),
Expand Down Expand Up @@ -263,92 +256,92 @@ pub enum ThrowContextValues {
impl fmt::Display for ThrowContextValues {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ThrowContextValues::Bool(ref x) => write!(f, "{}", x),
ThrowContextValues::Int8(ref x) => write!(f, "{}", x),
ThrowContextValues::Uint8(ref x) => write!(f, "{}", x),
ThrowContextValues::Int16(ref x) => write!(f, "{}", x),
ThrowContextValues::Uint16(ref x) => write!(f, "{}", x),
ThrowContextValues::Int32(ref x) => write!(f, "{}", x),
ThrowContextValues::Uint32(ref x) => write!(f, "{}", x),
ThrowContextValues::Int64(ref x) => write!(f, "{}", x),
ThrowContextValues::Uint64(ref x) => write!(f, "{}", x),
ThrowContextValues::Float32(ref x) => write!(f, "{}", x),
ThrowContextValues::Float64(ref x) => write!(f, "{}", x),
ThrowContextValues::String(ref x) => write!(f, "{}", x),
ThrowContextValues::StaticStr(ref x) => write!(f, "{}", x),
ThrowContextValues::Bool(ref x) => write!(f, "{x}"),
ThrowContextValues::Int8(ref x) => write!(f, "{x}"),
ThrowContextValues::Uint8(ref x) => write!(f, "{x}"),
ThrowContextValues::Int16(ref x) => write!(f, "{x}"),
ThrowContextValues::Uint16(ref x) => write!(f, "{x}"),
ThrowContextValues::Int32(ref x) => write!(f, "{x}"),
ThrowContextValues::Uint32(ref x) => write!(f, "{x}"),
ThrowContextValues::Int64(ref x) => write!(f, "{x}"),
ThrowContextValues::Uint64(ref x) => write!(f, "{x}"),
ThrowContextValues::Float32(ref x) => write!(f, "{x}"),
ThrowContextValues::Float64(ref x) => write!(f, "{x}"),
ThrowContextValues::String(ref x) => write!(f, "{x}"),
ThrowContextValues::StaticStr(ref x) => write!(f, "{x}"),
}
}
}

impl Into<ThrowContextValues> for u8 {
fn into(self) -> ThrowContextValues {
ThrowContextValues::Uint8(self)
impl From<u8> for ThrowContextValues {
fn from(val: u8) -> Self {
ThrowContextValues::Uint8(val)
}
}

impl Into<ThrowContextValues> for i8 {
fn into(self) -> ThrowContextValues {
ThrowContextValues::Int8(self)
impl From<i8> for ThrowContextValues {
fn from(val: i8) -> Self {
ThrowContextValues::Int8(val)
}
}

impl Into<ThrowContextValues> for u16 {
fn into(self) -> ThrowContextValues {
ThrowContextValues::Uint16(self)
impl From<u16> for ThrowContextValues {
fn from(val: u16) -> Self {
ThrowContextValues::Uint16(val)
}
}

impl Into<ThrowContextValues> for i16 {
fn into(self) -> ThrowContextValues {
ThrowContextValues::Int16(self)
impl From<i16> for ThrowContextValues {
fn from(val: i16) -> Self {
ThrowContextValues::Int16(val)
}
}

impl Into<ThrowContextValues> for u32 {
fn into(self) -> ThrowContextValues {
ThrowContextValues::Uint32(self)
impl From<u32> for ThrowContextValues {
fn from(val: u32) -> Self {
ThrowContextValues::Uint32(val)
}
}

impl Into<ThrowContextValues> for i32 {
fn into(self) -> ThrowContextValues {
ThrowContextValues::Int32(self)
impl From<i32> for ThrowContextValues {
fn from(val: i32) -> Self {
ThrowContextValues::Int32(val)
}
}

impl Into<ThrowContextValues> for u64 {
fn into(self) -> ThrowContextValues {
ThrowContextValues::Uint64(self)
impl From<u64> for ThrowContextValues {
fn from(val: u64) -> Self {
ThrowContextValues::Uint64(val)
}
}

impl Into<ThrowContextValues> for i64 {
fn into(self) -> ThrowContextValues {
ThrowContextValues::Int64(self)
impl From<i64> for ThrowContextValues {
fn from(val: i64) -> Self {
ThrowContextValues::Int64(val)
}
}

impl Into<ThrowContextValues> for f32 {
fn into(self) -> ThrowContextValues {
ThrowContextValues::Float32(self)
impl From<f32> for ThrowContextValues {
fn from(val: f32) -> Self {
ThrowContextValues::Float32(val)
}
}

impl Into<ThrowContextValues> for f64 {
fn into(self) -> ThrowContextValues {
ThrowContextValues::Float64(self)
impl From<f64> for ThrowContextValues {
fn from(val: f64) -> Self {
ThrowContextValues::Float64(val)
}
}

impl<'a> Into<ThrowContextValues> for &'static str {
fn into(self) -> ThrowContextValues {
ThrowContextValues::StaticStr(self)
impl From<&'static str> for ThrowContextValues {
fn from(val: &'static str) -> Self {
ThrowContextValues::StaticStr(val)
}
}

impl Into<ThrowContextValues> for String {
fn into(self) -> ThrowContextValues {
ThrowContextValues::String(self)
impl From<String> for ThrowContextValues {
fn from(val: String) -> Self {
ThrowContextValues::String(val)
}
}

Expand All @@ -357,10 +350,7 @@ pub type Result<T, E> = core::result::Result<T, Error<E>>;

/// Represents a location at which an error was thrown via throw!()
#[derive(Debug)]
#[cfg_attr(
any(feature = "serde-1", feature = "serde-1-std"),
derive(Serialize)
)]
#[cfg_attr(any(feature = "serde-1", feature = "serde-1-std"), derive(Serialize))]
pub struct ErrorPoint {
line: u32,
column: u32,
Expand Down Expand Up @@ -401,20 +391,17 @@ impl ErrorPoint {
file: &'static str,
) -> ErrorPoint {
ErrorPoint {
line: line,
column: column,
module_path: module_path,
file: file,
line,
column,
module_path,
file,
}
}
}

/// represent a key-value pair
#[derive(Debug, Clone)]
#[cfg_attr(
any(feature = "serde-1", feature = "serde-1-std"),
derive(Serialize)
)]
#[cfg_attr(any(feature = "serde-1", feature = "serde-1-std"), derive(Serialize))]
pub struct KvPair {
key: &'static str,
value: ThrowContextValues,
Expand All @@ -439,7 +426,6 @@ impl KvPair {

/// Represents an error. Stores an original error of type E, and any number of ErrorPoints at
/// which the error was propagated.

pub struct Error<E> {
points: Vec<ErrorPoint>,
context: Vec<KvPair>,
Expand Down Expand Up @@ -467,7 +453,7 @@ impl<E> Error<E> {
Error {
points: Vec::new(),
context: Vec::new(),
error: error,
error,
}
}

Expand Down Expand Up @@ -543,21 +529,21 @@ where
E: fmt::Display,
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
try!(write!(fmt, "Error: {}", self.error));
write!(fmt, "Error: {}", self.error)?;

for kv in self.context.iter().rev() {
try!(write!(fmt, "\n\t{}: {}", kv.key(), kv.value(),));
write!(fmt, "\n\t{}: {}", kv.key(), kv.value(),)?;
}

for point in self.points.iter().rev() {
try!(write!(
write!(
fmt,
"\n\tat {}:{} in {} ({})",
point.line(),
point.column(),
point.module_path(),
point.file()
));
)?;
}

Ok(())
Expand All @@ -569,19 +555,19 @@ where
E: fmt::Debug,
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
try!(write!(fmt, "Error: {:?}", self.error));
write!(fmt, "Error: {:?}", self.error)?;
for kv in self.context.iter().rev() {
try!(write!(fmt, "\n\t{}: {}", kv.key(), kv.value(),));
write!(fmt, "\n\t{}: {}", kv.key(), kv.value(),)?;
}
for point in self.points.iter().rev() {
try!(write!(
write!(
fmt,
"\n\tat {}:{} in {} ({})",
point.line(),
point.column(),
point.module_path(),
point.file()
));
)?;
}

Ok(())
Expand All @@ -591,13 +577,13 @@ where
#[cfg(feature = "std")]
impl<E> std::error::Error for Error<E>
where
E: std::error::Error
E: std::error::Error,
{
fn description(&self) -> &str {
self.error().description()
}

fn cause(&self) -> Option<&std::error::Error> {
fn cause(&self) -> Option<&dyn std::error::Error> {
Some(self.error())
}
}
Expand Down
5 changes: 1 addition & 4 deletions tests/exceptions_work.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ macro_rules! assert_matches {

assert!(
re.is_match(&actual),
format!(
"expected error to match regex `\n{}\n`, but found `\n{}\n`",
expected, actual
)
"expected error to match regex `\n{expected}\n`, but found `\n{actual}\n`",
);
}};
}
Expand Down