Rust crate: Overloaded Literals to construct your datatypes without boilerplate and with compile-time validation.

Overview

overloaded_literals   Latest Version License requires tests_badge

Overloaded Literals to construct your datatypes without boilerplate and with compile-time validation.

Features

  • Compile-time validation of literals (with decent compiler errors)
    • Supports bool, signed and unsigned integers, floats and &'static str.
  • Construct your types without ceremony or boilerplate.
  • 100% no_std compatible.
  • Runs on stable rust. MSRV: 1.65.0

Ships with implementations for std's various NonZero and Wrapping structs and CStr.

Usage

Add the overloaded_literals attribute to a function. This will rewrite any literals to calls to a trait with the literal as generic const parameter. Because a trait is used, construction of any desired target type which implements the type happens automatically:

use std::num::NonZeroI8;
use overloaded_literals::overloaded_literals;

#[overloaded_literals]
fn example() {
    let three: NonZeroI8 = 3;
    let result = three.saturating_mul(2); // <- This '2' also turns into a `NonZero` automatically because of the signature of `saturating_mul`.
    let six = 6; // <- And this '6' as well
    assert_eq!(result, six);
}
example()

Trait implementations can perform compile-time validation (using 'const evaluation') on the passed literal. This means that invalid literals are rejected at compile-time with a descriptive error message:

use std::num::NonZeroI8;
use overloaded_literals::overloaded_literals;

#[overloaded_literals]
fn mistake() -> NonZeroI8 {
    let oops: NonZeroI8 = 0; // <- compile error 'NonZero integer literal was 0'.
    oops.saturating_mul(2)
}
mistake();

Implementing the traits

As an example, here are the trait implementations for a type EvenI32 which ensures that the value it stores is even, similarly to how NonZeroI32 ensures that the contained value is non-zero.

use overloaded_literals::{overloaded_literals, FromLiteralUnsigned, FromLiteralSigned};

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct EvenI32(i32);

impl EvenI32 {
    fn new(val: i32) -> Option<Self> {
        if val % 2 != 0 {
            None
        } else {
            Some(EvenI32(val))
        }
    }
}

// Called for 0 and positive literals:
impl<const LIT: u128> FromLiteralUnsigned<LIT> for EvenI32 {
    const VALID_LITERAL: u128 = {
        if LIT % 2 != 0 {
            panic!("Odd EvenI32 integer literal")
        } else {
            LIT
        }
    };
    fn into_self() -> Self {
        let raw = <Self as FromLiteralUnsigned<LIT>>::VALID_LITERAL as i32;
        EvenI32(raw)
    }
}

// Called for negative literals:
impl<const LIT: i128> FromLiteralSigned<LIT> for EvenI32 {
    const VALID_LITERAL: i128 = {
        if LIT % 2 != 0 {
            panic!("Odd EvenI32 integer literal")
        } else {
            LIT
        }
    };
    fn into_self() -> Self {
        let raw = <Self as FromLiteralSigned<LIT>>::VALID_LITERAL as i32;
        EvenI32(raw)
    }
}


#[overloaded_literals]
fn example() {
    let x: EvenI32 = 100;
    // let y: EvenI32 = 7; // <- This would cause a compile error :-)
}
example()

Another full example, on how to accept a str literal for your datatype, can be found in the documentation of FromLiteralStr.

Missing features

The following features are currently missing and would be straightforward additions to later versions of the library:

  • Support for char literals
  • Support for raw byte str literals (Requires a similar abstraction as TypeStr.)
You might also like...
Recipes for avoiding bounds checks in Rust, without unsafe!

Recipes for avoiding bounds checks in Rust This repository showcases various approaches to avoiding bounds checks in Rust code, without unsafe code. E

Fast and simple datetime, date, time and duration parsing for rust.

speedate Fast and simple datetime, date, time and duration parsing for rust. speedate is a lax† RFC 3339 date and time parser, in other words, it pars

Parses a relative time string and returns a `Duration`

