#arithmetic #crypto #saturating #proc-macro #operator #equivalents #u32

macro saturating_arithmetic

Proc macro #[saturateit] to rewrite operators into their saturating equivalents

4 releases

0.1.3 Oct 1, 2020
0.1.2 Sep 30, 2020
0.1.1 Sep 30, 2020
0.1.0 Sep 30, 2020

#922 in Procedural macros

Apache-2.0

10KB
95 lines

Description

This crate provides a procedural macro that rewrites arithmetic operators +,-,* as well as their assigning versions +=,-=,*= into their saturating equivalents saturating_add, saturating_sub, saturating_mul. This is, for example, useful for quickly safening older code, if you can live with the performance penalty caused by the checks that is.

GitHub
Crates.io

Contents

Example

The following function

#[saturateit]
fn mix(a: u32, b: u32, c: &[u32]) -> u32 {
    let mut r = a + b;
    for u in c {
        r *= u;
    }
    r
}

is rewritten to

fn mix(a: u32, b: u32, c: &[u32]) -> u32 {
    let mut r = a.saturating_add(b);
    for u in c {
        r = r.saturating_mul(u);
    }
    r
}

Installation

To your Cargo.toml under [dependencies] add:

[dependencies]
saturating_arithmetic = "0.1"

# If you want this to work on your own types, you'll need this crate too:
num-traits = "0.2"

Then in your entry point (main.rs or lib.rs) add

extern crate saturating_arithmetic;
extern crate num_traits;

and then use them in your code.

use saturating_arithmetic::saturateit;
use num_traits::{SaturatingAdd, SaturatingMul, SaturatingSub};

Usage

Add #[saturateit] above your function body.

#[saturateit]
fn lmao_jeff() {
    4 + 4;
}

You can use something like cargo expand to check if the macro actually worked.

fn lmao_jeff() {
    4.saturating_add(4);
}

Warnings

If you are using the traits too, you may see a warning about having to borrow the right hand side of the operator, because the function signature according to the trait is saturating_add(&self, rhs: &Self) -> Self.
In my experience you can ignore these.



Disclaimer

I forked this from wrapping_arithmetic, because I needed it (kind of). I have not clue how this actually works besides procedural macro magic and those fat dependencies sure do something. Feel free to create an Issue or a PR, but I can't promise that I'll be able to help you.

Todo

In general the whole thing needs a redo to be more like overflower, but actively maintained and without any nightly features. I'm also unhappy with the whole trait thing, there has to be a way to make this all work reliably. For sure.

Dependencies

~1.5MB
~37K SLoC