Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ void main() {
final gateway = countryGatewayProvider.getGateway(providersContext);

gateway.transport = (request) async {
return Right(
return Either.right(
GraphQLSuccessResponse(
data: {
'countries': [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ void main() {
final gateway = countryGatewayProvider.getGateway(providersContext);

gateway.transport = (request) async {
return Right(
return Either.right(
GraphQLSuccessResponse(
data: {
'countries': request.continentCode == 'NA'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ void main() {
// Subscription shortcut to mock a successful response from a Gateway

useCase.subscribe<LastLoginDateOutput, LastLoginDateInput>(
(_) => Right<FailureInput, LastLoginDateInput>(
LastLoginDateInput(currentDate),
),
(_) => Either.right(LastLoginDateInput(currentDate)),
);

var output = useCase.getOutput<LastLoginUIOutput>();
Expand All @@ -39,7 +37,7 @@ void main() {
useCase.subscribe<LastLoginDateOutput, LastLoginDateInput>(
(output) {
expect(output, LastLoginDateOutput());
return Left<FailureInput, LastLoginDateInput>(FailureInput());
return Either.left(FailureInput());
},
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import 'package:clean_framework/clean_framework.dart';
import 'package:clean_framework/clean_framework_providers.dart';
import 'package:clean_framework/src/app_providers_container.dart';
import 'package:clean_framework_example/features/last_login/domain/last_login_use_case.dart';
import 'package:clean_framework_example/features/last_login/external_interface/last_login_date_gateway.dart';
import 'package:clean_framework_firestore/clean_framework_firestore.dart';
import 'package:clean_framework_test/clean_framework_test.dart';
import 'package:either_dart/either.dart';
import 'package:flutter_test/flutter_test.dart';

final context = ProvidersContext();
Expand All @@ -16,7 +15,7 @@ void main() {
var gateway = LastLoginDateGateway(context: context, provider: provider);

gateway.transport = (request) async =>
Right(FirebaseSuccessResponse({'date': '2000-01-01'}));
Either.right(FirebaseSuccessResponse({'date': '2000-01-01'}));

final testRequest = LastLoginDateRequest();
expect(testRequest.id, '12345');
Expand All @@ -32,7 +31,8 @@ void main() {
final provider = UseCaseProvider((_) => useCase);
var gateway = LastLoginDateGateway(context: context, provider: provider);

gateway.transport = (request) async => Left(UnknownFailureResponse());
gateway.transport =
(request) async => Either.left(UnknownFailureResponse());

await useCase.doFakeRequest(LastLoginDateOutput());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ void main() {
final gateway = randomCatGatewayProvider.getGateway(providersContext);

gateway.transport = (request) async {
return Right(RestSuccessResponse(
return Either.right(RestSuccessResponse(
data: {
'id': 420,
'webpurl':
Expand Down Expand Up @@ -54,7 +54,7 @@ void main() {
final gateway = randomCatGatewayProvider.getGateway(providersContext);

gateway.transport = (request) async {
return Left(UnknownFailureResponse());
return Either.left(UnknownFailureResponse());
};

expect(
Expand Down
2 changes: 1 addition & 1 deletion packages/clean_framework/lib/clean_framework.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ export 'package:clean_framework/src/logger.dart';
export 'package:clean_framework/src/open_feature/open_feature.dart';
export 'package:clean_framework/src/utilities/clean_framework_observer.dart';
export 'package:clean_framework/src/utilities/deserializer.dart';
export 'package:clean_framework/src/utilities/either.dart';
export 'package:clean_framework/src/utilities/network_logger.dart';
export 'package:clean_framework/src/widgets/widgets.dart';
export 'package:either_dart/either.dart';
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'dart:async';

import 'package:clean_framework/src/providers/gateway.dart';
import 'package:clean_framework/src/utilities/clean_framework_observer.dart';
import 'package:either_dart/either.dart';
import 'package:clean_framework/src/utilities/either.dart';

abstract class ExternalInterface<R extends Request, S extends SuccessResponse> {
ExternalInterface(List<GatewayConnection<Gateway>> gatewayConnections) {
Expand Down Expand Up @@ -87,10 +87,10 @@ class _RequestCompleter<R extends Request, S extends SuccessResponse> {

bool get isCompleted => _completer.isCompleted;

void complete(S success) => _completer.complete(Right(success));
void complete(S success) => _completer.complete(Either.right(success));

void completeFailure(FailureResponse failure) {
_completer.complete(Left(failure));
_completer.complete(Either.left(failure));
}
}

Expand Down
8 changes: 4 additions & 4 deletions packages/clean_framework/lib/src/providers/gateway.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:clean_framework/clean_framework_providers.dart';
import 'package:clean_framework/src/app_providers_container.dart';
import 'package:clean_framework/src/utilities/clean_framework_observer.dart';
import 'package:either_dart/either.dart';
import 'package:clean_framework/src/utilities/either.dart';
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';

Expand Down Expand Up @@ -34,8 +34,8 @@ abstract class Gateway<O extends Output, R extends Request,
Future<Either<FailureInput, S>> _processRequest(R request) async {
final either = await transport(request);
return either.fold(
(failureResponse) => Left(_onFailure(failureResponse)),
(response) => Right(onSuccess(response)),
(failureResponse) => Either.left(_onFailure(failureResponse)),
(response) => Either.right(onSuccess(response)),
);
}

Expand All @@ -55,7 +55,7 @@ abstract class BridgeGateway<SUBSCRIBER_OUTPUT extends Output,
_publisherUseCase = publisherUseCase {
_subscriberUseCase.subscribe<SUBSCRIBER_OUTPUT, SUBSCRIBER_INPUT>(
(output) {
return Right<FailureInput, SUBSCRIBER_INPUT>(
return Either<FailureInput, SUBSCRIBER_INPUT>.right(
onResponse(
_publisherUseCase.getOutput<PUBLISHER_OUTPUT>(),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'dart:async';

import 'package:clean_framework/src/providers/use_case/helpers/input.dart';
import 'package:clean_framework/src/providers/use_case/helpers/output.dart';
import 'package:either_dart/either.dart';
import 'package:clean_framework/src/utilities/either.dart';

typedef RequestSubscriptionMap<I extends Input>
= Map<Type, RequestSubscription<I>>;
Expand All @@ -27,7 +27,7 @@ extension RequestSubscriptionMapExtension<I extends Input>
final subscription = this[O];

if (subscription == null) {
return Left<NoSubscriptionFailureInput, S>(
return Either<NoSubscriptionFailureInput, S>.left(
NoSubscriptionFailureInput<O>(),
);
}
Expand Down
99 changes: 99 additions & 0 deletions packages/clean_framework/lib/src/utilities/either.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import 'package:meta/meta.dart';

@Deprecated('Use Either.left')
typedef Left<L, R> = _Left<L, R>;

@Deprecated('Use Either.right')
typedef Right<L, R> = _Right<L, R>;

/// Signature for a function that maps
/// either the left or the right side of this disjunction.
typedef EitherMapper<T, E> = T Function(E);

@sealed
@immutable

/// [Either] represents a value of two possible types.
/// An Either is either an [Either.left] or an [Either.right].
abstract class Either<L, R> {
/// Constructs an [Either].
const Either();

/// The Left version of an [Either].
const factory Either.left(L value) = _Left<L, R>;

/// The Right version of an [Either].
const factory Either.right(R value) = _Right<L, R>;

/// Returns whether this [Either] is an [Either.left].
bool get isLeft => this is _Left<L, R>;

/// Returns whether this [Either] is an [Either.right].
bool get isRight => this is _Right<L, R>;

/// Gets the right value if this is an [Either.left]
/// or throws if this is a [Either.right].
L get left {
return fold<L>((left) => left, _noSuchElementException);
}

/// Gets the right value if this is an [Either.right]
/// or throws if this is an [Either.left].
R get right {
return fold<R>(_noSuchElementException, (right) => right);
}

/// Folds either the left or the right side of this disjunction.
T fold<T>(EitherMapper<T, L> leftMapper, EitherMapper<T, R> rightMapper);

Never _noSuchElementException(value) {
throw NoSuchElementException(
'You should check ${isLeft ? 'isLeft' : 'isRight'} before calling.',
);
}
}

class _Left<L, R> extends Either<L, R> {
const _Left(this.value);

/// The Left value of an [Either].
final L value;

@override
T fold<T>(EitherMapper<T, L> leftMapper, EitherMapper<T, R> rightMapper) {
return leftMapper(value);
}

@override
bool operator ==(Object other) => other is _Left && value == other.value;

@override
int get hashCode => value.hashCode;
}

class _Right<L, R> extends Either<L, R> {
const _Right(this.value);

/// The Right value of an [Either].
final R value;

@override
T fold<T>(EitherMapper<T, L> leftMapper, EitherMapper<T, R> rightMapper) {
return rightMapper(value);
}

@override
bool operator ==(Object other) => other is _Right && value == other.value;

@override
int get hashCode => value.hashCode;
}

/// [Exception] that indicates the element being requested does not exist.
class NoSuchElementException implements Exception {
/// Creates a [NoSuchElementException] with an optional error [message].
const NoSuchElementException([this.message = '']);

/// The message describing the exception.
final String message;
}
5 changes: 2 additions & 3 deletions packages/clean_framework/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ environment:
flutter: '>=3.0.0'

dependencies:
either_dart: ^0.2.0
equatable: ^2.0.5
flutter:
sdk: flutter
flutter_riverpod: ^2.1.0
flutter_riverpod: ^2.1.3
meta: '>=1.8.0 <1.9.0'
riverpod: ^2.1.1
riverpod: ^2.1.3

dev_dependencies:
clean_framework_test: ^0.1.0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:clean_framework/clean_framework.dart';
import 'package:clean_framework/clean_framework_providers.dart';
import 'package:clean_framework/src/app_providers_container.dart';
import 'package:either_dart/either.dart';
import 'package:flutter_test/flutter_test.dart';

final context = ProvidersContext();
Expand All @@ -11,9 +10,7 @@ void main() {
(_) => TestUseCase(TestEntity(foo: 'bar')),
);
TestDirectGateway(provider).transport = (request) async {
return const Right<FailureResponse, TestResponse>(
TestResponse('success'),
);
return const Either.right(TestResponse('success'));
};

final useCase = provider.getUseCaseFromContext(context);
Expand All @@ -29,7 +26,7 @@ void main() {
(_) => TestUseCase(TestEntity(foo: 'bar')),
);
TestDirectGateway(provider).transport = (request) async {
return Left<FailureResponse, TestResponse>(UnknownFailureResponse());
return Either.left(UnknownFailureResponse());
};

final useCase = provider.getUseCaseFromContext(context);
Expand All @@ -46,9 +43,7 @@ void main() {
);
final gateway = TestYieldGateway(provider)
..transport = (request) async {
return const Right<FailureResponse, TestResponse>(
TestResponse('success'),
);
return const Either.right(TestResponse('success'));
};

final useCase = provider.getUseCaseFromContext(context);
Expand Down
11 changes: 5 additions & 6 deletions packages/clean_framework/test/providers/gateway_unit_test.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'package:clean_framework/clean_framework.dart';
import 'package:clean_framework/clean_framework_providers.dart';
import 'package:clean_framework/src/app_providers_container.dart';
import 'package:clean_framework_test/clean_framework_test.dart';
import 'package:either_dart/either.dart';
import 'package:flutter_test/flutter_test.dart';

final context = ProvidersContext();
Expand All @@ -11,7 +10,7 @@ void main() {
final useCase = UseCaseFake();
final provider = UseCaseProvider((_) => useCase);
TestDirectGateway(provider).transport = (request) async {
return const Right(TestResponse('success'));
return const Either.right(TestResponse('success'));
};

await useCase.doFakeRequest(TestDirectOutput('123'));
Expand All @@ -23,7 +22,7 @@ void main() {
final useCase = UseCaseFake();
final provider = UseCaseProvider((_) => useCase);
TestDirectGateway(provider).transport = (request) async {
return Left(UnknownFailureResponse());
return Either.left(UnknownFailureResponse());
};

await useCase.doFakeRequest(TestDirectOutput('123'));
Expand All @@ -36,7 +35,7 @@ void main() {
final provider = UseCaseProvider((_) => useCase);
final gateway = TestYieldGateway(provider)
..transport = (request) async {
return const Right(TestResponse('success'));
return const Either.right(TestResponse('success'));
};

await useCase.doFakeRequest(TestSubscriptionOutput('123'));
Expand All @@ -52,7 +51,7 @@ void main() {
final useCase = UseCaseFake();
final provider = UseCaseProvider((_) => useCase);
TestYieldGateway(provider).transport = (request) async {
return Left(UnknownFailureResponse());
return Either.left(UnknownFailureResponse());
};

await useCase.doFakeRequest(TestSubscriptionOutput('123'));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:clean_framework/clean_framework.dart';
import 'package:clean_framework/clean_framework_providers.dart';
import 'package:either_dart/either.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
Expand All @@ -24,12 +24,12 @@ void main() {
expect(SuccessInput() == successInput, isFalse);

useCase.subscribe<TestDirectOutput, TestSuccessInput>((output) {
return Right(successInput);
return Either.right(successInput);
});

expect(
() => useCase.subscribe<TestDirectOutput, TestSuccessInput>((_) {
return Right(successInput);
return Either.right(successInput);
}),
throwsStateError,
);
Expand All @@ -44,7 +44,7 @@ void main() {
test('UseCase subscription with delayed response on input filter', () async {
final useCase = TestUseCase(TestEntity(foo: ''))
..subscribe<TestSubscriptionOutput, SuccessInput>(
(output) => Right(SuccessInput()),
(output) => Either.right(SuccessInput()),
);

await useCase.fetchDataEventually();
Expand Down
Loading