Crates.io | safe_math |
lib.rs | safe_math |
version | 2.0.0-beta |
source | src |
created_at | 2023-05-25 19:13:58.257773+00 |
updated_at | 2025-06-22 23:48:13.827922+00 |
description | Safe arithmetic using a procedural macro. Write normal math expressions with automatic overflow checks. No panics, no boilerplate. |
homepage | https://github.com/GotenJBZ/safe-math-rs |
repository | https://github.com/GotenJBZ/safe-math-rs |
max_upload_size | |
id | 874551 |
size | 61,691 |
A procedural macro-based library that transforms standard arithmetic operations into their checked equivalents at compile time, preventing overflow, underflow, and division by zero errors.
safe-math
provides:
Result
typesThe #[safe_math]
attribute transforms arithmetic operations into their checked equivalents:
use safe_math::safe_math;
#[safe_math]
fn add(a: u8, b: u8) -> Result<u8, safe_math::SafeMathError> {
Ok(a + b) // Automatically uses checked addition
}
assert_eq!(add(10, 20), Ok(30));
assert_eq!(add(255, 1), Err(safe_math::SafeMathError::Overflow));
All basic arithmetic operations are supported:
+
, +=
)-
, -=
)*
, *=
)/
, /=
)%
, %=
)Operations return SafeMathError
for exceptional cases:
pub enum SafeMathError {
Overflow, // Result exceeds type bounds
DivisionByZero, // Division or remainder by zero
InfiniteOrNaN, // Result is infinite or NaN (floating-point types)
NotImplemented, // Missing trait implementation (derive feature)
}
Built-in support for:
u8
through u128
, usize
i8
through i128
, isize
f32
, f64
(with infinity/NaN handling)Enable the derive
feature to implement safe arithmetic for custom types:
use safe_math::SafeMathOps;
#[derive(SafeMathOps)]
#[SafeMathOps(add, sub, mul, div, rem)]
struct MyNumber(u32);
#[safe_math]
fn calculate(a: MyNumber, b: MyNumber) -> Result<MyNumber, safe_math::SafeMathError> {
Ok(a + b)
}
Note: For the derive to work, your type must implement both the standard arithmetic traits
(like Add
, Sub
, Mul
, Div
, Rem
) and their checked counterparts (like CheckedAdd
,
CheckedSub
, CheckedMul
, CheckedDiv
, CheckedRem
) from the num-traits
crate.
This requirement exists because without knowing what a type represents, it's impossible to determine what operations are safe to perform or what constitutes a "checked" operation.
Use safe_math_block!
to apply checked operations to a specific block of code:
use safe_math::safe_math_block;
fn process_numbers(a: u32, b: u32, c: u32) -> Result<u32, safe_math::SafeMathError> {
// Only this block uses checked arithmetic
let result = safe_math_block!({
let product = a * b;
let sum = product + c;
sum / b
});
Ok(result)
}
This is useful when you want to:
Planned upcoming features:
Option-returning functions
Support for functions that return Option<T>
instead of Result<T, SafeMathError>
.
Crate-level macro support
Ability to apply #[safe_math]
to the entire crate with a single attribute:
// main.rs or lib.rs
#![safe_math]
fn demo(a: u32, b: u32) -> Result<u32, safe_math::SafeMathError> {
Ok(a * b + 1)
}
Licensed under either:
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you shall be dual licensed as above, without any additional terms or conditions.