Choose Rust types at compile-time via boolean constants

Overview

condtype

docs.rs crates.io github

Choose Rust types at compile-time via boolean constants, brought to you by Nikolai Vazquez.

If you find this library useful, consider starring it as well as sponsoring or donating once. 💖

Conditional Typing

The CondType type and condval! macro choose types at compile-time using bool constants, just like std::conditional_t in C++. Unlike the Either type, the type chosen by CondType/condval! is directly used, rather than wrapped with an enum type. This may be considered a form of dependent typing, but it is limited in ability and is restricted to compile-time constants rather than runtime values.

Examples

In the following example, CondType aliases either &str or i32, depending on the boolean generic constant:

use condtype::CondType;

let str: CondType<true,  &str, i32> = "hello";
let int: CondType<false, &str, i32> = 42;

// Unsized types are also supported:
let str: &CondType<true, str, [u8]> = "world";

condval! enables choosing differently-typed values without specifying types. In the following example, val is inferred to be either &str or i32, depending on COND.

use condtype::condval;

const COND: bool = true;

let val = condval!(if COND {
    "hello"
} else {
    42
});

assert_eq!(val, "hello");

Platform-Specific Types

This library can make code for some platforms more efficient by using smaller-sized types, depending on platform-specific constants.

In the following example, the RlimOption type can be either Option<rlim_t> or rlim_t itself, where rlim_t::MAX can be treated as a sentinel value for Option::None if it is not equal to RLIM_INFINITY.

use condtype::{condval, CondType};
use libc::{rlim_t, RLIM_INFINITY};

const RLIM_INFINITY_IS_MAX: bool = RLIM_INFINITY == rlim_t::MAX;

type RlimOption = CondType<RLIM_INFINITY_IS_MAX, Option<rlim_t>, rlim_t>;

const RLIM_NONE: RlimOption = condval!(if RLIM_INFINITY_IS_MAX {
    None::<rlim_t>
} else {
    rlim_t::MAX
});

// Convert from either `RlimOption` type to `Option` via the `Into` trait:
let rlim_none: Option<rlim_t> = RLIM_NONE.into();

Without this library, one could otherwise use cfg_if! to achieve the same goal. However, using #[cfg] requires maintaining a list of platforms and being more fine-grained if RLIM_INFINITY is dependent on CPU architecture.

use cfg_if::cfg_if;
use libc::rlim_t;

cfg_if! {
    // Platforms where `RLIM_INFINITY != rlim_t::MAX`:
    if #[cfg(any(
        target_os = "macos",
        target_os = "freebsd",
        target_os = "solaris",
        // ad nauseam...
    ))] {
        type RlimOption = rlim_t;
        const RLIM_NONE: RlimOption = rlim_t::MAX;
    } else {
        type RlimOption = Option<rlim_t>;
        const RLIM_NONE: RlimOption = None;
    }
}

Limitations

It is currently not possible to use CondType or condval! with a generic constant because Rust does not yet consider trait implementations based on booleans to be exhaustive. Once that issue is resolved, all versions of this library should just work with generic constants.

fn generic<const B: bool>() {
    let val: CondType<B, &str, i32> = condval!(if B {
        "hello"
    } else {
        42
    });
}

Install

This library is available on crates.io and can be used by running the following cargo command in your project directory:

cargo add condtype

or by manually adding the following to your project's Cargo.toml:

[dependencies]
condtype = "1.1.0"

License

Like the Rust project, this library may be used under either the MIT License or Apache License (Version 2.0).

You might also like...
tidy-builder is a builder generator that is compile-time correct.
tidy-builder is a builder generator that is compile-time correct.

The Builder derive macro creates a compile-time correct builder which means that it only allows you to build the given struct if and only if you provi

Stockbook embeds 1-bit raster images in your code at compile time

stockbook Stockbook embeds 1-bit raster images in your code at compile time. Designed primarily for #![no_std] usage, in embedded or other program-mem

Catch Tailwindcss Errors  at Compile-Time Before They Catch You, without making any change to your code!  Supports overriding, extending, custom classes, custom modifiers, Plugins and many more 🚀🔥🦀
Catch Tailwindcss Errors at Compile-Time Before They Catch You, without making any change to your code! Supports overriding, extending, custom classes, custom modifiers, Plugins and many more 🚀🔥🦀

