RustCxx is a modern C++20 header-only library that provides Rust-style enums, Result, and Option types for C++. It's designed to bring the expressiveness and safety of Rust's type system to C++.
- π Header-only: Just include and use
- π¦ Rust-inspired: Familiar API for Rust developers
- π Type-safe: Compile-time type checking
- π― Pattern Matching: Expressive pattern matching with lambdas
- β‘ Modern C++: Requires C++20, uses
std::variantunder the hood - π§ͺ Well-tested: Comprehensive test suite
#include "rustcxx/rustcxx.hpp"
using namespace rustcxx;
// Define enum variants
ENUM_VARIANT(Red);
ENUM_VARIANT(Green);
ENUM_VARIANT(Blue, int intensity);
using Color = Enum<Red, Green, Blue>;
// Usage
Color color = Blue{128};
// Pattern matching
auto description = color.match(
[](const Red&) { return "It's red!"; },
[](const Green&) { return "It's green!"; },
[](const Blue& b) {
return "It's blue with intensity " + std::to_string(b.intensity);
}
);auto divide = [](int a, int b) -> Result<double, std::string> {
if (b == 0) {
return Result<double, std::string>::Err("Division by zero!");
}
return Result<double, std::string>::Ok(static_cast<double>(a) / b);
};
auto result = divide(10, 2);
// Pattern matching
result.match(
[](double value) { std::cout << "Result: " << value << std::endl; },
[](const std::string& error) { std::cout << "Error: " << error << std::endl; }
);
// Safe access
double value = result.unwrap_or(-1.0);
// Chaining
auto chained = divide(20, 4)
.map([](double x) { return x * 2; })
.and_then([&](double x) { return divide(static_cast<int>(x), 2); });auto find_user = [](int id) -> Option<std::string> {
if (id == 1) return Option<std::string>::Some("Alice");
if (id == 2) return Option<std::string>::Some("Bob");
return Option<std::string>::None();
};
auto user = find_user(1);
// Pattern matching
user.match(
[](const std::string& name) { std::cout << "Found: " << name << std::endl; },
[]() { std::cout << "User not found" << std::endl; }
);
// Chaining operations
auto greeting = find_user(1)
.map([](const std::string& name) { return "Hello, " + name + "!"; })
.unwrap_or("Hello, stranger!");- C++20 compatible compiler
- CMake 3.14 or later
mkdir build && cd build
cmake ..
make
./basic_usagecmake -DRUSTCXX_BUILD_TESTS=ON ..
make
ctestCore enum type that wraps std::variant with ergonomic APIs.
bool is<T>() const- Check if enum holds type TT& get<T>()- Get value of type T (throws if wrong type)T* get_if<T>()- Get pointer to value if type T, nullptr otherwiseauto match(lambdas...)- Pattern match over all variantsstd::size_t index() const- Get index of current variant
Type-safe error handling similar to Rust's Result<T, E>.
Result::Ok(value)- Create successful resultResult::Err(error)- Create error result
bool is_ok() const- Check if result is Okbool is_err() const- Check if result is ErrT unwrap()- Get Ok value (throws if Err)T unwrap_or(default)- Get Ok value or defaultE unwrap_err()- Get Err value (throws if Ok)auto map(func)- Transform Ok valueauto map_err(func)- Transform Err valueauto and_then(func)- Chain Resultsauto match(ok_func, err_func)- Pattern match
Nullable type similar to Rust's Option<T>.
Option::Some(value)- Create Some optionOption::None()- Create None option
bool is_some() const- Check if option has valuebool is_none() const- Check if option is emptyT unwrap()- Get value (throws if None)T unwrap_or(default)- Get value or defaultauto map(func)- Transform Some valueauto and_then(func)- Chain Optionsauto match(some_func, none_func)- Pattern match
ENUM_VARIANT(name)- Define empty variant
If installed:
find_package(rustcxx REQUIRED)
target_link_libraries(your_target rustcxx::rustcxx)Or as subdirectory:
add_subdirectory(path/to/rustcxx)
target_link_libraries(your_target rustcxx)Simply copy include/rustcxx/rustcxx.hpp to your project and include it.
See the examples/ directory for more comprehensive examples:
basic_usage.cpp- Demonstrates all core features- More examples coming soon!
| Rust | RustCxx |
|---|---|
enum Color { Red, Green, Blue(u8) } |
ENUM_VARIANT(Red); ENUM_VARIANT(Red); ENUM_VARIANT(Blue, uint8_t intensity); using Color = Enum<Red, Green, Blue>; |
Result<T, E> |
Result<T, E> |
Option<T> |
Option<T> |
match expr { ... } |
expr.match(...) |
result? |
result.and_then(...) |
option.map(f) |
option.map(f) |
Contributions are welcome! Please feel free to submit a Pull Request.
Licensed under the Apache License, Version 2.0. See LICENSE for details.
Inspired by Rust's excellent type system and the many discussions about bringing similar functionality to C++.