Skip to content

Commit

Permalink
feat: add getOrThrow method
Browse files Browse the repository at this point in the history
  • Loading branch information
higorlapa committed Jul 17, 2023
1 parent 76cba75 commit b137dc2
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 24 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
## 5.0.0 05/10/2022
## 5.1.0 07/17/2023

* Adds [getOrThrow] method

## 5.0.0 05/10/2023

* Supports new dart 3 features

Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,20 @@ void main() {
});
```

#### Handling the Result with `getOrThrow`

You may use the `getOrThrow` to get the value when you're sure that the result was a `Success`.
Be aware that accessing this method when the result is actually an `Error` will throw a `SuccessResultNotFoundException`.

```dart
final result = getSomethingPretty();
if (result.isSuccess()) {
final mySuccessResult = result.getOrThrow();
}
```


#### Handling the Result with `tryGetSuccess`

```dart
Expand Down
2 changes: 1 addition & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,5 @@ ResultOf<String, Exception> _getName({bool forceError = false}) {
if (forceError) {
return Result.error(Exception("Error forced"));
}
return Result.success("Higor");
return const Result.success("Higor");
}
36 changes: 34 additions & 2 deletions lib/src/result.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,21 @@ sealed class Result<S, E> {
const Result();

/// Build a [Result] that returns a [Success].
factory Result.success(S s) => Success(s);
const factory Result.success(S s) = Success;

/// Build a [Result] that returns a [Error].
factory Result.error(E e) => Error(e);
const factory Result.error(E e) = Error;

/// Get the [S] value IF it is a [Success].
///
/// It may throw [SuccessResultNotFoundException] if this result is actually
/// an [Error] of [E].
///
/// Make sure to use [isSuccess] or `if (result case Success())` before
/// accessing this method.
///
/// You can also use [tryGetSuccess] if you're unsure of the possible result.
S getOrThrow();

/// Returns the value of [S] if any.
S? tryGetSuccess();
Expand Down Expand Up @@ -97,6 +108,9 @@ final class Success<S, E> extends Result<S, E> {
/// Success value
S get success => _success;

@override
S getOrThrow() => _success;

@override
E? tryGetError() => null;

Expand Down Expand Up @@ -153,6 +167,9 @@ final class Error<S, E> extends Result<S, E> {
) =>
whenError(_error);

@override
S getOrThrow() => throw SuccessResultNotFoundException();

@override
E tryGetError() => _error;

Expand All @@ -165,3 +182,18 @@ final class Error<S, E> extends Result<S, E> {
@override
R? whenSuccess<R>(R Function(S success) whenSuccess) => null;
}

/// Thrown when getting the [S] type when none is available.
final class SuccessResultNotFoundException<S, E> implements Exception {
const SuccessResultNotFoundException();

@override
String toString() {
return '''
Tried to get the success value of [$S], but none was found.
Make sure you're checking for `isSuccess` before trying to get it through
`getOrThrow`. You can also use `tryGetSuccess` if you're unsure or
`if (result case Success())`
''';
}
}
42 changes: 25 additions & 17 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ packages:
dependency: transitive
description:
name: _fe_analyzer_shared
sha256: "3444216bfd127af50bbe4862d8843ed44db946dd933554f0d7285e89f10e28ac"
sha256: "0816708f5fbcacca324d811297153fe3c8e047beb5c6752e12292d2974c17045"
url: "https://pub.dev"
source: hosted
version: "50.0.0"
version: "62.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
sha256: "68796c31f510c8455a06fed75fc97d8e5ad04d324a830322ab3efc9feb6201c1"
sha256: "21862995c9932cd082f89d72ae5f5e2c110d1a0204ad06e4ebaee8307b76b834"
url: "https://pub.dev"
source: hosted
version: "5.2.0"
version: "6.0.0"
args:
dependency: transitive
description:
Expand Down Expand Up @@ -53,10 +53,10 @@ packages:
dependency: transitive
description:
name: collection
sha256: "6d4193120997ecfd09acf0e313f13dc122b119e5eca87ef57a7d065ec9183762"
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
url: "https://pub.dev"
source: hosted
version: "1.15.0"
version: "1.17.2"
convert:
dependency: transitive
description:
Expand All @@ -81,6 +81,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.0"
dart_internal:
dependency: transitive
description:
name: dart_internal
sha256: dae3976f383beddcfcd07ad5291a422df2c8c0a8a03c52cda63ac7b4f26e0f4e
url: "https://pub.dev"
source: hosted
version: "0.2.8"
file:
dependency: transitive
description:
Expand Down Expand Up @@ -141,10 +149,10 @@ packages:
dependency: "direct dev"
description:
name: lints
sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015"
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "2.1.1"
logging:
dependency: transitive
description:
Expand All @@ -157,10 +165,10 @@ packages:
dependency: transitive
description:
name: matcher
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev"
source: hosted
version: "0.12.15"
version: "0.12.16"
meta:
dependency: transitive
description:
Expand Down Expand Up @@ -317,26 +325,26 @@ packages:
dependency: "direct dev"
description:
name: test
sha256: "4f92f103ef63b1bbac6f4bd1930624fca81b2574464482512c4f0896319be575"
sha256: "67ec5684c7a19b2aba91d2831f3d305a6fd8e1504629c5818f8d64478abf4f38"
url: "https://pub.dev"
source: hosted
version: "1.24.2"
version: "1.24.4"
test_api:
dependency: transitive
description:
name: test_api
sha256: daadc9baabec998b062c9091525aa95786508b1c48e9c30f1f891b8bf6ff2e64
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
url: "https://pub.dev"
source: hosted
version: "0.5.2"
version: "0.6.1"
test_core:
dependency: transitive
description:
name: test_core
sha256: "3642b184882f79e76ca57a9230fb971e494c3c1fd09c21ae3083ce891bcc0aa1"
sha256: "6b753899253c38ca0523bb0eccff3934ec83d011705dae717c61ecf209e333c9"
url: "https://pub.dev"
source: hosted
version: "0.5.2"
version: "0.5.4"
typed_data:
dependency: transitive
description:
Expand Down Expand Up @@ -386,4 +394,4 @@ packages:
source: hosted
version: "3.1.0"
sdks:
dart: ">=3.0.0 <4.0.0"
dart: ">=3.0.0 <3.2.0"
6 changes: 3 additions & 3 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name: multiple_result
description: Multiple results for dart. Inspired by dartz's Either and Kotlin's sealed classes
version: 5.0.0
version: 5.1.0
repository: https://github.com/higorlapa/result

environment:
sdk: ">=3.0.0 <4.0.0"

dev_dependencies:
test: ^1.24.2
lints: ^2.0.1
test: 1.24.4
lints: 2.1.1
23 changes: 23 additions & 0 deletions test/src/result_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,29 @@ void main() {
expect(Error(1) == Error(1), isTrue);
expect(Error(1).hashCode == Error(1).hashCode, isTrue);
});

group("getOrThrow", () {
test(
"When accessing `getOrThrow` with a Success result, should return the Success value",
() {
final result = useCase.call();

expect(result.getOrThrow(), isA<MyResult>());
});

test(
"When accessing `getOrThrow` with a Error result, should throw SuccessResultNotFoundException",
() {
final result = useCase.call(returnError: true);

expect(
() => result.getOrThrow(),
throwsA(
isA<SuccessResultNotFoundException>(),
),
);
});
});
}

class MyUseCase {
Expand Down

0 comments on commit b137dc2

Please sign in to comment.