154 lines
4.5 KiB
Dart
154 lines
4.5 KiB
Dart
// 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 <https://www.gnu.org/licenses/>.
|
|
|
|
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<T> = Result<T, AppException>;
|
|
typedef FutureOrResult<T> = FutureOr<Res<T>>;
|
|
typedef StreamResult<T> = Stream<Res<T>>;
|
|
|
|
/// A wrapper around [Result] to make it easier to use with AppException.
|
|
Future<Res<T>> unsafe<T>(FutureOr<T> Function() fn) =>
|
|
Result.tryCatchAsync<T, AppException, Object>(
|
|
() => Future.sync(fn),
|
|
(e) => e.toException(),
|
|
);
|
|
|
|
abstract class AsyncUseCase<I, O> extends generic.Usecase<I, Res<O>>
|
|
with Observer<I, O>, ExceptionObserver<O>, CompleterObserver<O> {
|
|
const AsyncUseCase() : super();
|
|
|
|
@override
|
|
FutureOr<generic.ConditionsResult> 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<generic.ConditionsResult> checkPostconditions(Res<O>? result) async {
|
|
try {
|
|
await onComplete(result);
|
|
return generic.ConditionsResult(isValid: true);
|
|
} catch (e) {
|
|
return generic.ConditionsResult(isValid: false, message: e.toString());
|
|
}
|
|
}
|
|
|
|
@override
|
|
FutureOrResult<O> onException(Object e) async {
|
|
final exception = e.toException();
|
|
await onError(exception);
|
|
|
|
return Err(exception);
|
|
}
|
|
}
|
|
|
|
abstract class NoParamsAsyncUseCase<O> extends generic.NoParamsUsecase<Res<O>>
|
|
with ExceptionObserver<O>, CompleterObserver<O> {
|
|
const NoParamsAsyncUseCase() : super();
|
|
|
|
@override
|
|
FutureOr<generic.ConditionsResult> checkPostconditions(Res<O>? result) async {
|
|
try {
|
|
await onComplete(result);
|
|
return generic.ConditionsResult(isValid: true);
|
|
} catch (e) {
|
|
return generic.ConditionsResult(isValid: false, message: e.toString());
|
|
}
|
|
}
|
|
|
|
@override
|
|
FutureOrResult<O> onException(Object e) async {
|
|
final exception = e.toException();
|
|
await onError(exception);
|
|
|
|
return Err(exception);
|
|
}
|
|
}
|
|
|
|
abstract class StreamUseCase<I, O> extends generic.StreamUsecase<I, Res<O>>
|
|
with Observer<I, O>, ExceptionObserver<O> {
|
|
const StreamUseCase() : super();
|
|
|
|
@override
|
|
FutureOr<generic.ConditionsResult> checkPreconditions(I? params) async {
|
|
try {
|
|
await onStart(params);
|
|
return generic.ConditionsResult(isValid: true);
|
|
} catch (e) {
|
|
return generic.ConditionsResult(isValid: false, message: e.toString());
|
|
}
|
|
}
|
|
|
|
StreamSubscription<Res<O>> listen(
|
|
I params,
|
|
void Function(Res<O>)? onData, {
|
|
Function? onError,
|
|
void Function()? onDone,
|
|
bool? cancelOnError,
|
|
}) =>
|
|
super.call(params).listen(
|
|
onData,
|
|
onError: onError,
|
|
onDone: onDone,
|
|
cancelOnError: cancelOnError,
|
|
);
|
|
|
|
@override
|
|
FutureOrResult<O> onException(Object e) async {
|
|
final exception = e.toException();
|
|
await onError(exception);
|
|
|
|
return Err(exception);
|
|
}
|
|
}
|
|
|
|
abstract class NoParamsStreamUseCase<O>
|
|
extends generic.NoParamsStreamUsecase<Res<O>> with ExceptionObserver<O> {
|
|
const NoParamsStreamUseCase() : super();
|
|
|
|
StreamSubscription<Res<O>> listen(
|
|
void Function(Res<O>)? onData, {
|
|
Function? onError,
|
|
void Function()? onDone,
|
|
bool? cancelOnError,
|
|
}) =>
|
|
super.call().listen(
|
|
onData,
|
|
onError: onError,
|
|
onDone: onDone,
|
|
cancelOnError: cancelOnError,
|
|
);
|
|
|
|
@override
|
|
FutureOrResult<O> onException(Object e) async {
|
|
final exception = e.toException();
|
|
await onError(exception);
|
|
|
|
return Err(exception);
|
|
}
|
|
}
|