Skip to content

Commit

Permalink
running Effect
Browse files Browse the repository at this point in the history
  • Loading branch information
SandroMaglione committed Mar 22, 2024
1 parent 05036f1 commit a44fed8
Showing 1 changed file with 81 additions and 68 deletions.
149 changes: 81 additions & 68 deletions packages/fpdart/lib/src/effect.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ EffectGen<E, L> _effectGen<E, L>(E? env) => (
final run = effect.asEffect._unsafeRun(env);
if (run is Future) {
throw _EffectThrow<L>(
Die.current("Cannot execute a Future using sync"),
Die.current(
Exception("gen.sync cannot execute async Effect"),
),
);
}

Expand Down Expand Up @@ -75,50 +77,77 @@ final class Effect<E, L, R> extends IEffect<E, L, R> {

/// {@category execution}
R runSync(E env) {
final result = _unsafeRun(env);
if (result is Future) {
throw Die.current(result);
try {
final result = _unsafeRun(env);
if (result is Future) {
throw Die.current(
Exception("runSync cannot execute async Effect"),
);
}

return switch (result) {
Left(value: final cause) => throw cause,
Right(value: final value) => value,
};
} on Cause<L> {
rethrow;
} catch (error, stackTrace) {
throw Die(error, stackTrace);
}

return switch (result) {
Left(value: final cause) => throw cause,
Right(value: final value) => value,
};
}

/// {@category execution}
Exit<L, R> runSyncExit(E env) {
final result = _unsafeRun(env);
if (result is Future) {
return Left(Die.current(""));
try {
final result = _unsafeRun(env);
if (result is Future) {
return Left(Die.current(
Exception("runSyncExit cannot execute async Effect"),
));
}
return result;
} on Cause<L> catch (cause) {
return Left(cause);
} catch (error, stackTrace) {
return Left(Die(error, stackTrace));
}
return result;
}

/// {@category execution}
Future<R> runFuture(E env) async {
final result = _unsafeRun(env);
if (result is! Future) {
print(
"You can use runSync instead of runFuture since the Effect is synchronous",
);
try {
final result = _unsafeRun(env);
if (result is! Future) {
return switch (result) {
Left(value: final cause) => throw cause,
Right(value: final value) => value,
};
}

return switch (await result) {
Left(value: final cause) => throw cause,
Right(value: final value) => value,
};
} on Cause<L> {
rethrow;
} catch (error, stackTrace) {
throw Die(error, stackTrace);
}

return switch (await result) {
Left(value: final cause) => throw cause,
Right(value: final value) => value,
};
}

/// {@category execution}
Future<Exit<L, R>> runFutureExit(E env) async {
final result = _unsafeRun(env);
if (result is! Future) {
print(
"You can use runSyncExit instead of runFutureExit since the Effect is synchronous",
);
try {
final result = _unsafeRun(env);
if (result is! Future) {
return result;
}
return result;
} on Cause<L> catch (cause) {
return Left(cause);
} catch (error, stackTrace) {
return Left(Die(error, stackTrace));
}
return result;
}

/// {@category constructors}
Expand Down Expand Up @@ -172,6 +201,17 @@ final class Effect<E, L, R> extends IEffect<E, L, R> {
/// {@category constructors}
factory Effect.succeed(R value) => Effect._((_) => Right(value));

/// {@category constructors}
static Effect<E, Never, Never> die<E>(dynamic defect) => Effect._(
(_) => Left(Die.current(defect)),
);

/// {@category constructors}
static Effect<E, Never, Never> functionDie<E>(dynamic Function() run) =>
Effect._(
(_) => Left(Die.current(run())),
);

/// {@category constructors}
static Effect<Never, Never, fpdart_unit.Unit> unit = Effect._(
(_) => const Right(fpdart_unit.unit),
Expand Down Expand Up @@ -420,49 +460,22 @@ extension ProvideNever<L, R> on Effect<Never, L, R> {
);

/// {@category execution}
R runSyncNoEnv() {
final result = _unsafeRun(null);
if (result is Future) {
throw Die.current(result);
}

return switch (result) {
Left(value: final cause) => throw cause,
Right(value: final value) => value,
};
}
R runSyncNoEnv() => Effect<void, L, R>._(
(_) => _unsafeRun(null),
).runSync(null);

/// {@category execution}
Exit<L, R> runSyncExitNoEnv() {
final result = _unsafeRun(null);
if (result is Future) {
return Left(Die.current(""));
}
return result;
}
Exit<L, R> runSyncExitNoEnv() => Effect<void, L, R>._(
(_) => _unsafeRun(null),
).runSyncExit(null);

/// {@category execution}
Future<R> runFutureNoEnv() async {
final result = await _unsafeRun(null);
if (result is! Future) {
print(
"You can use runSync instead of runFuture since the Effect is synchronous",
);
}
return switch (result) {
Left(value: final cause) => throw cause,
Right(value: final value) => value,
};
}
Future<R> runFutureNoEnv() async => Effect<void, L, R>._(
(_) => _unsafeRun(null),
).runFuture(null);

/// {@category execution}
Future<Exit<L, R>> runFutureExitNoEnv() async {
final result = _unsafeRun(null);
if (result is! Future) {
print(
"You can use runSync instead of runFuture since the Effect is synchronous",
);
}
return result;
}
Future<Exit<L, R>> runFutureExitNoEnv() async => Effect<void, L, R>._(
(_) => _unsafeRun(null),
).runFutureExit(null);
}

0 comments on commit a44fed8

Please sign in to comment.