expected 0.1.1

Implementation of expected idiom for D


To use this package, run the following command in your project's root directory:

Manual usage
Put the following dependency into your project's dependences section:

Expected

Latest version Dub downloads Build status codecov license

Implementation of the Expected idiom.

See the Andrei Alexandrescu’s talk (Systematic Error Handling in C++ and its slides.

Or more recent "Expect the Expected" by Andrei Alexandrescu for further background.

It is also inspired by C++'s proposed std::expected and Rust's Result.

Similar work is expectations by Paul Backus.

Features

  • lightweight, no other external dependencies
  • works with pure, @safe, @nogc, nothrow, and immutable
  • provides methods: expected, unexpected, andThen, orElse, map, mapError, mapOrElse
  • type inference for ease of use with expected and unexpected
  • allows to use same types for T and E
  • allows to define Expected without value (void for T) - can be disabled with custom Hook
  • provides facility to change the Expected behavior by custom Hook implementation using the Design by introspection paradigm.
  • can enforce result check (with a cost)
  • can behave like a normal Exception handled code by changing the used Hook implementation
  • range interface

Documentation

View online on Github Pages

expected uses adrdox to generate it's documentation. To build your own copy, run the following command from the root of the expected repository:

path/to/adrdox/doc2 --genSearchIndex --genSource -o generated-docs source

Example usage

auto foo(int i) {
	if (i == 0) return unexpected!int("oops");
	return expected(42 / i);
}

auto bar(int i) {
	if (i == 0) throw new Exception("err");
	return i-1;
}

// basic checks
assert(foo(2));
assert(foo(2).hasValue);
assert(!foo(2).hasError);
assert(foo(2).value == 21);

assert(!foo(0));
assert(!foo(0).hasValue);
assert(foo(0).hasError);
assert(foo(0).error == "oops");

// void result
assert(Expected!(void)()); // no error -> success
assert(!Expected!(void)().hasError);
// assert(unexpected("foo").value); // doesn't have hasValue and value properties

// expected from throwing function
assert(expected!bar(1) == 0);
assert(expected!bar(0).error.msg == "err");

// orElse
assert(foo(2).orElse!(() => 0) == 21);
assert(foo(0).orElse(100) == 100);

// andThen
assert(foo(2).andThen(foo(6)) == 7);
assert(foo(0).andThen(foo(6)).error == "oops");

// map
assert(foo(2).map!(a => a*2).map!(a => a - 2) == 40);
assert(foo(0).map!(a => a*2).map!(a => a - 2).error == "oops");

// mapError
assert(foo(0).mapError!(e => "OOPS").error == "OOPS");
assert(foo(2).mapError!(e => "OOPS") == 21);

// mapOrElse
assert(foo(2).mapOrElse!(v => v*2, e => 0) == 42);
assert(foo(0).mapOrElse!(v => v*2, e => 0) == 0);

See documentation for more usage examples.

Installation

If you're using dub, add the expected package to your project as a dependency.

Alternatively, since it's a single file self-contained implementation, you can simply copy expected.d to your project source directory and compile as usual.

Compilers compatibility

Build is tested against:

  • dmd-2.086.0
  • dmd-2.085.1
  • dmd-2.084.1
  • dmd-2.083.1
  • dmd-2.082.1
  • dmd-2.081.2
  • dmd-2.080.1
  • dmd-2.079.1
  • dmd-2.078.3
  • dmd-2.077.1
  • dmd-2.076.1
  • ldc-1.15.0
  • ldc-1.14.0
  • ldc-1.13.0
  • ldc-1.12.0
  • ldc-1.11.0
  • ldc-1.10.0
  • ldc-1.9.0
  • ldc-1.8.0
  • ldc-1.7.0
  • ldc-1.6.0
  • dmd-beta
Authors:
  • Tomáš Chaloupka
Dependencies:
none
Versions:
0.4.0 2023-May-20
0.3.4 2021-Nov-14
0.3.3 2021-Nov-13
0.3.2 2021-Nov-09
0.3.1 2021-Oct-11
Show all 14 versions
Download Stats:
  • 20 downloads today

  • 64 downloads this week

  • 303 downloads this month

  • 13528 downloads total

Score:
2.9
Short URL:
expected.dub.pm