// 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>; /// {@template base_usecase} /// Abstract class of any use case. /// {@endtemplate} abstract class BaseUseCase { /// {@macro base_usecase} const BaseUseCase(); /// Run use case scenarios ReturnType call(Parameters parameters); /// Private function to implement main scenario /// of your usecase. ReturnType execute(Parameters params); } /// {@template usecase} /// Abstract class of a use case that deals specifically /// with the response and its state. /// {@endtemplate} abstract class UseCase extends BaseUseCase> with Observer { /// {@macro usecase} const UseCase(); FutureOr _onSuccess(ReturnType data); /// Supports the result of the main scenario and integrates /// some alternative scenarios if necessary. @override FutureOrResult call(Parameters? parameters) async { try { await onStart(parameters); final response = await execute(parameters); if (response.isErr) { await onError(response.err); } else if (response.isOk && response.ok != null) { await _onSuccess(response.ok as ReturnType); } return response; } catch (e) { return Err(ClientException(e.toString())); } } } /// {@template async_usecase} /// Abtstract classic usecase bases on futures /// {@endtemplate} abstract class AsyncUseCase extends UseCase with AsyncObserver { /// {@macro async_usecase} const AsyncUseCase(); @override FutureOr _onSuccess(ReturnType data) => onComplete(data); } /// {@template stream_usecase} /// Abstract specific usecase bases on streams /// {@endtemplate} abstract class StreamUseCase extends UseCase> with StreamObserver { /// {@macro stream_usecase} const StreamUseCase(); @override FutureOr _onSuccess(Stream data) { data.listen( onData, onDone: onDone, ); } }