simply_result

A lightweight Result type for Dart.

style: very good analysis coverage


Features

  • Functional Result type
  • Success / Error modeling
  • Functional helpers (map, flatMap, zip)
  • Async helpers
  • Zero dependencies
  • High test coverage

API Index

Quick dictionary of all helpers available in simply_result.

Installation

dependencies:
  simply_result: ^1.0.0

API


Constructors

success(value)

Creates a successful result containing a value.

Use it when an operation completes correctly.

final result = success(10);
print(result); // → Success(10)

// or

final result = Res.success(10)
print(result); // → Success(10)

error(err)

Creates a failed result containing an error.

Useful for returning failures without throwing exceptions.

final result = error("network failure");
print(result); // → Error(network failure)

// or

final result = Res.error("network failure");
print(result); // → Error(network failure)

Res.unit()

Creates a success result containing null. Useful when the operation has no meaningful return value.

final result = Res.unit(); 
// Same as `Success(null) or success(null)`

print(result); // → Success(null)

Core

map

Transforms the value only if the result is Success. If the result is Error, it is propagated unchanged.

final result = success(5)
    .map((v) => v * 2);

print(result);
// → Success(10)

Error propagation:

final result = error("fail")
    .map((v) => v * 2);

print(result);
// → Error(fail)

flatMap

Chains operations that also return a Res.

Useful for composing multiple fallible operations.

final result = success(5)
    .flatMap((v) => success(v * 2));

print(result);
// → Success(10)

Error propagation:

final result = error("fail")
    .flatMap((v) => success(v * 2));

print(result);
// → Error(fail)

mapError

Transforms the error value without touching the success value.

final result = error("network")
    .mapError((e) => "Error: $e");

print(result);
// → Error(Error: network)

fold

Handles both success and error cases, returning a single value.

final result = success(10).fold(
  (value) => "Value: $value",
  (err) => "Error: $err",
);

print(result);
// → Value: 10

With error:

final result = error("fail").fold(
  (value) => "Value: $value",
  (err) => "Error: $err",
);

print(result);
// → Error: fail

Recovery

getOrElse

Returns the value if success, otherwise returns a fallback.

final value = success(10)
    .getOrElse((_) => 0);

print(value);
// → 10

With error:

final value = error("fail")
    .getOrElse((_) => 0);

print(value);
// → 0

recover

Transforms an error into a success by applying a recovery function.

If the result is already a success, it is returned unchanged.

final result = error("fail")
    .recover((_) => 42);

print(result);
// → Success(42)

If the result is already a success:

final result = success(10)
    .recover((_) => 42);

print(result);
// → Success(10)

Unlike getOrElse, this method keeps the value wrapped in Res.


Async

mapAsync

Asynchronous version of map.

final result = await success(5)
    .mapAsync((v) async => v * 2);

print(result);
// → Success(10)

flatMapAsync

Asynchronous version of flatMap.

final result = await success(5)
    .flatMapAsync((v) async => success(v * 2));

print(result);
// → Success(10)

Side effects

tap

Executes side-effect on success.

success(10).tap(print);

tapError

Executes side-effect on error.

error("fail").tapError(print);

Mapping helpers

mapOr

Returns a fallback if Error.

final result = error("fail")
    .mapOr(0, (v) => v * 2);

mapOrElse

Lazy fallback for Error.

final result = error("fail")
    .mapOrElse(
      (e) => -1,
      (v) => v * 2,
    );

Filters

filter

Fails if predicate does not match.

final result = success(10)
    .filter((v) => v > 5, "too small");

exists

Checks predicate on success.

success(10).exists((v) => v > 5);

contains

Checks equality on success.

success(10).contains(10);

Conversions

toNullable

Converts to nullable value.

success(10).toNullable(); // 10
error("fail").toNullable(); // null

Try

tryCatch

Wraps sync code.

final result = Res.tryCatch(
  () => int.parse("10"),
  (e, _) => e.toString(),
);

asyncTry

Wraps async code.

final result = await Res.asyncTry(
  () async => 10,
  (e, _) => e.toString(),
);

Guards

fromNullable

Creates result from nullable.

final result = Res.fromNullable(null, "error");

fromBool

Creates result from condition.

final result = Res.fromBool(false, "fail");

Collections

combine

Combines multiple results.

final result = Res.combine([
  success(1),
  success(2),
]);

sequence

Runs futures sequentially.

final result = await Res.sequence([
  Future.value(success(1)),
  Future.value(success(2)),
]);

parallel

Runs futures in parallel.

final result = await Res.parallel([
  Future.value(success(1)),
  Future.value(success(2)),
]);

traverse

Maps and sequences.

final result = await Res.traverse(
  [1, 2, 3],
  (n) async => success(n * 2),
);

Zip

zip

Combines two results into one.

final result = Res.zip(
  success(2),
  success(3),
);

print(result);
// → Success((2, 3))

zip3

Combines three results.

final result = Res.zip3(
  success(2),
  success(3),
  success(5),
);

print(result);
// → Success((2, 3, 5))

zip4

Combines four results.

final result = Res.zip4(
  success(1),
  success(2),
  success(3),
  success(4),
);

Advanced

flatten

Flattens nested results.

final result = Res.flatten(
  success(success(10)),
);

Libraries

simply_result