rust_like_result 2.7.1 icon indicating copy to clipboard operation
rust_like_result: ^2.7.1 copied to clipboard

The Result<T> type implemented in Ok<T> and Err<T> types with unwrap methods.

example/example.dart

import 'dart:convert';
import 'dart:io';

import 'package:rust_like_result/rust_like_result.dart';

void main() async {
  // Ok:
  Result<Map> res = Ok({'Forward': 'yes', 'Back': 'no'});
  print(res); // Ok({Forward: yes, Back: no})
  print(res is Ok ? 'Ok' : 'Err'); // Ok
  print(res.unwrap); // {Forward: yes, Back: no}
  print(res.unwrapOrDefault({})); // {Forward: yes, Back: no}
  print(res.unwrapOrElse((e) => {'error': e})); // {Forward: yes, Back: no}

  // Err:
  res = Err(ArgumentError('Bad name'));
  print(res); // Err(Invalid argument(s): Bad name)
  print(res is Ok ? 'Ok' : 'Err'); // Err
  // print(res.unwrap); // <--try uncomment it. Raises exception 'Invalid argument(s): Bad name'
  print(res.unwrapOrDefault({})); // {}
  print(res.unwrapOrElse(
      (e) => {'Got error': e})); // {Got error: Invalid argument(s): Bad name}

  // tryAsResult...() - calls function and return result as Ok, or Err if exception was raised:
  var res1 =
      await tryAsResultAsync(() => File('notExistsFile').rename('newPath'));
  print(res1); // Err(Bad state: FileSystemException: Cannot rename ...

  var res2 = await tryAsResultAsync(() => Directory('.').list());
  print(res2); // Ok(Instance of '_ControllerStream<FileSystemEntity>')

  var res3 = tryAsResultSync(() => File('notExistsFile').renameSync('newPath'));
  print(res3); // Err(Bad state: FileSystemException ...

  var res4 = tryAsResultSync(() => Directory('.').listSync());
  print(res4); // Ok([File:...

  // ok() - use it when you sure that will produce value for Ok(),
  // pipe() - use it when can produce value for Ok(), Err(), Error() or null:
  var r = Ok(123).ok((x) => x * 2).pipe((x) => 246 / x);
  print(r); // Ok(1)

  // Long cascading:
  var r2 = Ok(123)
      .ok((x) => x * 2)
      .ok((x) => x + 4)
      .onResult(stderr.writeln) // <-- print current Result to stderr
      .ok((x) => x * 2)
      .ok((x) => x / 5)
      .ok((x) => 'My answer is: $x')
      .unwrapOrElse((e) => 'Was some error:$e');

  print(r2); // My answer is: 100.0

  // All after Err() will not calculated:
  var r3 = Err(ArgumentError('Your argument is bad'))
      .ok((x) => x * 2)
      .ok((x) => x + 4)
      .ok((x) => x * 2)
      .ok((x) => x / 5)
      .ok((x) => 'My answer is: $x')
      .unwrapOrElse((e) => 'Was some error:$e');

  print(r3); // Was some error:Invalid argument(s): Your argument is bad

  var r4 = Ok(123)
      .ok((x) => x * 2)
      // Possible to use pipe() if function may return Ok,Err,Error, null,
      // but it's better to define a type parameter (because pipe() not infer returned type):
      .pipe<int>((x) => Ok(x + 4))
      // With pipe() not need to wrap error with Err() like:
      // .pipe((x) => Err(AssertionError('My assertion error')))
      // Be simple:
      .pipe<int>((x) => AssertionError('My assertion error'))
      .ok((x) => x / 5)
      .ok((x) => 'My answer is: $x')
      .unwrapOrElse((e) => 'Was some error:$e');

  print(r4); // Was some error:Assertion failed: "My assertion error"

  // =========== Realworld cascading sample: =========================
  var client = HttpClient();
  var addr1 = Uri.parse('https://vlang.io/utc_now');
  // When function returns Future, use tryAsResultAsync(), pipeAsync(), okAsync().
  // And remember about `await` before whole expression.
  // ( Otherwise - use tryAsResultSync(), pipe(), ok() and so on ).
  await tryAsResultAsync(() => client.getUrl(addr1))
      .pipeAsync<HttpClientResponse>((request) => request.close())
      .pipeAsync<String>((response) => response.transform(utf8.decoder).join())
      .pipe<int>((text) => int.tryParse(text))
      .ok((shortMilliseconds) => shortMilliseconds * 1000)
      .pipe<DateTime>(
          (timestamp) => DateTime.fromMillisecondsSinceEpoch(timestamp))
      // execute only when Ok():
      .onOk((dt) => stderr.writeln('Got datetime: $dt'))
      // execute only when Err():
      .onErr((e) => stderr.writeln('Cant get datetime: $e'));

  // It's cool, but...
  // All operations above may be rewrited as one simple function.
  // Note that you don't need to catch any exceptions inside this function.
  // Code can throws exception.
  // Or it can return null if you want. Then it return type will like a Future<DateTime?>.
  Future<DateTime> dateTimeFromVlang() async {
    var request = await client.getUrl(addr1);
    var response = await request.close();
    var text = await response.transform(utf8.decoder).join();
    var timestamp = int.parse(text) * 1000;
    return DateTime.fromMillisecondsSinceEpoch(timestamp);
  }

  // tryAsResultAsync() will catch any axceptions inside your function dateTimeFromVlang().
  // ( See also tryAsResultSync() method. )
  // Also, if dateTimeFromVlang() will return null, then tryAsResultAsync() will return Future of Err().
  await tryAsResultAsync(dateTimeFromVlang)
      // there is interesting way to print any result:
      .onResult(print); // Ok(2022-05-...)

  // Let declare alternative way to get datetime:
  var addr2 = Uri.parse('http://worldtimeapi.org/api/ip');
  Future<DateTime> dateTimeFromWTA() async {
    var request = await client.getUrl(addr2);
    var response = await request.close();
    var text = await response.transform(utf8.decoder).join();
    // Again, we don't worry about possible exceptions here:
    var timestamp = jsonDecode(text)['unixtime'] * 1000;
    return DateTime.fromMillisecondsSinceEpoch(timestamp);
  }

  // Now we can chain two alternative ways via `orAsync()` method.
  // (See alse `or()` method for sync calculations. )
  // If first way will failed then second will tried:
  await tryAsResultAsync(dateTimeFromVlang)
      .onResult((r) => stderr.writeln('First way give me: $r'))
      .orAsync(dateTimeFromWTA)
      .onResult((r) => stderr.writeln('Result is: $r'));
  // First way give me: Ok(2022-05-...)
  // Result is: Ok(2022-05-...)

  // Try replace first addr1 to some bad (then calling of dateTimeFromVlang() will failed):
  addr1 = Uri.parse('https://some_bad_addr');
  await tryAsResultAsync(dateTimeFromVlang)
      .onResult((r) => stderr.writeln('First way give me: $r'))
      .orAsync(dateTimeFromWTA)
      .onResult((r) => stderr.writeln('Result is: $r'));
  // First way give me: Err(Bad state: SocketException: Failed host lookup...))
  // Result is: Ok(2022-05-...)
}
6
likes
120
pub points
28%
popularity

Publisher

unverified uploader

The Result<T> type implemented in Ok<T> and Err<T> types with unwrap methods.

Homepage

Documentation

API reference

License

Icon for licenses.unknown (LICENSE)

More

Packages that depend on rust_like_result