Coder Social home page Coder Social logo

nonzero_ext's Introduction

nonzero_ext

Traits to represent generic nonzero integer types

Build status Docs

Rust ships with non-zero integer types now, which let programmers promise (memory-savingly!) that a number can never be zero. That's great, but sadly the standard library has not got a whole lot of tools to help you use them ergonomically.

A macro for non-zero constant literals

Creating and handling constant literals is neat, but the standard library (and the rust parser at the moment) have no affordances to easily create values of num::NonZeroU* types from constant literals. This crate ships a nonzero! macro that lets you write nonzero!(20u32), which checks at compile time that the constant being converted is non-zero, instead of the cumbersome (and runtime-checked!) NonZeroU32::new(20).unwrap().

Traits for generic non-zeroness

The stdlib num::NonZeroU* types do not implement any common traits (and neither do their zeroable equivalents). Where this lack of traits in the standard library becomes problematic is if you want to write a function that takes a vector of integers, and that returns a vector of the corresponding non-zero integer types, minus any elements that were zero in the original. You can write that with the standard library quite easily for concrete types:

fn only_nonzeros(v: Vec<u8>) -> Vec<NonZeroU8>
{
    v.into_iter()
        .filter_map(|n| NonZeroU8::new(n))
        .collect::<Vec<NonZeroU8>>()
}
let expected: Vec<NonZeroU8> = vec![nonzero!(20u8), nonzero!(5u8)];
assert_eq!(expected, only_nonzeros(vec![0, 20, 5]));

But what if you want to allow this function to work with any integer type that has a corresponding non-zero type? This crate can help:

fn only_nonzeros<I>(v: Vec<I>) -> Vec<I::NonZero>
where
    I: Sized + NonZeroAble,
{
    v.into_iter()
        .filter_map(|n| n.as_nonzero())
        .collect::<Vec<I::NonZero>>()
}

// It works for `u8`:
let input_u8: Vec<u8> = vec![0, 20, 5];
let expected_u8: Vec<NonZeroU8> = vec![nonzero!(20u8), nonzero!(5u8)];
assert_eq!(expected_u8, only_nonzeros(input_u8));

// And it works for `u32`:
let input_u32: Vec<u32> = vec![0, 20, 5];
let expected_u32: Vec<NonZeroU32> = vec![nonzero!(20u32), nonzero!(5u32)];
assert_eq!(expected_u32, only_nonzeros(input_u32));

License: Apache-2.0

nonzero_ext's People

Contributors

antifuchs avatar bors[bot] avatar dependabot-preview[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

rukai

nonzero_ext's Issues

nonzero! macro is not (yet) zero cost

Looking at the output of cargo asm on my application I can see function calls being generated from the nonzero macro
image

We could possibly add an #[inline(always)] but I dont think that will necessarily be enough, there might be more logic included.
To ensure it is actually zero cost we will need to make the macro generate code within a const context via rust-lang/rust#76001 once that is stabilized.

Make `as_nonzero_unchecked()` a const fn?

the new_unchecked() fn on the various NonZero types is a const fn, so I think if as_nonzero_unchecked() was as well, it would be possible to write things like:

const MY_NON_ZERO_U32: NonZeroU32 = nonzero!(42u32);

currently it gives the following compile error:

error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants

provide Ratelimiter type aliases?

Because of all the generics, storing a limiter in a struct is a bit verbose:

    cover_limiter: governor::RateLimiter<
        governor::state::NotKeyed,
        governor::state::InMemoryState,
        governor::clock::DefaultClock,
        governor::middleware::NoOpMiddleware,
    >,

Maybe we could type aliases for the common types like the one returned by RateLimiter::direct()?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.