dartsult 0.1.3 copy "dartsult: ^0.1.3" to clipboard
dartsult: ^0.1.3 copied to clipboard

A library implements Rust style [Result] for Dart error handle.

example/dartsult_example.dart

import 'package:dartsult/dartsult.dart';

class MockException implements Exception {
  final String msg;

  MockException(this.msg);

  @override
  String toString() {
    return 'MockException($msg)';
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) {
      return true;
    }
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is MockException && other.msg == msg;
  }

  @override
  int get hashCode => msg.hashCode;
}

Future<Result<Void, MockException>> voidResult(bool shouldPanic) async {
  return await mockLogic(null, 'cannot get void value',
          shouldPanic: shouldPanic)
      .then(
    (value) => Result.ok<Void, MockException>(Void()),
    onError: (error, stackTrace) => Result.error<Void, MockException>(
      error,
    ),
  );
}

Future<Result<int, MockException>> intResult(bool shouldPanic) async {
  return await mockLogic<int>(5, 'cannot get int value',
          shouldPanic: shouldPanic)
      .then(
    (value) => Result.ok<int, MockException>(value),
    onError: (error, stackTrace) => Result.error<int, MockException>(
      error,
    ),
  );
}

/// mockLogic is used to mock some network I/O, file I/O or other asynchronous
/// logic
Future<T> mockLogic<T>(T val, String msg, {bool shouldPanic = false}) {
  return Future.delayed(Duration(milliseconds: 100), () {
    if (shouldPanic) {
      throw MockException(msg);
    }
    return val;
  });
}

Result<int, int> sq(int x) {
  return Result.ok(x * x);
}

Result<int, int> err(int x) {
  return Result.error(x);
}

void unwrap() {
  Result<int, String> x = Result.ok(2);
  assert(x.unwrap() == 2);

  x = Result.error("emergency failure");
  try {
    x.unwrap();
  } catch (e) {
    assert(e.toString() == "Null check operator used on a null value");
  }
}

void unwrapError() {
  Result<int, String> x = Result.error("emergency failure");
  assert(x.unwrapError() == "emergency failure");

  x = Result.ok(2);
  try {
    x.unwrapError();
  } catch (e) {
    assert(e.toString() == "Null check operator used on a null value");
  }
}

void unwrapOr() {
  int defaultt = 2;
  Result<int, String> x = Result.ok(9);
  assert(x.unwrapOr(defaultt) == 9);

  x = Result.error("error");
  assert(x.unwrapOr(defaultt) == defaultt);
}

void unwrapOrElse() {
  int count(String x) {
    return x.length;
  }

  assert(Result.ok<int, String>(2).unwrapOrElse(count) == 2);
  assert(Result.error<int, String>("foo").unwrapOrElse(count) == 3);
}

void or() {
  Result<int, String> x = Result.ok(2);
  Result<int, String> y = Result.error("late error");
  assert(x.or(y) == Result.ok<int, String>(2));

  x = Result.error("early error");
  y = Result.ok(2);
  assert(x.or(y) == Result.ok<int, String>(2));

  x = Result.ok(2);
  y = Result.ok(100);
  assert(x.or(y) == Result.ok<int, String>(2));
}

void orElse() {
  assert(
      Result.ok<int, int>(2).orElse(sq).orElse(sq) == Result.ok<int, int>(2));
  assert(
      Result.ok<int, int>(2).orElse(err).orElse(sq) == Result.ok<int, int>(2));
  assert(Result.error<int, int>(3).orElse(sq).orElse(err) ==
      Result.ok<int, int>(9));
  assert(Result.error<int, int>(3).orElse(err).orElse(err) ==
      Result.error<int, int>(3));
}

void and() {
  Result<int, String> x = Result.ok(2);
  Result<String, String> y = Result.error("late error");

  assert(x.and(y) == Result.error<String, String>("late error"));

  x = Result.error("early error");
  y = Result.ok("foo");
  assert(x.and(y) == Result.error<String, String>("early error"));

  x = Result.error("not a 2");
  y = Result.error("late error");
  assert(x.and(y) == Result.error<String, String>("not a 2"));

  x = Result.ok(2);
  y = Result.ok("different result type");
  assert(x.and(y) == Result.ok<String, String>("different result type"));
}

