// 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:generic_usecase/generic_usecase.dart' as generic;
import 'package:wyatt_architecture/src/core/exceptions/exceptions.dart';
import 'package:wyatt_architecture/src/core/extensions/object_extension.dart';
import 'package:wyatt_architecture/src/core/mixins/observers.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
typedef Res = Result;
typedef FutureOrResult = FutureOr>;
typedef StreamResult = Stream>;
/// A wrapper around [Result] to make it easier to use with AppException.
Future> unsafe(FutureOr Function() fn) =>
Result.tryCatchAsync(
() => Future.sync(fn),
(e) => e.toException(),
);
abstract class AsyncUseCase extends generic.Usecase>
with Observer, ExceptionObserver, CompleterObserver {
const AsyncUseCase() : super();
@override
FutureOr checkPreconditions(I? params) async {
try {
await onStart(params);
return generic.ConditionsResult(isValid: true);
} catch (e) {
return generic.ConditionsResult(isValid: false, message: e.toString());
}
}
@override
FutureOr checkPostconditions(Res? result) async {
try {
await onComplete(result);
return generic.ConditionsResult(isValid: true);
} catch (e) {
return generic.ConditionsResult(isValid: false, message: e.toString());
}
}
@override
FutureOrResult onException(Object e) async {
final exception = e.toException();
await onError(exception);
return Err(exception);
}
}
abstract class NoParamsAsyncUseCase extends generic.NoParamsUsecase>
with ExceptionObserver, CompleterObserver {
const NoParamsAsyncUseCase() : super();
@override
FutureOr checkPostconditions(Res? result) async {
try {
await onComplete(result);
return generic.ConditionsResult(isValid: true);
} catch (e) {
return generic.ConditionsResult(isValid: false, message: e.toString());
}
}
@override
FutureOrResult onException(Object e) async {
final exception = e.toException();
await onError(exception);
return Err(exception);
}
}
abstract class StreamUseCase extends generic.StreamUsecase>
with Observer, ExceptionObserver {
const StreamUseCase() : super();
@override
FutureOr checkPreconditions(I? params) async {
try {
await onStart(params);
return generic.ConditionsResult(isValid: true);
} catch (e) {
return generic.ConditionsResult(isValid: false, message: e.toString());
}
}
StreamSubscription> listen(
I params,
void Function(Res)? onData, {
Function? onError,
void Function()? onDone,
bool? cancelOnError,
}) =>
super.call(params).listen(
onData,
onError: onError,
onDone: onDone,
cancelOnError: cancelOnError,
);
@override
FutureOrResult onException(Object e) async {
final exception = e.toException();
await onError(exception);
return Err(exception);
}
}
abstract class NoParamsStreamUseCase
extends generic.NoParamsStreamUsecase> with ExceptionObserver {
const NoParamsStreamUseCase() : super();
StreamSubscription> listen(
void Function(Res)? onData, {
Function? onError,
void Function()? onDone,
bool? cancelOnError,
}) =>
super.call().listen(
onData,
onError: onError,
onDone: onDone,
cancelOnError: cancelOnError,
);
@override
FutureOrResult onException(Object e) async {
final exception = e.toException();
await onError(exception);
return Err(exception);
}
}