Line data Source code
1 : import 'package:collection/collection.dart'; 2 : 3 : /// A generic Result class used for converting a future to a stream by 4 : /// `AsResultStream.asResultStream`. 5 : /// 6 : /// Represents the following states 7 : /// 1. Loading 8 : /// 2. Success 9 : /// 3. Error 10 : abstract class Result<T> { 11 : /// The success event of a stream. 12 3 : factory Result.success( 13 : T data, { 14 : String tag = '', 15 : }) { 16 3 : return ResultSuccess._(data, tag: tag); 17 : } 18 : 19 : /// The loading state of the stream. 20 : /// 21 : /// Usually emitted before starting an async task such as API Request. 22 2 : factory Result.loading({ 23 : String tag = '', 24 : }) { 25 2 : return ResultLoading._(tag: tag); 26 : } 27 : 28 : /// Error event of a stream. 29 2 : factory Result.error( 30 : Exception error, { 31 : String tag = '', 32 : }) { 33 2 : return ResultError._(error, tag: tag); 34 : } 35 : 36 : ///TODO: add public documentation 37 : String get tag; 38 : } 39 : 40 : /// A generic Result class used for converting a future to a stream. 41 : /// 42 : /// Represents the loading state 43 : class ResultLoading<T> implements Result<T> { 44 2 : ResultLoading._({this.tag = ''}); 45 : 46 1 : @override 47 : bool operator ==(dynamic other) { 48 4 : return other is ResultLoading<T> && other.tag == tag; 49 : } 50 : 51 1 : @override 52 1 : int get hashCode => true.hashCode; 53 : 54 : @override 55 : String tag; 56 : 57 1 : @override 58 2 : String toString() => 'ResultLoading(tag: $tag)'; 59 : } 60 : 61 : /// A generic Result class used for converting a future to a stream. 62 : /// 63 : /// Represents the success state 64 : class ResultSuccess<T> implements Result<T> { 65 3 : ResultSuccess._( 66 : this.data, { 67 : this.tag = '', 68 : }); 69 : 70 : /// The data of the event 71 : final T data; 72 : 73 2 : @override 74 : bool operator ==(dynamic other) { 75 2 : if (other is! ResultSuccess<T>) { 76 : return false; 77 : } 78 : 79 : // Compare list 80 6 : if (other.data is List && data is List) { 81 1 : final _otherData = other.data as List; 82 1 : final _data = data as List; 83 : 84 4 : return other.tag == tag && const ListEquality().equals(_otherData, _data); 85 : } 86 : 87 6 : return other.tag == tag && other.data == data; 88 : } 89 : 90 1 : @override 91 3 : String toString() => 'ResultSuccess(data: $data, tag: $tag)'; 92 : 93 1 : @override 94 4 : int get hashCode => T.hashCode ^ tag.hashCode; 95 : 96 : @override 97 : String tag; 98 : } 99 : 100 : /// A generic Result class used for converting a future to a stream. 101 : /// 102 : /// Represents the error state 103 : class ResultError<T> implements Result<T> { 104 2 : ResultError._( 105 : this.error, { 106 : this.tag = '', 107 : }); 108 : 109 : /// The stream error 110 : final Exception error; 111 : 112 1 : @override 113 : bool operator ==(dynamic other) { 114 1 : return other is ResultError<T> && 115 3 : other.tag == tag && 116 5 : other.error.toString() == error.toString(); 117 : } 118 : 119 1 : @override 120 4 : String toString() => 'ResultError(error: ${error.toString()}, tag: $tag)'; 121 : 122 1 : @override 123 5 : int get hashCode => error.hashCode ^ tag.hashCode; 124 : 125 : @override 126 : String tag; 127 : }