// 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,
);
}
}