feat/architecture/make_usecases_more_modular_and_adaptable #39
| @ -14,14 +14,70 @@ | |||||||
| // You should have received a copy of the GNU General Public License | // You should have received a copy of the GNU General Public License | ||||||
| // along with this program. If not, see <https://www.gnu.org/licenses/>. | // along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||||
| 
 | 
 | ||||||
|  | import 'dart:async'; | ||||||
|  | 
 | ||||||
| import 'package:wyatt_architecture/src/core/exceptions/exceptions.dart'; | 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'; | import 'package:wyatt_type_utils/wyatt_type_utils.dart'; | ||||||
| 
 | 
 | ||||||
| typedef FutureResult<T> = Future<Result<T, AppException>>; | typedef FutureOrResult<T> = FutureOr<Result<T, AppException>>; | ||||||
| typedef StreamResult<T> = Stream<Result<T, AppException>>; | typedef StreamResult<T> = Stream<Result<T, AppException>>; | ||||||
| typedef Res<T> = Result<T, AppException>; |  | ||||||
| 
 | 
 | ||||||
| // ignore: one_member_abstracts | /// Abstract class of a use case | ||||||
| abstract class UseCase<Parameters, ReturnType> { | abstract class BaseUseCase<Parameters, ReturnType> { | ||||||
|   FutureResult<ReturnType> call(Parameters params); |   /// 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<Parameters, ReturnType> | ||||||
|  |     extends BaseUseCase<Parameters?, FutureOrResult<ReturnType>> | ||||||
|  |     with Observer<Parameters, ReturnType> { | ||||||
|  |   FutureOr<void> _onSuccess(ReturnType data); | ||||||
|  | 
 | ||||||
|  |   /// Supports the result of the main scenario and integrates | ||||||
|  |   /// some alternative scenarios if necessary. | ||||||
|  |   @override | ||||||
|  |   FutureOrResult<ReturnType> 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<Parameters, ReturnType> | ||||||
|  |     extends UseCase<Parameters?, ReturnType> with AsyncObserver<ReturnType> { | ||||||
|  |   @override | ||||||
|  |   FutureOr<void> _onSuccess(ReturnType data) => onComplete(data); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Abstract specific usecase bases on streams | ||||||
|  | abstract class StreamUseCase<Parameters, ReturnType> | ||||||
|  |     extends UseCase<Parameters?, Stream<ReturnType>> | ||||||
|  |     with StreamObserver<ReturnType> { | ||||||
|  |   @override | ||||||
|  |   FutureOr<void> _onSuccess(Stream<ReturnType> data) { | ||||||
|  |     data.listen( | ||||||
|  |       onData, | ||||||
|  |       onDone: onDone, | ||||||
|  |     ); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user