Giter Club home page Giter Club logo

condtype's Introduction

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.

CondType

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!

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");

if let pattern matching is also supported:

use condtype::condval;

const STR: Option<&str> = Some("hello");

let val = condval!(if let Some(str) = STR {
    str.to_uppercase()
} 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.3.0"

License

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

condtype's People

Contributors

nvzqz avatar

Stargazers

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

Watchers

 avatar  avatar  avatar

condtype's Issues

Support `if`/`else` within `if` condition in `condval!`

The following Rust statement works:

let x = if if true { true } else { false } { "a" } else { "b" };

But the same wrapped in condval! does not parse:

error: expected `{`, found `}`
 --> src/main.rs:4:13
  |
4 |     let x = condval!(if if true { true } else { false } { "a" } else { "b" });
  |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{`
  |
note: the `if` expression is missing a block after this condition
 --> src/main.rs:4:28
  |
4 |     let x = condval!(if if true { true } else { false } { "a" } else { "b" });
  |                            ^^^^
  = note: this error originates in the macro `$crate::__condval_parser` which comes from the expansion of the macro `condval` (in Nightly builds, run with -Z macro-backtrace for more info)

error: no rules expected the token `{`
   --> src/main.rs:4:47
    |
4   |     let x = condval!(if if true { true } else { false } { "a" } else { "b" });
    |                                               ^ no rules expected this token in macro call
    |
note: while trying to match `if`
   --> condtype/src/lib.rs:212:6
    |
212 |     (if let $pat:pat = $input:block $then:block else $else:block) => {
    |      ^^

error: could not compile `condtype` (bin "condtype") due to 2 previous errors

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.