Error Handling » CnxResult module

CnxResult(T) is a "struct template" for representing the value of a fallible operation. It enables a simple, type-safe way of returning, communicating, and handling the result of an operation that can fail, without resorting to heap-allocation and pointers or out-parameters.

CnxResult(T) allows for arbitrary user-defined errors through CnxError, and shares some functionality, such as if_let(var, self), withCnxOption(T)` (see Monadic Interfaces).

Example:

#define IMPORTANT_VALUE 3U

typedef enum ExampleErrorTypes {
    EXAMPLE_SUCCESS = 0,
    EXAMPLE_IMPORTANT_BAD_VALUE
} ExampleErrorTypes;

const_cstring example_error_message_function(i64 error_code) {
    if(error_code == EXAMPLE_IMPORTANT_BAD_VALUE) {
        return "Error: bad value for `important`";
    }
    else {
        return "No error: Example successful";
    }
}

[[maybe_unused]] static const CnxErrorCategory example_error_category
    = {.m_message_function = example_error_message_function};

CnxResult(u32) operation_that_can_fail(u32 important, u32 right) {
    if(important != IMPORTANT_VALUE) {
        return Err(u32, cnx_error_new(EXAMPLE_IMPORTANT_BAD_VALUE, example_error_category));
    }
    else {
        let res = // result of some operation with `important` and `right`...
        return Ok(u32, res);
    }
}

void example(void) {
    let_mut val1 = IMPORTANT_VALUE;
    let_mut val2 = 10U;
    // do something with val1 and/or val2...
    let_mut maybe_value = operation_that_can_fail(val1, val2);
    if_let(value, maybe_value) {
        // do something with value...
    }
    else {
        // maybe_value was `Err(u32)`, do something to recover
        // or report the error, eg:...
        let err = cnx_result_unwrap_err(maybe_value);
        eprintln("Error in example: {}", as_format_t(CnxError, err));
        // or, even more succinctly:
        eprintln("Error in example: {}", as_format_t(CnxResult(T), maybe_value));
    }
}

Defines

#define CnxResult(T)
Macro Alias used to refer to an instantiation of CnxResult(T) for type T
#define Ok(T, value)
Creates a CnxResult(T) holding the given value.
#define Err(T, error)
Creates a CnxResult(T) holding the given error.
#define cnx_result_is_ok(self)
Returns whether this CnxResult(T) is holding a value.
#define cnx_result_is_err(self)
Returns whether this CnxResult(T) is holding an error.
#define cnx_result_as_const(self)
Returns a const reference to the value stored in this CnxResult(T)
#define cnx_result_as_mut(self)
Returns a reference to the value stored in this CnxResult(T)
#define cnx_result_unwrap(self)
Returns the value stored in this CnxResult(T)
#define cnx_result_unwrap_or(self, default_value)
Returns the value stored in this CnxResult(T) , or default_value
#define cnx_result_unwrap_or_else(self, default_generator)
Returns the value stored in this CnxResult(T) , or default_generator()
#define cnx_result_expect(self, panic_message)
Returns the value stored in this CnxResult(T)
#define cnx_result_unwrap_err(self)
Returns the error stored in this CnxResult(T)
#define cnx_result_map(self, MapType, map_func)
Maps the value stored in this CnxResult(T)
#define cnx_result_map_or(self, map_func, default_value)
Maps the value stored in this CnxResult(T)
#define cnx_result_map_or_else(self, map_func, default_generator)
Maps the value stored in this CnxResult(T)
#define cnx_result_map_err(self, map_func)
Maps the error stored in this CnxResult(T)
#define cnx_result_and(self, result_b)
Returns result_b is self is Ok. Otherwise returns the Err value of self.
#define cnx_result_and_then(self, next_func)
Returns the result of calling next_func with the contained value if self is Ok. Otherwise, returns the Err value contained in self
#define cnx_result_or(self, result_b)
Returns self if it is Ok, otherwise returns result_b
#define cnx_result_or_else(self, func)
Returns self if it is Ok, otherwise returns the result of calling func
#define cnx_result_as_bool(self)
Converts this CnxResult(T) to a bool

Define documentation

#define CnxResult(T)

Macro Alias used to refer to an instantiation of CnxResult(T) for type T

Parameters
T - The type held by the result

Used to create and refer to a typedef for an instantiation of CnxResult(T) holding type T

#define Ok(T, value)

Creates a CnxResult(T) holding the given value.

Parameters
T - The Ok type to store in the CnxResult(T)
value - The Ok value to store in the CnxResult(T)
Returns a CnxResult containing the given value

#define Err(T, error)

Creates a CnxResult(T) holding the given error.

Parameters
T - The Ok type to store in the CnxResult(T)
error - The error to store in the CnxResult(T)
Returns a CnxResult containing the given error

#define cnx_result_is_ok(self)

Returns whether this CnxResult(T) is holding a value.

Parameters
self - The CnxResult(T) to check
Returns true if this CnxResult(T) is holding a value, false otherwise

This returns whether the CnxResult(T) is Ok(T, value), ie the associated operation that created this CnxResult(T) was successful and this holds the resulting value.

#define cnx_result_is_err(self)

Returns whether this CnxResult(T) is holding an error.

Parameters
self - The CnxResult(T) to check
Returns true if this CnxResult(T) is holding an error

This returns whether the CnxResult(T) is Err(T, error), ie the associated operation that created this CnxResult(T) failed and his holds an error.

#define cnx_result_as_const(self)

Returns a const reference to the value stored in this CnxResult(T)

Parameters
self - The CnxResult(T) to get the stored value from
Returns a const reference to the contained value

Returns a const reference (an immediately dereferenced pointer-to-const) to the value stored in this CnxResult(T). This requires that this does hold a value. If this is the Err(T, error) variant, this function will invoke a panic.

#define cnx_result_as_mut(self)

Returns a reference to the value stored in this CnxResult(T)

Parameters
self - The CnxResult(T) to get the stored value from
Returns a reference to the contained value

Returns a reference (an immediately dereferenced pointer) to the value stored in this CnxResult(T). This requires that this does hold a value. If this is the Err(T, error) variant, this function will invoke a panic.

#define cnx_result_unwrap(self)

Returns the value stored in this CnxResult(T)

Parameters
self - The CnxResult(T) to get the stored value from
Returns the contained value

This requires that this does hold a value. If this is the Err(T, error) variant, this function will invoke a panic.

#define cnx_result_unwrap_or(self, default_value)

Returns the value stored in this CnxResult(T) , or default_value

Parameters
self - The CnxResult(T) to get the stored value from
default_value - The value to return if this is the Err(T, error) variant
Returns the contained value, or default_value

If this CnxResult(T) is the Ok(T, value) variant, then this returns the stored value, if this is the Err(T, error) variant, then this returns default_value

#define cnx_result_unwrap_or_else(self, default_generator)

Returns the value stored in this CnxResult(T) , or default_generator()

Parameters
self - The CnxResult(T) to get the stored value from
default_generator - The function to generate the value to return if this is the Err(T, error) variant
Returns the contained value, or the one generated by default_generator

If this CnxResult(T) is the Ok(T, value) variant, then this returns the stored value, if this is the Err(T, error) variant, then this returns the value generated by calling default_generator.

#define cnx_result_expect(self, panic_message)

Returns the value stored in this CnxResult(T)

Parameters
self - The CnxResult(T) to get the stored value from
panic_message - The custom panic message to use if self is not the Ok(T, value) variant
Returns the contained value

Returns the value stored in this CnxResult(T) if this is the Ok(T, value) variant. Otherwise, invokes a panic with the given panic message.

#define cnx_result_unwrap_err(self)

Returns the error stored in this CnxResult(T)

Parameters
self - The CnxResult(T) to get the error from
Returns the contained error

Returns the error stored in this CnxResult(T) if this is the Err(T, error) variant. If this is not the Err(T, error) variant, then this invokes a panic.

#define cnx_result_map(self, MapType, map_func)

Maps the value stored in this CnxResult(T)

Parameters
self - The CnxResult(T) to map
MapType - The type to map to. This is the type that will be held by the returned CnxResult, and map_func must return this type.
map_func - The function to map the value stored in self to a MapType.
Returns The CnxResult(MapType) resulting from the mapping

If self is Ok, maps the value stored in it by calling map_func on it. Otherwise, self is Err and this returns the error contained in it.

map_func must be a function type callable with T and returning MapType

#define cnx_result_map_or(self, map_func, default_value)

Maps the value stored in this CnxResult(T)

Parameters
self - The CnxResult(T) to map.
map_func - The function to map the value stored in self.
default_value - The value to return if self is Err.
Returns The value resulting from the mapping

If self is Ok, maps the value stored in it by calling map_func on it. Otherwise, returns default_value.

map_func must be a function type callable with T and returning the same type as default_value

#define cnx_result_map_or_else(self, map_func, default_generator)

Maps the value stored in this CnxResult(T)

Parameters
self - The CnxResult(T) to map.
map_func - The function to map the value stored in self.
default_generator - The function to generate the returned value if self is Err.
Returns The value resulting from the mapping

If self is Ok, maps the value stored in it by calling map_func on it. Otherwise, returns the result of calling default_generator.

map_func must be a function type callable with T. default_generator must be a function type taking no arguments. Both map_func and default_generator must return the same type.

#define cnx_result_map_err(self, map_func)

Maps the error stored in this CnxResult(T)

Parameters
self - The CnxResult(T) to map.
map_func - The function to map the error stored in self.
Returns The CnxResult(T) resulting from the mapping

If self is Err, maps the error stored in it by calling map_func on it. Otherwise, returns self.

map_func must be a function returning a CnxError

#define cnx_result_and(self, result_b)

Returns result_b is self is Ok. Otherwise returns the Err value of self.

Parameters
self - The CnxResult(T) to "and" with result_b.
result_b - Another CnxResult, of a potentially different Ok type to "and" with self
Returns result_b if self is Ok. Otherwise the Err value of self

#define cnx_result_and_then(self, next_func)

Returns the result of calling next_func with the contained value if self is Ok. Otherwise, returns the Err value contained in self

Parameters
self - The CnxResult(T) to operate on.
next_func - The function type to call with the value stored in self
Returns The result of calling next_func with the value stored in self. Otherwise, returns the Err value contained in self

#define cnx_result_or(self, result_b)

Returns self if it is Ok, otherwise returns result_b

Parameters
self - The CnxResult(T) to "or" with result_b
result_b - Another CnxResult(T) to "or" with self.
Returns self if it is Ok. Otherwise, result_b

#define cnx_result_or_else(self, func)

Returns self if it is Ok, otherwise returns the result of calling func

Parameters
self - The CnxResult(T) to "or" with result_b
func - The function to call if self is Err
Returns self if it is Ok. Otherwise, func()

#define cnx_result_as_bool(self)

Converts this CnxResult(T) to a bool

Parameters
self - The CnxResult(T) to convert to a bool
Returns this CnxResult(T) as a bool

This is effectively the same as calling cnx_result_is_ok(self), as it converts to a bool on the condition that this is the Ok(T, value) variant.