expected 0.1.0

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.

Main differences with that are:

  • lightweight, no other external dependencies
  • allows to use same types for T and E
  • allows to define Expected without value (void for T)
  • provides facility to change the Expected behavior by custom Hook implementation using the Design by introspection.
  • can enforce result check (with a cost)

Features

  • works with pure, @safe, @nogc, nothrow, and immutable
  • supports void value type
  • behavior configuration using custom Hook implementation and Design by introspection paradigm with safe default
  • provides methods: expected, unexpected, andThen, orElse, map, mapError, mapOrElse

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

Instalation

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.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:
  • 6 downloads today

  • 57 downloads this week

  • 257 downloads this month

  • 13766 downloads total

Score:
2.9
Short URL:
expected.dub.pm