ds 0.10.0
A C library to safely yet efficiently work with UTF-8–encoded, growable dynamic strings.
result.h
Go to the documentation of this file.
1#pragma once
2
3#ifndef DS_RESULT_H
4#define DS_RESULT_H 1
5
6//! @file ds/result.h
7//! @author Avinash Maddikonda (svasssakavi@gmail.com)
8//! @brief Declaration of the @ref ds_result_t "Result" enumeration type,
9//! related constants and functions.
10//! @since 0.6.0
11//! @date 2023-08-01
12
13#include <stdbool.h>
14
15#include "ds/helpers.h"
16#include "ds/usize.h"
17
18#ifdef __cplusplus
19extern "C"
20{
21#endif /* __cplusplus */
22
23 /// @brief @ref ds_result_t "Result" is a type that represents either success
24 /// (@ref DS_RESULT_OK "Ok") or failure (a `DS_RESULT_ERR_*` variant).
26 {
27 /// @brief Represents success.
29
30 /// @brief Represents failure due to an unexpected `NULL` pointer.
32
33 /// @brief Represents a memory allocation failure (usually due to lack of
34 /// sufficient available memory).
36
37 /// @brief Represents failure due to encountering an invalid value outside
38 /// the expected range of valid values.
40 };
41
42 typedef enum ds_result_t ds_result_t;
43
44 /// @brief Returns `true` if @p self is @ref DS_RESULT_OK "Ok".
45 ///
46 /// @param self The value to check.
47 /// @return `true` if @p self is @ref DS_RESULT_OK "Ok", and `false`
48 /// otherwise.
49 ///
50 /// ### Examples
51 ///
52 /// Basic usage:
53 ///
54 /// ```c
55 /// ds_result_t const x = DS_RESULT_OK;
56 /// assert (ds_result_is_ok (x));
57 ///
58 /// ds_result_t const y = DS_RESULT_ERR_PTR_IS_NULL;
59 /// assert (!ds_result_is_ok (y));
60 /// ```
61 extern bool ds_result_is_ok (ds_result_t self);
62
63 /// @brief Returns `true` if @p self is a `DS_RESULT_ERR_*` variant.
64 ///
65 /// @param self The value to check.
66 /// @return `true` if @p self is a `DS_RESULT_ERR_*` variant. `false`
67 /// otherwise.
68 ///
69 /// ### Examples
70 ///
71 /// Basic usage:
72 ///
73 /// ```c
74 /// ds_result_t const x = DS_RESULT_OK;
75 /// assert (!ds_result_is_err (x));
76 ///
77 /// ds_result_t const y = DS_RESULT_ERR_PTR_IS_NULL;
78 /// assert (ds_result_is_err (y));
79 /// ```
80 extern bool ds_result_is_err (ds_result_t self);
81
82/// @brief The size of @ref ds_result_t "Result" in bytes.
83///
84/// ### Examples
85///
86/// Basic usage:
87///
88/// ```c
89/// assert (DS_RESULT_BYTES == sizeof (ds_result_t));
90/// ```
91#define DS_RESULT_BYTES ((ds_usize_t)sizeof (ds_result_t))
92
93/// @internal
94/// @brief Actual internal implementation of @ref DS_RESULT_PROPAGATE_ERR.
95/// @warning Only for internal use.
96#define DS_RESULT_PROPAGATE_ERR_INTERNAL_IMPL(result, id) \
97 do \
98 { \
99 ds_result_t const ds_result_propagate_err_internal_result_##id \
100 = result; \
101 if (ds_result_is_err (ds_result_propagate_err_internal_result_##id)) \
102 { \
103 return ds_result_propagate_err_internal_result_##id; \
104 } \
105 } \
106 while (false)
107
108/// @internal
109/// @brief Internal intermediate interface for @ref
110/// DS_RESULT_PROPAGATE_ERR_INTERNAL_IMPL to @ref DS_RESULT_PROPAGATE_ERR. Acts
111/// as a level of indirection.
112/// @warning Only for internal use.
113#define DS_RESULT_PROPAGATE_ERR_INTERNAL_INTERFACE(result, id) \
114 DS_RESULT_PROPAGATE_ERR_INTERNAL_IMPL (result, id)
115
116/// @brief Propagates (instantly, possibly early, returns) evaluated @p result
117/// to the calling function only if it is a `DS_RESULT_ERR*` variant.
118/// @param result The @ref ds_result_t "Result" variant to be returned if and
119/// only if it is a `DS_RESULT_ERR*` variant (i.e., not @ref DS_RESULT_OK).
120/// @warning Please refrain from using and passing identifiers matching
121/// `ds_result_propagate_err_internal_result_*`. Their usage may cause
122/// unintended or undefined behavior, as they are reserved for internal use
123/// only.
124/// @return @p result ***if and only if*** it is a `DS_RESULT_ERR_*` variant,
125/// else does ***not*** return at all.
126///
127/// ### Examples
128///
129/// Basic usage:
130///
131/// ```c
132/// ds_result_t get_some_result()
133/// {
134/// DS_RESULT_PROPAGATE_ERR (get_some_other_result ());
135/// do_something ();
136///
137/// return DS_RESULT_OK;
138/// }
139/// ```
140#define DS_RESULT_PROPAGATE_ERR(result) \
141 DS_RESULT_PROPAGATE_ERR_INTERNAL_INTERFACE (result, __COUNTER__)
142
143/// @brief Propagates (instantly, possibly early, returns) @ref
144/// DS_RESULT_ERR_PTR_IS_NULL ***if and only if*** @p ptr is `NULL`.
145/// @param ptr The pointer to check if `NULL`.
146/// @return @ref DS_RESULT_ERR_PTR_IS_NULL ***if and only if*** @p ptr is
147/// `NULL`, else does ***not*** return at all.
148///
149/// ### Examples
150///
151/// Basic usage:
152///
153/// ```c
154/// ds_result_t get_some_result(ds_usize_t *const size_ptr)
155/// {
156/// DS_RESULT_PROPAGATE_IF_NULL (size_ptr);
157///
158/// *size_ptr = DS_USIZE_MIN;
159/// return DS_RESULT_OK;
160/// }
161/// ```
162#define DS_RESULT_PROPAGATE_IF_NULL(ptr) \
163 do \
164 { \
165 if (ds_helpers_is_null (ptr)) \
166 { \
167 return DS_RESULT_ERR_PTR_IS_NULL; \
168 } \
169 } \
170 while (false)
171
172#ifdef __cplusplus
173}
174#endif /* __cplusplus */
175
176#endif /* DS_RESULT_H */
Declaration of helper constants and functions.
ds_result_t
Result is a type that represents either success (Ok) or failure (a DS_RESULT_ERR_* variant).
Definition: result.h:26
@ DS_RESULT_ERR_PTR_IS_NULL
Represents failure due to an unexpected NULL pointer.
Definition: result.h:31
@ DS_RESULT_OK
Represents success.
Definition: result.h:28
@ DS_RESULT_ERR_MEM_ALLOC_FAILED
Represents a memory allocation failure (usually due to lack of sufficient available memory).
Definition: result.h:35
@ DS_RESULT_ERR_OUT_OF_RANGE
Represents failure due to encountering an invalid value outside the expected range of valid values.
Definition: result.h:39
bool ds_result_is_ok(ds_result_t self)
Returns true if self is Ok.
Definition: result.c:13
bool ds_result_is_err(ds_result_t self)
Returns true if self is a DS_RESULT_ERR_* variant.
Definition: result.c:19
Declaration of the usize type, related constants and functions.