elemental 0.0.58 copy "elemental: ^0.0.58" to clipboard
elemental: ^0.0.58 copied to clipboard

A toolkit for writing software in dart

example/lib/main.dart

import 'package:dio/dio.dart';
import 'package:elemental/elemental.dart';

/// You could define [Todo] with something like freezed.
typedef Todo = Map<String, dynamic>;

/// Convenience type alias for our ZIO. This allows us to do things like:
///
/// ```dart
/// final greeting = TodosIO.succeed('Hello, world!');
/// ```
///
/// And `greeting` will have the correct type of:
///
/// ```dart
/// ZIO<NoEnv, TodosError, String>
/// ```
typedef TodosIO<A> = ZIO<NoEnv, TodosError, A>;

/// Here we define our error type
abstract class TodosError {}

class ListTodosError extends TodosError {}

class TodosDioError extends TodosError {
  final DioError dioError;
  TodosDioError(this.dioError);

  @override
  String toString() => dioError.toString();
}

// Here we define our service
class Todos {
  const Todos(this.dio);

  final Dio dio;

  TodosIO<IList<Todo>> get list => TodosIO.tryCatch(
        () => dio.get<List<dynamic>>('/todos'),
        (error, stack) => TodosDioError(error),
      )
          .flatMapNullableOrFail(
            (response) => response.data,
            (response) => ListTodosError(),
          )
          .map((todos) => todos.cast<Todo>().toIList());
}

// Here we create a Dio layer, which closes the Dio instance when finished.
final dioLayer = Layer.scoped(
  IO(
    () => Dio(BaseOptions(baseUrl: 'https://jsonplaceholder.typicode.com/')),
  ).acquireRelease(
    (dio) => IO(() {
      dio.close();
      print("closed DIO");
      return unit;
    }),
  ),
);

// We then use the Dio layer to create a Todos layer.
final todosLayer = Layer(IO.layer(dioLayer).map((dio) => Todos(dio)));

Future<void> main() async {
  final listTodos = TodosIO.layer(todosLayer)
      .zipLeft(ZIO.logInfo('Fetching todos...'))
      .annotateLog("custom key", true) // You can add annotations to the log
      .flatMap((todos) => todos.list);

  final todos = await listTodos.runOrThrow();

  print(todos);
}