DotNameLib
Loading...
Searching...
No Matches
UtilsError.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4#include <optional>
5#include <stdexcept>
6#include <string>
7#include <variant>
8
9namespace dotnamecpp::utils {
10
11 // Error codes for file operations
23
24 // Error codes for JSON operations
33
34 // File operation error details
35 struct FileError {
37 std::string message;
38 std::string path;
39
40 [[nodiscard]]
41 std::string toString() const {
42 std::string codeStr;
43 switch (code) {
44 case FileErrorCode::NotFound: codeStr = "NotFound"; break;
45 case FileErrorCode::AccessDenied: codeStr = "AccessDenied"; break;
46 case FileErrorCode::AlreadyExists: codeStr = "AlreadyExists"; break;
47 case FileErrorCode::ReadError: codeStr = "ReadError"; break;
48 case FileErrorCode::WriteError: codeStr = "WriteError"; break;
49 case FileErrorCode::InvalidPath: codeStr = "InvalidPath"; break;
50 case FileErrorCode::IsDirectory: codeStr = "IsDirectory"; break;
51 case FileErrorCode::NotDirectory: codeStr = "NotDirectory"; break;
52 case FileErrorCode::Unknown: codeStr = "Unknown"; break;
53 }
54 return codeStr + ": " + message + (path.empty() ? "" : " (path: " + path + ")");
55 }
56 };
57
58 // JSON operation error details
59 struct JsonError {
61 std::string message;
62 std::string details;
63
64 [[nodiscard]]
65 std::string toString() const {
66 std::string codeStr;
67 switch (code) {
68 case JsonErrorCode::ParseError: codeStr = "ParseError"; break;
69 case JsonErrorCode::InvalidStructure: codeStr = "InvalidStructure"; break;
70 case JsonErrorCode::FileNotFound: codeStr = "FileNotFound"; break;
71 case JsonErrorCode::InvalidType: codeStr = "InvalidType"; break;
72 case JsonErrorCode::MissingKey: codeStr = "MissingKey"; break;
73 case JsonErrorCode::Unknown: codeStr = "Unknown"; break;
74 }
75 return codeStr + ": " + message + (details.empty() ? "" : " (details: " + details + ")");
76 }
77 };
78
79 // Helper functions to create errors
80 inline FileError makeFileError(FileErrorCode code, const std::string &message,
81 const std::string &path = "") {
82 return FileError{code, message, path};
83 }
84
85 inline JsonError makeJsonError(JsonErrorCode code, const std::string &message,
86 const std::string &details = "") {
87 return JsonError{code, message, details};
88 }
89
90 // Custom Result<T, E> implementation (similar to std::expected from C++23)
91 // This is a simplified version - for production, consider using std::expected or a library
92 template <typename T, typename E>
93 class Result {
94 public:
95 // Constructors for success case
96 Result(const T &value) : data_(value), hasValue_(true) {}
97
98 Result(T &&value) : data_(std::move(value)), hasValue_(true) {}
99
100 // Constructor for error case
101 Result(const E &error) : data_(error), hasValue_(false) {}
102
103 Result(E &&error) : data_(std::move(error)), hasValue_(false) {}
104
105 // Check if result contains value
106 [[nodiscard]]
107 bool hasValue() const noexcept {
108 return hasValue_;
109 }
110
111 [[nodiscard]]
112 explicit operator bool() const noexcept {
113 return hasValue_;
114 }
115
116 // Get value (throws if error)
117 [[nodiscard]]
118 T &value() & {
119 if (!hasValue_) {
120 throw std::logic_error("Accessing value of Result with error");
121 }
122 return std::get<T>(data_);
123 }
124
125 [[nodiscard]]
126 const T &value() const & {
127 if (!hasValue_) {
128 throw std::logic_error("Accessing value of Result with error");
129 }
130 return std::get<T>(data_);
131 }
132
133 [[nodiscard]]
134 T &&value() && {
135 if (!hasValue_) {
136 throw std::logic_error("Accessing value of Result with error");
137 }
138 return std::get<T>(std::move(data_));
139 }
140
141 // Get error (throws if value)
142 [[nodiscard]]
143 E &error() & {
144 if (hasValue_) {
145 throw std::logic_error("Accessing error of Result with value");
146 }
147 return std::get<E>(data_);
148 }
149
150 [[nodiscard]]
151 const E &error() const & {
152 if (hasValue_) {
153 throw std::logic_error("Accessing error of Result with value");
154 }
155 return std::get<E>(data_);
156 }
157
158 [[nodiscard]]
159 E &&error() && {
160 if (hasValue_) {
161 throw std::logic_error("Accessing error of Result with value");
162 }
163 return std::get<E>(std::move(data_));
164 }
165
166 // Dereference operators (for value)
167 [[nodiscard]]
169 return &value();
170 }
171
172 [[nodiscard]]
173 const T *operator->() const {
174 return &value();
175 }
176
177 [[nodiscard]]
178 T &operator*() & {
179 return value();
180 }
181
182 [[nodiscard]]
183 const T &operator*() const & {
184 return value();
185 }
186
187 [[nodiscard]]
188 T &&operator*() && {
189 return std::move(value());
190 }
191
192 // Get value or default
193 template <typename U>
194 [[nodiscard]]
195 T valueOr(U &&defaultValue) const & {
196 return hasValue_ ? std::get<T>(data_) : static_cast<T>(std::forward<U>(defaultValue));
197 }
198
199 template <typename U>
200 [[nodiscard]]
201 T valueOr(U &&defaultValue) && {
202 return hasValue_ ? std::get<T>(std::move(data_))
203 : static_cast<T>(std::forward<U>(defaultValue));
204 }
205
206 private:
207 std::variant<T, E> data_;
208 bool hasValue_;
209 };
210
211 // Specialization for void return type
212 template <typename E>
213 class Result<void, E> {
214 public:
215 // Constructor for success case
216 Result() : error_(std::nullopt), hasValue_(true) {}
217
218 // Constructor for error case
219 Result(const E &error) : error_(error), hasValue_(false) {}
220
221 Result(E &&error) : error_(std::move(error)), hasValue_(false) {}
222
223 [[nodiscard]]
224 bool hasValue() const noexcept {
225 return hasValue_;
226 }
227
228 [[nodiscard]]
229 explicit operator bool() const noexcept {
230 return hasValue_;
231 }
232
233 [[nodiscard]]
234 E &error() & {
235 if (hasValue_) {
236 throw std::logic_error("Accessing error of successful Result");
237 }
238 return *error_;
239 }
240
241 [[nodiscard]]
242 const E &error() const & {
243 if (hasValue_) {
244 throw std::logic_error("Accessing error of successful Result");
245 }
246 return *error_;
247 }
248
249 private:
250 std::optional<E> error_;
251 bool hasValue_;
252 };
253
254} // namespace dotnamecpp::utils
bool hasValue() const noexcept
Definition UtilsError.hpp:224
Result()
Definition UtilsError.hpp:216
Result(E &&error)
Definition UtilsError.hpp:221
Result(const E &error)
Definition UtilsError.hpp:219
E & error() &
Definition UtilsError.hpp:234
const E & error() const &
Definition UtilsError.hpp:242
T & operator*() &
Definition UtilsError.hpp:178
T valueOr(U &&defaultValue) &&
Definition UtilsError.hpp:201
T & value() &
Definition UtilsError.hpp:118
Result(const E &error)
Definition UtilsError.hpp:101
Result(const T &value)
Definition UtilsError.hpp:96
E & error() &
Definition UtilsError.hpp:143
bool hasValue() const noexcept
Definition UtilsError.hpp:107
T valueOr(U &&defaultValue) const &
Definition UtilsError.hpp:195
T * operator->()
Definition UtilsError.hpp:168
const T * operator->() const
Definition UtilsError.hpp:173
T && value() &&
Definition UtilsError.hpp:134
T && operator*() &&
Definition UtilsError.hpp:188
const T & operator*() const &
Definition UtilsError.hpp:183
const E & error() const &
Definition UtilsError.hpp:151
Result(E &&error)
Definition UtilsError.hpp:103
const T & value() const &
Definition UtilsError.hpp:126
Result(T &&value)
Definition UtilsError.hpp:98
E && error() &&
Definition UtilsError.hpp:159
Definition DirectoryManager.cpp:5
JsonError makeJsonError(JsonErrorCode code, const std::string &message, const std::string &details="")
Definition UtilsError.hpp:85
FileError makeFileError(FileErrorCode code, const std::string &message, const std::string &path="")
Definition UtilsError.hpp:80
FileErrorCode
Definition UtilsError.hpp:12
@ NotFound
Definition UtilsError.hpp:13
@ WriteError
Definition UtilsError.hpp:17
@ IsDirectory
Definition UtilsError.hpp:19
@ InvalidPath
Definition UtilsError.hpp:18
@ Unknown
Definition UtilsError.hpp:21
@ AlreadyExists
Definition UtilsError.hpp:15
@ NotDirectory
Definition UtilsError.hpp:20
@ AccessDenied
Definition UtilsError.hpp:14
@ ReadError
Definition UtilsError.hpp:16
@ Unknown
Definition IPlatformInfo.hpp:10
JsonErrorCode
Definition UtilsError.hpp:25
@ FileNotFound
Definition UtilsError.hpp:28
@ MissingKey
Definition UtilsError.hpp:30
@ Unknown
Definition UtilsError.hpp:31
@ InvalidType
Definition UtilsError.hpp:29
@ ParseError
Definition UtilsError.hpp:26
@ InvalidStructure
Definition UtilsError.hpp:27
Definition UtilsError.hpp:35
std::string message
Definition UtilsError.hpp:37
std::string toString() const
Definition UtilsError.hpp:41
FileErrorCode code
Definition UtilsError.hpp:36
std::string path
Definition UtilsError.hpp:38
Definition UtilsError.hpp:59
std::string details
Definition UtilsError.hpp:62
JsonErrorCode code
Definition UtilsError.hpp:60
std::string toString() const
Definition UtilsError.hpp:65
std::string message
Definition UtilsError.hpp:61