Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/fisothemes/result-cpp

A lightweight, header-only C++ library that provides a result type for monadic error handling .
https://github.com/fisothemes/result-cpp

cpp cpp17 error error-handling expected expected-value header-only result

Last synced: 23 days ago
JSON representation

A lightweight, header-only C++ library that provides a result type for monadic error handling .

Awesome Lists containing this project

README

        

# Result-CPP

Result-CPP is a lightweight, header-only C++ library for error handling using the monadic pattern in C++. It provides a generic class called `result` that can store either a successful value or an error value as well as ways to extract and handle them.

## Features

- Simple and concise result type for error handling.
- Header-only library with no external dependencies.
- Supports chaining operations and handling errors.

## Getting Started

### Prerequisites

- C++17 compiler

### Usage

1. Include the `result.hpp` header in your C++ project.
2. Start using the `fst::result` type for handling success and error states.

### Example

```cpp
#include
#include

#include "fst/result.hpp"

// Function that may fail and return a Result
fst::result div(double a, double b) {
if (b == 0.0)
return std::string("Division by zero error"); // Implicitly converts to std::string
return a / b; // Implicitly converts to double
}

int main() {
// Example 1: Chaining with `and_then` and `map`
auto result1 = div(12.0, 3.0)
.and_then([](const auto& x) {
return x > 0.0
? fst::result(x * 2.0)
: fst::result("Negative result");
})
.map([](const auto& y) {
std::cout << "Result: " + std::to_string(y) << '\n';
return y*y;
});

std::cout << "Example 1: " << result1 << '\n';

// Example 2: Chaining with `or_else` and `map_error`
auto result2 = div(10.0, 0.0)
.or_else([](const auto& error) {
return fst::result("Error: " + error);
})
.map_error([](const std::string& original_error) {
return original_error + " (mapped)";
});

std::cout << "Example 2: " << result2 << '\n';

// Example 3: Chaining with `transform`
auto result3 = div(20.0, 4.0)
.transform([](const auto& res) {
return res.success()
? fst::result(
fst::success_t,
"Success! No error")
: fst::result(
fst::error_t,
res.error()
.value_or("Unknown error"));
});

std::cout << "Example 3: " << result3 << '\n';

// Example 4: Using `inspect` for side effects
auto result4 = div(8.0, 2.0)
.inspect([](const fst::result& res) {
if (auto value = res.success()) {
std::cout << "Success! Result is: "
<< *value
<< '\n';
} else {
std::cerr << "Error! Message: "
<< res.error()
.value_or("Unknown error")
<< '\n';
}
});

std::cout << "Example 4: " << result4 << '\n';

return 0;
}
```