resx 0.4.1 copy "resx: ^0.4.1" to clipboard
resx: ^0.4.1 copied to clipboard

Functional error handling for Dart: Result/Option/Validation + AsyncResult, Stream/Iterable utils, and tiny state Loadable.

Resx ⚡️ #

pub package documentation license: MIT

A lightweight and complete functional error-handling toolkit for Dart, featuring Result, Option, Validation, AsyncResult, stream utilities, and a minimal Loadable state.

Tiny, complete, and functional.

English | 中文

Features ✨ #

🚀 High Performance - Optimized for speed and memory efficiency
🔒 Type Safe - Full null safety and strong typing
🔗 Chainable - Fluent API with method chaining
📦 Batch Operations - Process collections efficiently
🎯 Validation - Accumulate multiple errors elegantly
Async Support - First-class async/await integration
🧩 Extensions - Native Dart type integrations

Core Types 🧠 #

Result<T, E> - Error Handling ✅/❌ #

Type-safe error handling inspired by Rust's Result type.

import 'package:resx/resx.dart';

// Create results
final success = Result.ok(42);
final failure = Result.err('Something went wrong');

// Chain operations
final result = Result.ok(5)
  .map((x) => x * 2)
  .flatMap((x) => x > 5 ? Result.ok(x) : Result.err('Too small'));

// Handle both cases
final message = result.fold(
  (value) => 'Success: $value',
  (error) => 'Error: $error',
);

// Exception catching
final parsed = Result.from(() => int.parse('42')); // Ok(42)
final failed = Result.from(() => int.parse('abc')); // Err(FormatException)

// Guards and swap
final guarded = Result.ok(10).ensure((v) => v > 5, 'Too small');
final swapped = Result.ok(1).swap(); // Err(1)

Option<T> - Nullable Values ❓ #

Safe nullable value handling with Some/None variants.

// Create options
final some = Option.some('Hello');
final none = Option<String>.none();

// Safe operations
final result = Option.some('world')
  .map((s) => s.toUpperCase())
  .filter((s) => s.length > 3)
  .unwrapOr('DEFAULT');

// From nullable
String? nullable = getValue();
final option = Option.fromNullable(nullable);

Validation<E, T> - Error Accumulation 🧰 #

Collect multiple validation errors instead of failing fast.

// Built-in validators
final emailValidation = Validators.email('user@example.com', 'Invalid email');
final rangeValidation = Validators.range(25, 18, 65, 'Age out of range');

// Accumulate errors
final userValidation = Validators.notEmpty('John', 'Name required')
  .and(Validators.email('invalid-email', 'Email invalid'))
  .and(Validators.range(150, 0, 120, 'Age invalid'));

// Result: Invalid(['Email invalid', 'Age invalid'])

AsyncResult<T, E> - Async Operations ⏱️ #

First-class async support for Result operations.

// Create async results
final asyncResult = AsyncResult.ok(42);
final fromFuture = AsyncResult.from(fetchData());

// Chain async operations
final result = await AsyncResult.ok(5)
  .map((x) => x * 2)
  .flatMap((x) => AsyncResult.ok(x + 1));

// Handle async errors safely
final safeResult = await AsyncResult.from(riskyOperation())
  .orElse((error) => AsyncResult.ok('fallback'));

// Guard async values
final ensured = await AsyncResult.ok<int, String>(10)
  .ensure((v) => v > 0, 'non-positive');

Dart Extensions 🧩 #

String Extensions 🔤 #

// Parsing with results
final number = '42'.parseInt(); // Ok(42)
final invalid = 'abc'.parseInt(); // Err(FormatException)

// Validation
final email = 'user@example.com'.validateEmail(); // Valid(...)
final url = Validators.url('https://example.com'); // Valid(...)

List, Stream and Nullable Extensions #

final numbers = [1, 2, 3, 4, 5];
final results = numbers.map((x) => x.isEven ? Result.ok(x) : Result.err('odd'));
final combined = Results.sequence(results); // Ok([...]) or first Err
final (oks, errs) = Results.partition(results);

// Stream helpers
final stream = Stream.fromIterable([1,2,3]);
final asResults = stream.toResultStream<Object>();
final collected = await stream.collectToResult<Object>();

Universal and Nullable Conversions 🔁 #

String? nullable = getValue();
final option = nullable.toOption(); // Option<String>

final result = nullable.toResult('Value is null'); // Result<String, String>

// Universal: wrap any value fast
final r1 = 42.ok<String>();              // Result<int, String>::Ok(42)
final r2 = 'boom'.err<int>();             // Result<int, String>::Err('boom')
final o1 = 'hello'.some();                // Option<String>::Some('hello')

Batch Operations 📦 #

// Combine multiple results
final results = [Result.ok(1), Result.ok(2), Result.ok(3)];
final combined = Results.combine(results); // Ok([1, 2, 3])

// Partition successes and errors
final mixed = [Result.ok(1), Result.err('error'), Result.ok(3)];
final (values, errors) = Results.partition(mixed); // ([1, 3], ['error'])

// Applicative operations
final sum = Results.lift2(
  Result.ok(2),
  Result.ok(3),
  (a, b) => a + b,
); // Ok(5)

Advanced Usage 🚀 #

Custom Validators #

// Using built-in predicate helper
final validation = Validators.predicate<String, String>(
  'test',
  (v) => v.startsWith('prefix_'),
  'Must start with prefix_',
); // Invalid(['Must start with prefix_'])

Pattern Matching #

final result = Result.ok(42);

final message = result.match(
  (value) => 'Got value: $value',
  (error) => 'Got error: $error',
);

Railway-Oriented Programming #

final pipeline = (String input) => Result.ok(input)
  .flatMap(validateInput)
  .flatMap(processData)
  .flatMap(saveToDatabase)
  .map(formatResponse);

final result = pipeline('user input');

Performance #

Focused API, minimal indirections, idiomatic Dart sealed classes and extension types. No magic.

Installation #

Add to your pubspec.yaml:

dependencies:
  resx: any

Then run:

dart pub get

Examples #

Check out the example directory for comprehensive usage examples:

API Documentation #

Complete API documentation with examples is available at pub.dev.

Contributing #

Contributions are welcome! Please read our contributing guidelines and feel free to submit issues and pull requests.

License #

This project is licensed under the MIT License - see the LICENSE file for details.


Made with 💙 by FlutterCandies

1
likes
145
points
192
downloads

Publisher

verified publisherfluttercandies.com

Weekly Downloads

Functional error handling for Dart: Result/Option/Validation + AsyncResult, Stream/Iterable utils, and tiny state Loadable.

Repository (GitHub)
View/report issues

Topics

#result #option #validation #functional-programming #error-handling

Documentation

API reference

Funding

Consider supporting this project:

github.com

License

MIT (license)

Dependencies

meta

More

Packages that depend on resx