API Docs
This document provides a comprehensive overview of all available API methods in the REslava.Result library, organized by functional categories.
| Document | Description |
|---|---|
| Reasons | All reason types (Success, Error, ExceptionError, ConversionError) and their methods |
| Result Methods | Core instance methods on Result classes (Map, Tap, Match, Bind, Conversions) |
| Result Factories | Static factory methods for creating Results (Ok, Fail, Combine, Conditional, Try) |
| Result Extensions | Extension methods for enhanced functionality (LINQ, Validation, Async operations) |
| Validation Rules | Built-in validation rules and custom validation patterns |
| Advanced Patterns | Maybe, OneOf, and other advanced functional patterns |
Result Types
- Result: Non-generic result for operations without return values
- Result
: Generic result for operations with return values - IReason: Base interface for all reasons (successes and errors)
- ISuccess: Interface for success reasons
- IError: Interface for error reasons
Reason Types
- Success: Represents a successful operation
- Error: Represents a general error
- ExceptionError: Wraps exceptions with automatic tag generation
- ConversionError: Used for implicit conversion failures
Core Patterns
1. Creation
// Success cases
var success = Result.Ok();
var successWithValue = Result<User>.Ok(user);
var successWithMessage = Result.Ok("Operation completed");
// Failure cases
var failure = Result.Fail("Something went wrong");
var failureWithError = Result<User>.Fail(new ValidationError("Email", "Invalid format"));
// Tags are immediately available with safe access:
var field = failureWithError.Errors[0].GetTagString("Field"); // "Email"
var errorType = failureWithError.Errors[0].GetTagString("ErrorType"); // "Validation"
2. Transformation
// Map - transform value
var name = userResult.Map(u => u.Name);
// Bind - chain operations
var order = userResult.Bind(u => CreateOrder(u));
// LINQ syntax
var result = from user in GetUser(id)
from order in CreateOrder(user)
select order.Total;
3. Pattern Matching
var message = result.Match(
onSuccess: () => "Success!",
onFailure: errors => $"Failed: {errors[0].Message}"
);
4. Side Effects
var logged = result.Tap(user => logger.LogInformation($"User: {user.Name}"));
var validated = result.Ensure(user => user.Email != null, "Email required");
5. Combination
var combined = Result.Combine(
ValidateEmail(email),
ValidateAge(age),
ValidateName(name)
);
Factory Methods
- Ok(): Create successful results
- Fail(): Create failed results
- Try(): Wrap operations in exception handling
- Combine/Merge: Combine multiple results
- OkIf/FailIf: Conditional creation
Instance Methods
- Map(): Transform values
- Bind(): Chain operations
- Tap(): Execute side effects
- Match(): Pattern matching
- Ensure(): Validation
- WithReason/WithError/WithSuccess(): Add reasons
Extension Methods
- LINQ: Query syntax support
- Validation: Ensure conditions
- Async: Task-based operations
- Tap: Side effects on failures
Thread Safety
All Result types are immutable and therefore thread-safe. All operations return new instances rather than modifying existing ones.
Error Handling Philosophy
- No exceptions for expected failures: Use Result pattern instead of throwing
- Rich error context: Errors can contain tags and metadata
- Composable: Results can be chained and combined
- Explicit: Success/failure must be explicitly handled
Performance Considerations
- Immutable design: Creates new instances, but enables safe sharing
- Lazy evaluation: Many factory methods support lazy predicates
- Efficient combining: Optimized for multiple result operations
- Minimal allocations: Uses immutable collections efficiently
Async Support
Most methods have async counterparts:
- Map() → MapAsync()
- Bind() → BindAsync()
- Tap() → TapAsync()
- Match() → MatchAsync()
- Extensions for Task<Result<T>> types
LINQ Integration
Full LINQ query syntax support enables expressive functional composition:
var result = from user in GetUserAsync(id)
from profile in GetProfileAsync(user.Id)
where profile.IsActive
select new UserProfile(user, profile);
This is equivalent to:
var result = await GetUserAsync(id)
.BindAsync(user => GetProfileAsync(user.Id))
.WhereAsync(profile => profile.IsActive)
.SelectAsync((user, profile) => new UserProfile(user, profile));