// Copyright (C) 2022 WYATT GROUP // Please see the AUTHORS file for details. // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . import 'dart:async'; import 'package:wyatt_architecture/src/core/exceptions/exceptions.dart'; import 'package:wyatt_architecture/src/domain/usecases/observers.dart'; import 'package:wyatt_type_utils/wyatt_type_utils.dart'; typedef FutureOrResult = FutureOr>; typedef StreamResult = Stream>; /// Abstract class of a use case abstract class BaseUseCase { /// Run use case scenarios ReturnType execute(Parameters parameters); /// Private function to implement main scenario /// of your usecase. ReturnType call(Parameters params); } /// Abstract class of a use case that deals specifically /// with the response and its state. abstract class UseCase extends BaseUseCase> with Observer { FutureOr _onSuccess(ReturnType data); /// Supports the result of the main scenario and integrates /// some alternative scenarios if necessary. @override FutureOrResult execute(Parameters? parameters) => Result.tryCatchAsync( () async { await onStart(parameters); final response = await call(parameters); if (response.isErr) { await onError(response.err); } else if (response.isOk && response.ok != null) { await _onSuccess(response.ok as ReturnType); } return response.ok!; }, (error) => ClientException( error.toString(), ), ); } /// Abtstract classic usecase. abstract class AsyncUseCase extends UseCase with AsyncObserver { @override FutureOr _onSuccess(ReturnType data) => onComplete(data); } /// Abstract specific usecase bases on streams abstract class StreamUseCase extends UseCase> with StreamObserver { @override FutureOr _onSuccess(Stream data) { data.listen( onData, onDone: onDone, ); } }