twofold 0.2.0 copy "twofold: ^0.2.0" to clipboard
twofold: ^0.2.0 copied to clipboard

A small utility for representing values with two possible outcomes, commonly failure or success.

Twofold #

Twofold is a small, explicit utility for representing values that can have
one of two outcomes — a success or an error.

It is designed to be:

  • Simple
  • Explicit
  • Easy to read
  • Friendly for real-world Dart and Flutter apps

No functional-programming background is required.


Why Twofold? #

In many applications, operations can:

  • succeed with a value
  • fail with a reason

Twofold<S, E> lets you model this clearly without relying on exceptions, nullable values, or implicit control flow.

Twofold focuses on:

  • clear intent
  • predictable APIs
  • readable application code

Design Principles #

Twofold is intentionally small, strict, and predictable.

The project follows clear design and API stability rules to ensure:

  • long-term maintainability
  • strong typing
  • readable application code
  • safe evolution toward v1.0

If you plan to contribute or propose new features, please read
CONTRIBUTING.md before opening an issue or PR.


Installation #

dependencies:
  twofold: ^0.2.0
import 'package:twofold/twofold.dart';

Basic Usage #

Creating values #

final Twofold<int, String> success = Twofold.success(42);
final Twofold<int, String> error = Twofold.error('Something went wrong');

Checking state #

if (result.isSuccess) {
  print('Operation succeeded');
}

if (result.isError) {
  print('Operation failed');
}

final message = result.when(
  onSuccess: (value) => 'Success: $value',
  onError: (error) => 'Failed: $error',
);

Side effects #

result.when(
  onSuccess: (value) => save(value),
  onError: (error) => log(error),
);

Transforming values #

mapSuccess #

final doubled = Twofold.success(2)
    .mapSuccess((v) => v * 2);

mapError #

final formattedError = Twofold.error(404)
    .mapError((code) => 'Error $code');

flatMapSuccess (chaining) #

Twofold<int, String> parse(String value) {
  final parsed = int.tryParse(value);
  return parsed != null
      ? Twofold.success(parsed)
      : Twofold.error('Invalid number');
}

final result = Twofold.success('10')
    .flatMapSuccess(parse);

Fallback values #

final value = result.getOrElse(0);
final value = result.getOrElseGet(() => expensiveFallback());

Async Usage #

Twofold provides extensions and helpers for Future<Twofold> to enable clear and fluent async flows without deeply nested try/catch blocks.

fetchUser()
  .mapSuccess((u) => u.name)
  .flatMapSuccess(fetchProfile)
  .when(
    onSuccess: print,
    onError: showError,
  );

Creating async results safely:

final result = await TwofoldFuture.tryCatch(
  () async => fetchData(),
  onError: (e, _) => e.toString(),
);

Testing Helpers #

Twofold includes framework-agnostic testing helpers to make assertions clear and intention-revealing.

expectSuccess(result, (value) {
  expect(value, 42);
});

expectError(result, (error) {
  expect(error, 'Invalid input');
});

These helpers work with:

  • package:test
  • flutter_test
  • any assertion-based testing setup

This package includes a dedicated example/ project with well-documented, runnable code covering every API.

The example project demonstrates:

  • core construction and inspection
  • when handling patterns
  • transformations and chaining
  • async factories vs async transforms
  • fallback utilities
  • testing helpers with real tests

📂 See: example/
📄 Start here: example/README.md


Important Note #

A Twofold always represents exactly one state:

  • a Success containing a value
  • or an Error containing an error

Invalid or ambiguous states are not possible by design.


Feedback & Contributions #

4
likes
160
points
79
downloads

Publisher

unverified uploader

Weekly Downloads

A small utility for representing values with two possible outcomes, commonly failure or success.

Repository (GitHub)
View/report issues
Contributing

Topics

#error-handling #utility #functional #dart

Documentation

API reference

License

MIT (license)

More

Packages that depend on twofold