rsl 1.0.0
rsl: ^1.0.0 copied to clipboard
A simple Result type implementation for Dart with standalone Right/Left constructors similar to dartz.
// rsl_example.dart
import 'package:rsl/rsl.dart';
void main() {
// 1. Basic Usage
print('\n=== Basic Usage ===');
final validNumber = parseNumber('42');
final invalidNumber = parseNumber('abc');
printResult(validNumber); // Success: 42
printResult(invalidNumber); // Error: Invalid number: abc
// 2. Different Ways to Handle Results
print('\n=== Handling Results ===');
handleResults();
// 3. Chaining Operations
print('\n=== Chaining Operations ===');
chainOperations();
// 4. Real-world Example: API Call
print('\n=== Real-world Example ===');
simulateApiCall();
}
// 1. Basic Usage Example
Result<String, int> parseNumber(String input) {
try {
return Right(int.parse(input));
} catch (e) {
return Left('Invalid number: $input');
}
}
void printResult(Result<String, int> result) {
result.fold(
(error) => print('Error: $error'),
(number) => print('Success: $number'),
);
}
// 2. Different Ways to Handle Results
void handleResults() {
final success = Right<String, int>(42);
final failure = Left<String, int>('Something went wrong');
// Using fold (pattern matching)
print('Using fold:');
success.fold(
(error) => print('Failure: $error'),
(value) => print('Success: $value'),
);
// Using getOrElse
print('\nUsing getOrElse:');
print('Success value: ${success.getOrElse(() => 0)}');
print('Failure value: ${failure.getOrElse(() => 0)}');
// Using getOrNull
print('\nUsing getOrNull:');
print('Success value: ${success.getOrNull()}');
print('Failure value: ${failure.getOrNull()}');
// Using getOrThrow
print('\nUsing getOrThrow:');
try {
print('Success value: ${success.getOrThrow()}');
print('Failure value: ${failure.getOrThrow()}'); // This will throw
} catch (e) {
print('Caught error: $e');
}
}
// 3. Chaining Operations
void chainOperations() {
final result = Right<String, String>('hello,world')
.map((s) => s.split(',')) // Returns List<String>
.flatMap((list) {
// Explicit null check and length validation
if (list.isEmpty || list.length < 2) {
return Left<String, List<String>>('Invalid format: expected 2 parts');
}
return Right<String, List<String>>(list);
})
.map((list) {
// Safe access since flatMap ensured we have at least 2 elements
final first = list[0];
final second = list[1];
return '$first ${second.toUpperCase()}';
});
print('Final result:');
result.fold(
(error) => print('Error: $error'),
(value) => print('Value: $value'),
);
// Swapping example
print('\nAfter swap:');
final swapped = result.swap();
swapped.fold(
(error) => print('Error: $error'),
(value) => print('Value: $value'),
);
}
// 4. Real-world Example: API Call
void simulateApiCall() {
// Simulate a user repository
final userRepo = UserRepository();
// Successful case
print('Fetching valid user:');
userRepo
.getUser(123)
.fold(
(error) => print('Error: $error'),
(user) => print('User: ${user.name} (${user.email})'),
);
// Error case
print('\nFetching invalid user:');
userRepo
.getUser(999)
.fold((error) => print('Error: $error'), (user) => print('User: $user'));
}
// Supporting classes for the real-world example
class User {
final int id;
final String name;
final String email;
User(this.id, this.name, this.email);
}
class UserRepository {
final _users = {
123: User(123, 'John Doe', 'john@example.com'),
456: User(456, 'Jane Smith', 'jane@example.com'),
};
Result<String, User> getUser(int id) {
return _users.containsKey(id)
? Right(_users[id]!)
: Left('User with ID $id not found');
}
}