void andThen() {
  assert(Result.ok<int, int>(2).andThen(sq).andThen(sq) ==
      Result.ok<int, int>(16));
  assert(Result.ok<int, int>(2).andThen(sq).andThen(err) ==
      Result.error<int, int>(4));
  assert(Result.ok<int, int>(2).andThen(err).andThen(sq) ==
      Result.error<int, int>(2));
  assert(Result.error<int, int>(3).andThen(sq).andThen(sq) ==
      Result.error<int, int>(3));
}

void map() {
  String stringify(int x) {
    return 'code: $x';
  }

  Result<int, String> x = Result.ok<int, String>(13);
  assert(x.map(stringify) == Result.ok<String, String>('code: 13'));
}

void mapError() {
  String stringify(int x) {
    return 'error code: $x';
  }

  Result<int, int> x = Result.ok(2);
  assert(x.mapError(stringify) == Result.ok<int, String>(2));

  x = Result.error(13);
  assert(x.mapError(stringify) == Result.error<int, String>("error code: 13"));
}

void mapOr() {
  Result<dynamic, String> x = Result.ok<dynamic, String>("foo");
  int val = x.mapOr<int>(42, (v) => v.length);
  assert(val == 3);

  Result<String, dynamic> y = Result.error<String, dynamic>("bar");
  int val1 = y.mapOr<int>(42, (v) => v.length);
  assert(val1 == 42);
}

void mapOrElse() {
  int k = 21;

  Result<dynamic, String> x = Result.ok<dynamic, String>("foo");
  int val = x.mapOrElse<int>((v) => k * 2, (v) => v.length);
  assert(val == 3);

  Result<String, dynamic> y = Result.error<String, dynamic>("bar");
  int val1 = y.mapOrElse<int>((v) => k * 2, (v) => v.length);
  assert(val1 == 42);
}

main() async {
  MockException mock = MockException('cannot get int value');
  MockException mock1 = MockException('cannot get void value');
  MockException mock2 = MockException('from another error');

  Result intRst = await intResult(false);
  assert(intRst.isOk());
  assert(intRst.unwrap() == 5);
  assert(intRst.contains(5));
  assert(intRst.contains(6) == false);

  Result<int, MockException> intErrRst = await intResult(true);
  assert(intErrRst.isError(), true);
  assert(intErrRst.unwrapError().toString() ==
      'MockException(cannot get int value)');
  assert(intErrRst.containsError(mock));
  assert(intErrRst.unwrapOr(6) == 6);
  assert(intErrRst.unwrapOrElse((_) => 7) == 7);

  Result voidRst = await voidResult(false);
  assert(voidRst.isOk());
  assert(voidRst.unwrap() == Void());
  assert(voidRst.contains(Void()));

  Result voidErrRst = await voidResult(true);
  assert(voidErrRst.isError(), true);
  assert(voidErrRst.unwrapError().toString() ==
      'MockException(cannot get void value)');
  assert(voidErrRst.containsError(mock1));
  assert(voidErrRst.unwrapOr(Void()) == Void());
  assert(voidErrRst.unwrapOrElse((_) => Void()) == Void());

  // unwrap
  unwrap();

  // unwrapError
  unwrapError();

  // unwrapOr
  unwrapOr();

  // unwrapOrElse
  unwrapOrElse();

  // or
  or();

  // orElse example
  orElse();

  // and
  and();

  // andThen
  andThen();

  // map
  map();

  // mapError
  mapError();

  // mapOr
  mapOr();

  // mapOrElse
  mapOrElse();
}
2
likes
130
pub points
0%
popularity

Publisher

unverified uploader

A library implements Rust style [Result] for Dart error handle.

Repository (GitHub)
View/report issues

Documentation

API reference

License

Apache-2.0 (LICENSE)

Dependencies

meta

More

Packages that depend on dartsult