philiprehberger_result_type 0.3.0
philiprehberger_result_type: ^0.3.0 copied to clipboard
Rust-style Result type for type-safe error handling with pattern matching
philiprehberger_result_type #
Rust-style Result type for type-safe error handling with pattern matching.
Requirements #
- Dart SDK ^3.6.0
Installation #
dependencies:
philiprehberger_result_type: ^0.3.0
dart pub get
Usage #
import 'package:philiprehberger_result_type/philiprehberger_result_type.dart';
Result<int, String> divide(int a, int b) {
if (b == 0) return Result.err('Division by zero');
return Result.ok(a ~/ b);
}
Pattern Matching #
final result = divide(10, 2);
final message = result.when(
ok: (value) => 'Result: $value',
err: (error) => 'Error: $error',
);
print(message); // Result: 5
Transformations #
// Map success values
final doubled = Result<int, String>.ok(5).map((v) => v * 2);
print(doubled); // Ok(10)
// Chain operations
final chained = Result<int, String>.ok(10)
.flatMap((v) => v > 0 ? Result.ok(v) : Result.err('must be positive'));
// Transform errors
final mapped = Result<int, String>.err('not found')
.mapErr((e) => 'Error: $e');
Async Error Handling #
final result = await Result.tryAsync(
() async => fetchDataFromApi(),
(error, stack) => 'Request failed: $error',
);
Collecting Results #
final results = [Result<int, String>.ok(1), Result.ok(2), Result.ok(3)];
final collected = Result.collect(results);
print(collected); // Ok([1, 2, 3])
final mixed = [Result<int, String>.ok(1), Result.err('bad')];
final failed = Result.collect(mixed);
print(failed); // Err(bad)
Unwrapping #
final ok = Result<int, String>.ok(42);
print(ok.unwrap()); // 42
print(ok.unwrapOr(0)); // 42
final err = Result<int, String>.err('fail');
print(err.unwrapOr(0)); // 0
// err.unwrap(); // throws StateError
Unwrap with Lazy Default #
final result = Err<int, String>('missing');
final value = result.unwrapOrElse((e) => e.length);
print(value); // 7
Expect #
final result = Result<int, String>.ok(42);
print(result.expect('value must exist')); // 42
// On Err, throws StateError with custom message:
// Result<int, String>.err('fail').expect('value must exist');
Sync Error Handling #
final result = Result.trySync(
() => int.parse('42'),
(error) => 'parse failed: $error',
);
print(result); // Ok(42)
Filtering #
final result = Result<int, String>.ok(5)
.filter((v) => v > 0, (v) => 'expected positive, got $v');
print(result); // Ok(5)
final filtered = Result<int, String>.ok(-1)
.filter((v) => v > 0, (v) => 'expected positive, got $v');
print(filtered); // Err(expected positive, got -1)
Flattening Nested Results #
final nested = Result<Result<int, String>, String>.ok(Result.ok(42));
final flat = Result.flatten(nested);
print(flat); // Ok(42)
final nestedErr = Result<Result<int, String>, String>.err('outer error');
final flatErr = Result.flatten(nestedErr);
print(flatErr); // Err(outer error)
Zipping Results #
final a = Result<int, String>.ok(1);
final b = Result<int, String>.ok(2);
final zipped = Result.zip(a, b);
print(zipped); // Ok((1, 2))
API #
Result<T, E> #
| Member | Description |
|---|---|
Result.ok(T value) |
Create a success result |
Result.err(E error) |
Create a failure result |
isOk |
Whether this is an Ok result |
isErr |
Whether this is an Err result |
okOrNull |
Success value or null |
errOrNull |
Error value or null |
unwrap() |
Get value or throw StateError |
unwrapOr(T default) |
Get value or return default |
unwrapOrElse(T Function(E) fn) |
Get value or compute default from error |
expect(String message) |
Get value or throw StateError with message |
map(U Function(T) f) |
Transform success value |
mapErr(F Function(E) f) |
Transform error value |
flatMap(Result<U,E> Function(T) f) |
Chain Result-producing operation |
filter(predicate, orElse) |
Keep Ok if predicate passes, else convert to Err |
when({ok, err}) |
Exhaustive pattern match |
Result.trySync(fn, onError) |
Wrap sync operation into Result |
Result.tryAsync(fn, onError) |
Wrap async operation into Result |
Result.collect(results) |
Combine list of Results |
Result.flatten(nested) |
Unwrap nested Result<Result<T,E>,E> into Result<T,E> |
Result.zip(a, b) |
Combine two Results into a record |
Ok<T, E> #
Success variant. Holds a value of type T. All transformation methods operate on the value.
Err<T, E> #
Failure variant. Holds an error of type E. Transformation methods like map and flatMap pass through the error unchanged.
Development #
dart pub get
dart analyze --fatal-infos
dart test
Support #
File issues on GitHub.
License #
MIT - see LICENSE for details.