twust Twust is a powerful static checker in rust for TailwindCSS class names at compile-time. Table of Contents Overview Installation Usage Statement

belt is a command line app that can show your time from a list of selected time zones

A CLI app to show your time from a list of selected time zones, and a rust lib to parse dates in string formats that are commonly used.

Deadliner helps you keep track of the time left for your deadline by dynamically updating the wallpaper of your desktop with the time left.
Deadliner helps you keep track of the time left for your deadline by dynamically updating the wallpaper of your desktop with the time left.

Deadliner Watch the YouTube video What's Deadliner? Deadliner is a cross-platform desktop application for setting deadline for a project and keeping t

Helps you keep track of time for team members across different time zones & DST changes

Teamdate Helps you keep track of time for team members across different timezones and other daylight saving changes based off their location. Because

compile TypeScript or JavaScript to binaries

the powr project Development is paused until 2023. 🥳 powr aims to be a javascript/typescript engine to power serverless functions over the web. the j

A series of crates that I made to compile images/video into asciinema & play them.

Bad Apple A series of crates that I made to compile images/video into asciinema & play them. The end goal is to make a kernel & legacy bootloader that

Evaluate performance gains to expect when EVM were to compile hot contracts into machine code

Convert evm bytecode to native machine code and go vroom - just an experiment, probably broken, reach out to [email protected] to contribute / productionize.

Releases(v1.1.0)
Owner
Nikolai Vazquez
conducts curses, breaks things, and uses the oxford comma
Nikolai Vazquez
This is choose, a human-friendly and fast alternative to cut and (sometimes) awk

Choose This is choose, a human-friendly and fast alternative to cut and (sometimes) awk Features terse field selection syntax similar to Python's list

Ryan Geary 1.4k Jan 7, 2023
Calculation of Wigner symbols and related constants

Calculation of Wigner symbols and related constants This crate computes Wigner 3j coefficients and Clebsch-Gordan coefficients in pure Rust. The calcu

Guillaume Fraux 3 Jan 19, 2022
Sysexits-rs (sysexits) is a library that provides the system exit code constants

sysexits-rs sysexits-rs (sysexits) is a library that provides the system exit code constants as defined by <sysexits.h>. This library implements the T

Shun Sakai 7 Dec 15, 2022
Game of life rendered in your terminal with over 500+ unique patterns to choose from.

Controls a: play animation n: next generation s: stop j or down arrow: go down next pattern (note: you have to stop the animation to browse the patter

Omar Magdy 20 Dec 22, 2022
The paradox that we both choose grace and are chosen by grace is the essence of the phenomenon of serendipity.

grace macOS only for now. You'll need: Deepgram API key: https://console.deepgram.com Log into your Deepgram account, if you already have one, or crea

null 3 Feb 26, 2024
🧮 Boolean expression evaluation engine. A Rust port of boolrule.

coolrule My blog post: Porting Boolrule to Rust Boolean expression evaluation engine (a port of boolrule to Rust). // Without context let expr = coolr

Andrew Healey 3 Aug 21, 2023
Supporting code for the paper "Optimized Homomorphic Evaluation of Boolean Functions" submitted to Eurocrypt 2024

This repository contains the code related to the paper Optimized Homomorphic Evaluation of Boolean Functions. The folder search_algorithm contains the

CryptoExperts 3 Oct 23, 2023
Rust library to convert RGB 24-bit colors into ANSI 256 (8-bit) color codes with zero dependencies and at compile-time.

rgb2ansi256 rgb2ansi256 is a small Rust library to convert RGB 24-bit colors into ANSI 256 (8-bit) color codes with zero dependencies and const fn. Th

Linda_pp 7 Nov 17, 2022
A strong, compile-time enforced authorization framework for rust applications.

DACquiri A compile-time enforced authorization framework for Rust applications. Authorization In typical applications, authorization checks are perfor

resync 247 Dec 20, 2022
ChatGPT powered Rust proc macro that generates code at compile-time.

gpt-macro ChatGPT powered Rust proc macro that generates code at compile-time. Implemented Macros auto_impl!{} #[auto_test(...)] Usage Get ChatGPT API

Akira Moroo 429 Apr 15, 2023