local Result = {} Result.__index = Result local ResultTypeSymbol = newproxy(true) function Result.new(status, value) assert(typeof(status) == "boolean") local result = { -- Used to locate where a result was created _source = debug.traceback(), -- A tag to identify us as a result [ResultTypeSymbol] = true, _status = status, -- The value success value or error message. _value = value, } setmetatable(result, Result) return result end function Result.success(value) return Result.new(true, value) end function Result.error(value) return Result.new(false, value) end --[[ Is the given object a Result instance? ]] function Result.is(object) if typeof(object) ~= "table" then return false end return object[ResultTypeSymbol] end --[[ The given callbacks are invoked depending on that result. Creates a new result that receives the output of the callback. ]] function Result:match(successHandler, errorHandler) assert(typeof(successHandler) == "function" or typeof(successHandler) == "nil", string.format("Result:match expects successHandler to be a function or nil, got %s", typeof(successHandler))) assert(typeof(errorHandler) == "function" or typeof(errorHandler) == "nil", string.format("Result:match expects errorHandler to be a function or nil, got %s", typeof(errorHandler))) local newResult if self._status then if successHandler ~= nil then newResult = successHandler(self._value) else return self end else if errorHandler ~= nil then newResult = errorHandler(self._value) else return self end end if Result.is(newResult) then return newResult else return Result.success(newResult) end end --[[ The given callback is invoked if the result is success. Creates a new result that receives the output of the callback. ]] function Result:matchSuccess(successHandler) return self:match(successHandler, nil) end --[[ The given callback is invoked if the result is error. Creates a new result that receives the output of the callback. ]] function Result:matchError(errorHandler) return self:match(nil, errorHandler) end function Result:unwrap() return self._status, self._value end return Result