What is this?
RustResult
is a Lua implementation inspired by Rust’s Result
type, designed to represent the outcome of operations that can either succeed or fail. It provides a way to handle both success and error cases explicitly, avoiding the need for exceptions and enabling more predictable, safe, and readable error handling.
There are two possible outcomes:
-
Ok(T)
: Represents a successful result containing a value of typeT
. This is the standard outcome when an operation completes successfully. -
Err(E)
: Represents a failure containing an error value of typeE
. This is used when an operation encounters an error.
Why Use RustResult
?
In Lua, error handling is often done via pcall
or xpcall
, or sometimes just through implicit error values. RustResult
provides a more structured approach that forces explicit handling of success (Ok
) and error (Err
) states. This leads to cleaner, more maintainable code that clearly communicates the outcome of operations.
The core benefit of RustResult
is that it avoids unhandled exceptions and ensures that errors are always checked and dealt with. Rather than relying on vague error messages or silent failures, the result of an operation is encapsulated in a RustResult
object that must be inspected and handled appropriately.
Example Usage
--!strict
local Modules = game.ReplicatedStorage.Modules
local RustResult = require(Modules.RustResult)
-- A function that divides two numbers
local function divide(a : number, b : number) : RustResult.ClassType<number, string>
if b == 0 then
return RustResult.Err("Cannot divide by zero")
else
return RustResult.Ok(a / b)
end
end
-- Handling the result of division
local result = divide(10, 2)
if result:is_ok() then
print("Success:", result:unwrap()) -- Output: Success: 5
else
print("Error:", result:unwrap_err())
end
-- Handling division by zero
local errorResult = divide(10, 0)
if errorResult:is_err() then
print("Error:", errorResult:unwrap_err()) -- Output: Error: Cannot divide by zero
end
When to Use RustResult
RustResult
is useful when dealing with operations that can either succeed or fail (e.g., file operations, network requests, division by zero, etc.). It is especially beneficial in large projects or systems where error handling needs to be predictable, robust, and easy to follow.
By using RustResult
, you make it clear that errors will be handled, improving both the reliability and maintainability of your code.
Changelog
- Made the module
!strict
mode friendly - Updated the in-script documentation
- Fixed
or_else
,and_then
returning back the inner value instead of the result - Switched to a more dynamic compact approach
- Statically defined all the method signatures for consistency.
If this module is received well, I might extend it with more functionality from nightly Rust.