#options #boolean #conversion #extension #result

no-std fool

Traits for interoperation of Boolean and sum types

4 releases

0.0.4 Aug 28, 2020
0.0.3 May 18, 2020
0.0.2 Aug 12, 2019
0.0.1 Nov 21, 2018

#2977 in Rust patterns


Used in plexus

MIT license

13KB
270 lines

Fool is a Rust library for interoperation of bool and the Option and Result sum types. Fool also provides macros for Boolean combinations of bool, Option, and Result types and does not require std.

GitHub docs.rs crates.io


lib.rs:

Traits for interoperation of bool and the Option and Result sum types.

Fool provides extension traits for bool and sum types as well as a Boolean coercion trait for Option and Result. BoolExt enables fluent conversion from bool into sum types. IntoBool enables compound Boolean predicates using bool, Option, and Result types with implicit conversion.

Versions in the 0.0.* series are experimental and unstable.

Generalized Zipping

In Rust 1.46, the Option::zip API was stabilized. Fool provides OptionExt::zip_ext for prior versions of Rust as well as a generalized zip function when the zip feature is enabled. The zip function accepts a tuple of up to six Options and collapses them into a single Option if all of the inputs are Some.

Collisions with Proposed core and std APIs

Some extension methods in BoolExt and OptionExt mirror unstable APIs and APIs added to core and std in subsequent releases of Rust. Fool avoids collisions with these APIs using a _ext postfix, but the bare names of these APIs can be included with the bare feature.

Use of bare extension methods can cause errors after upgrading to a Rust toolchain that includes these APIs, because the invocation may become ambiguous. For example, BoolExt::then_some_ext mirrors bool::then_some, which has not yet become a stable API at the time of this writing.

Examples

Using then_ext (or then with the bare feature flag) to create an Option from a Boolean expression:

use fool::BoolExt;
use std::collections::HashSet;

let mut set = HashSet::new();
set.insert(10u32);

let message = set.contains(&10u32).then_ext(|| "Contains 10!".to_owned());

Using ok_or_else and the try operator ? to return errors:

use fool::BoolExt;

struct Door {
    is_open: bool,
}

impl Door {
    pub fn close(&mut self) -> Result<(), ()> {
        self.is_open().ok_or_else(|| ())?;
        self.is_open = false;
        Ok(())
    }

    pub fn is_open(&self) -> bool {
        self.is_open
    }
}

Dependencies

~105KB