humantime_to_duration A Rust crate for parsing human-readable relative time strings and converting them to a Duration. Features Parses a variety of hu

Omeglib, a portmanteau of "omegle" and "library", is a crate for interacting with omegle, simply and asynchronously

Omeglib, a portmanteau of "omegle" and "library", is a crate for interacting with omegle, simply and asynchronously. It is intended to suit one's every requirement regarding chat on omegle.

Safe, comp time generated queries in rust

query_builder For each struct field following methods will be generated. All fields where_FIELDNAME_eq Numeric fields where_FIELDNAME_le where_FIELDNA

Simple time handling in Rust

time Documentation: latest release main branch book Minimum Rust version policy The time crate is guaranteed to compile with any release of rustc from

Time to dive into Rust!

Lets-Learn-Rust Time to dive into Rust! Day 1 Installation Running a Simple Rust Program Managing Projects with Cargo Basic Programming - Comments and

🦀 A Rust CLI to find the optimal time to meet given a when2meet URL

when3meet 🦀 The Rust when2meet CLI Install | Usage | Contributing & Issues | Docs Built with ❤️ and 🦀 by Garrett Ladley Install cargo install when3m

Rust on ESP32 STD "Hello, World" app. A "Hello, world!" STD binary crate for the ESP32[XX] and ESP-IDF.

Rust on ESP32 STD "Hello, World" app A "Hello, world!" STD binary crate for the ESP32[XX] and ESP-IDF. This is the crate you get when running cargo ne

Rust crate for obfuscating string literals.

Obfustring This crate provides a obfuscation macro for string literals. This makes it easy to protect them from common reverse engineering attacks lik

null 7 Mar 1, 2023
Simple and fast proxy checker that include protocol validation;

Open Proxies ⭐️ Leave me a start please ⭐️ it will motivate me to continue maintaining and adding futures About | Technologies | Requirements | Starti

kmoz000 3 Nov 29, 2022
Compile-time stuff and other goodies for rustaceans 🦀

?? bagel: Always baked, never fried bagel is a collection of macros and other things that we frequently use at Skytable, primarily to get work done at

Skytable 3 Jul 4, 2022
Compile time static maps for Rust

Rust-PHF Documentation Rust-PHF is a library to generate efficient lookup tables at compile time using perfect hash functions. It currently uses the C

null 1.3k Jan 1, 2023
A rust crate can find first `Err` in `Iterator>` and iterating continuously, without allocation.

Api Document first-err Find the first Err in Iterator<Result<T, E>> and allow iterating continuously. This crate is specifically designed to replace t

null 3 Oct 28, 2023
A minimal boilerplate for Astro / Vite with the Nannou creative framework (Rust → WASM). Supports multiple sketches + hot-reload.

Astro x Nannou Starter astro-nannou-demo-1c.mov ?? Try it online! # 0a. Rust language tools open https://www.rust-lang.org/tools/install # 0b. wasm-p

Julian Cataldo 4 Jan 4, 2023
High-order Virtual Machine (HVM) is a pure functional compile target that is lazy, non-garbage-collected and massively parallel

High-order Virtual Machine (HVM) High-order Virtual Machine (HVM) is a pure functional compile target that is lazy, non-garbage-collected and massivel

null 5.5k Jan 2, 2023
Mindful Time Tracking: Simplify Your Focus and Boost Productivity Effortlessly.

Mindful Time Tracking: Simplify Your Focus and Boost Productivity Effortlessly. About pace is a mindful productivity tool designed to help you keep tr

pace 6 Mar 1, 2024
A typemap for a set of known types optionally without heap allocation, and supporting iterating by traits

fixed_typemap docs.rs GitHub Sponsors Implements typemaps that support a lot of extra funcctionality using procedural macros. docs.rs has a lot more t

Austin Hicks 2 Dec 27, 2021
Rust-only ext4 implementation without unsafe code.

Rust-Ext4 Rust-only ext4 implementation without unsafe code. Supporting features no_std Direct/Indirect Block Addressing (RO) Extent Tree Addressing (

null 7 Dec 5, 2022