di 0.1.0
Loading...
Searching...
No Matches
json_deserializer_error.h
Go to the documentation of this file.
1#pragma once
2
5#include "di/format/style.h"
9#include "di/types/prelude.h"
18
20struct ReadError {
22
23 auto operator==(ReadError const&) const -> bool = default;
24};
25
27 auto operator==(ParseBoolError const&) const -> bool = default;
28};
29
33
34 auto operator==(ParseEnumError const&) const -> bool = default;
35};
36
40
41 auto operator==(ParseValueError const&) const -> bool = default;
42};
43
46
47 auto operator==(ParseNumberError const&) const -> bool = default;
48};
49
52
53 auto operator==(UnexpectedKeyError const&) const -> bool = default;
54};
55
62
66
67 auto operator==(MissingArrayElementsError const&) const -> bool = default;
68};
69
71 auto operator==(UnexpectedEndOfInputError const&) const -> bool = default;
72};
73
75 auto operator==(InvalidUtf8Error const&) const -> bool = default;
76};
77
81
85
86 auto operator==(ConcreteError const&) const -> bool = default;
87};
88
89class ErrorDomain;
90class Error;
92
93class Error {
94public:
95 Error() = default;
96
97 constexpr explicit Error(ErrorVariant error, di::String key)
98 : m_value(di::make_box<ConcreteError>(di::move(error), di::move(key))) {}
99
100 constexpr auto empty() const { return !m_value; }
101
102 constexpr auto inner() -> ConcreteError& { return *m_value; }
103 constexpr auto inner() const -> ConcreteError const& { return *m_value; }
104
105 constexpr auto operator==(Error const& other) const -> bool {
106 if (this->empty() != other.empty()) {
107 return false;
108 }
109 if (this->empty()) {
110 return true;
111 }
112 return *this->m_value == *other.m_value;
113 }
114
115 constexpr auto into_status_code() && -> ErrorCode;
116
117private:
118 constexpr friend auto tag_invoke(Tag<concepts::trivially_relocatable>, InPlaceType<Error>) -> bool { return true; }
119
121};
122
123class ErrorDomain final : public StatusCodeDomain {
124private:
125 using Base = StatusCodeDomain;
126
127public:
128 using Value = Error;
130
131 constexpr explicit ErrorDomain(UniqueId id = 0x3acfeb8908d1656b) : Base(id) {}
132
133 ErrorDomain(ErrorDomain const&) = default;
135
136 auto operator=(ErrorDomain const&) -> ErrorDomain& = default;
137 auto operator=(ErrorDomain&&) -> ErrorDomain& = default;
138
139 constexpr static auto get() -> ErrorDomain const&;
140
141 constexpr auto name() const -> container::ErasedString override {
142 return container::ErasedString(u8"JSON Deserializer Error Domain");
143 }
144
145 constexpr auto payload_info() const -> PayloadInfo override {
146 return { sizeof(Value), sizeof(Value) + sizeof(StatusCodeDomain const*),
147 container::max(alignof(Value), alignof(StatusCodeDomain const*)) };
148 }
149
150protected:
151 constexpr auto do_failure(vocab::StatusCode<void> const& code) const -> bool override {
152 auto const& value = down_cast(code);
153 return !value.value().empty();
154 }
155
156 constexpr auto do_equivalent(vocab::StatusCode<void> const& a, vocab::StatusCode<void> const& b) const
157 -> bool override {
158 DI_ASSERT(a.domain() == *this);
159 return b.domain() == *this && down_cast(a).value() == down_cast(b).value();
160 }
161
162 constexpr auto do_convert_to_generic(vocab::StatusCode<void> const& a) const -> vocab::GenericCode override {
163 DI_ASSERT(a.domain() == *this);
164 return a.failure() ? platform::BasicError::InvalidArgument : platform::BasicError::Success;
165 }
166
167 constexpr auto do_message(vocab::StatusCode<void> const& code) const -> container::ErasedString override {
168 DI_ASSERT(code.domain() == *this);
169 using Enc = di::String::Encoding;
170
171 auto const& value = down_cast(code).value().inner();
172 auto writer = StringWriter<>();
173 di::visit(
174 overload(
175 [&](ReadError const& error) {
176 writer_print<Enc>(writer, "Failing reading input stream while parsing '{}': {}"_sv, value.key,
177 error.error);
178 },
179 [&](ParseBoolError) {
180 writer_print<Enc>(writer, "Cannot parse '{}' as boolean"_sv, value.key);
181 },
182 [&](ParseEnumError const& error) {
183 writer_print<Enc>(writer, "Cannot parse '{}': '{}' as enum. Expected one of [ {} ]"_sv, value.key,
184 error.value, error.possible | di::join_with(", "_sv) | di::to<di::String>());
185 },
186 [&](ParseValueError const& error) {
187 writer_print<Enc>(writer, "Cannot parse '{}' as value for key '{}': {}"_sv, error.value, value.key,
188 error.error);
189 },
190 [&](ParseNumberError const& error) {
191 writer_print<Enc>(writer, "Cannot parse '{}': '{}' as number"_sv, value.key, error.input);
192 },
193 [&](UnexpectedKeyError const& error) {
194 writer_print<Enc>(writer, "Unexpected key '{}' while parsing '{}'"_sv, error.key, value.key);
195 },
197 writer_print<Enc>(writer, "Unexpected end of input while parsing '{}'"_sv, value.key);
198 },
199 [&](MissingArrayElementsError const& error) {
200 writer_print<Enc>(writer, "Expected {} elements but got {} while parsing '{}'"_sv, error.expected,
201 error.actual, value.key);
202 },
203 [&](UnexpectedCharacterError const& error) {
204 if (error.expected) {
205 writer_print<Enc>(writer, "Unexpected character while parsing '{}' (expected {}): {:?}"_sv,
206 value.key, error.expected.value(), error.code_point);
207 } else {
208 writer_print<Enc>(writer, "Unexpected character while parsing '{}': {:#4x}"_sv, value.key,
209 error.code_point);
210 }
211 },
212 [&](InvalidUtf8Error) {
213 writer_print<Enc>(writer, "Invalid UTF-8 byte detected while parsing '{}'"_sv, value.key);
214 }),
215 value.error);
216 return di::move(writer).output();
217 }
218
219private:
220 template<typename Domain>
222
223 constexpr auto down_cast(vocab::StatusCode<void> const& code) const -> ErrorCode const& {
224 DI_ASSERT(code.domain() == *this);
225 return static_cast<ErrorCode const&>(code);
226 }
227};
228
229constexpr auto Error::into_status_code() && -> ErrorCode {
230 return ErrorCode(di::in_place, di::move(*this));
231}
232
233constexpr inline auto error_domain = ErrorDomain {};
234
235constexpr auto ErrorDomain::get() -> ErrorDomain const& {
236 return error_domain;
237}
238}
#define DI_ASSERT(...)
Definition assert_bool.h:7
Definition erased_string.h:21
Definition vector.h:25
Definition string_writer.h:14
Definition json_deserializer_error.h:123
auto operator=(ErrorDomain const &) -> ErrorDomain &=default
static constexpr auto get() -> ErrorDomain const &
Definition json_deserializer_error.h:235
Error Value
Definition json_deserializer_error.h:128
constexpr auto name() const -> container::ErasedString override
Definition json_deserializer_error.h:141
constexpr auto do_convert_to_generic(vocab::StatusCode< void > const &a) const -> vocab::GenericCode override
Definition json_deserializer_error.h:162
constexpr auto do_equivalent(vocab::StatusCode< void > const &a, vocab::StatusCode< void > const &b) const -> bool override
Definition json_deserializer_error.h:156
constexpr auto payload_info() const -> PayloadInfo override
Definition json_deserializer_error.h:145
constexpr ErrorDomain(UniqueId id=0x3acfeb8908d1656b)
Definition json_deserializer_error.h:131
auto operator=(ErrorDomain &&) -> ErrorDomain &=default
Base::UniqueId UniqueId
Definition json_deserializer_error.h:129
constexpr auto do_failure(vocab::StatusCode< void > const &code) const -> bool override
Definition json_deserializer_error.h:151
constexpr auto do_message(vocab::StatusCode< void > const &code) const -> container::ErasedString override
Definition json_deserializer_error.h:167
Definition json_deserializer_error.h:93
constexpr Error(ErrorVariant error, di::String key)
Definition json_deserializer_error.h:97
constexpr auto operator==(Error const &other) const -> bool
Definition json_deserializer_error.h:105
constexpr friend auto tag_invoke(Tag< concepts::trivially_relocatable >, InPlaceType< Error >) -> bool
Definition json_deserializer_error.h:118
constexpr auto inner() -> ConcreteError &
Definition json_deserializer_error.h:102
constexpr auto empty() const
Definition json_deserializer_error.h:100
constexpr auto inner() const -> ConcreteError const &
Definition json_deserializer_error.h:103
Definition box.h:28
Definition optional_forward_declaration.h:5
constexpr StatusCodeDomain(UniqueId id)
Definition status_code_domain.h:29
constexpr auto id() const
Definition status_code_domain.h:12
u64 UniqueId
Definition status_code_domain.h:10
Definition status_code_forward_declaration.h:11
Definition variant.h:30
Definition sequence.h:12
string::StringImpl< string::Utf8Encoding > String
Definition string.h:11
constexpr auto max
Definition max.h:49
Definition json_deserializer_error.h:19
vocab::StatusCode< ErrorDomain > ErrorCode
Definition json_deserializer_error.h:91
Variant< ReadError, ParseBoolError, ParseEnumError, ParseValueError, ParseNumberError, UnexpectedKeyError, UnexpectedCharacterError, MissingArrayElementsError, UnexpectedEndOfInputError, InvalidUtf8Error > ErrorVariant
Definition json_deserializer_error.h:78
constexpr auto error_domain
Definition json_deserializer_error.h:233
size_t usize
Definition integers.h:33
__UINT8_TYPE__ u8
Definition integers.h:9
char32_t c32
Definition char.h:6
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
StatusCode< platform::GenericDomain > GenericCode
Definition status_code_forward_declaration.h:13
StatusCode< Erased< long > > Error
Definition error.h:8
Definition any_storable.h:9
constexpr auto into_status_code
Definition into_status_code.h:25
constexpr auto make_box
Definition box.h:171
constexpr auto writer_print
Definition writer_print.h:21
constexpr auto visit(Vis &&visitor, Vars &&... variants) -> R
Definition visit.h:39
constexpr auto to(Con &&container, Args &&... args)
Definition to.h:25
constexpr auto in_place
Definition in_place.h:8
constexpr auto overload
Definition overload.h:28
Definition json_deserializer_error.h:82
auto operator==(ConcreteError const &) const -> bool=default
di::String key
Definition json_deserializer_error.h:84
ErrorVariant error
Definition json_deserializer_error.h:83
Definition json_deserializer_error.h:74
auto operator==(InvalidUtf8Error const &) const -> bool=default
usize actual
Definition json_deserializer_error.h:64
auto operator==(MissingArrayElementsError const &) const -> bool=default
usize expected
Definition json_deserializer_error.h:65
Definition json_deserializer_error.h:26
auto operator==(ParseBoolError const &) const -> bool=default
Definition json_deserializer_error.h:30
di::Vector< String > possible
Definition json_deserializer_error.h:32
di::String value
Definition json_deserializer_error.h:31
auto operator==(ParseEnumError const &) const -> bool=default
Definition json_deserializer_error.h:44
di::String input
Definition json_deserializer_error.h:45
auto operator==(ParseNumberError const &) const -> bool=default
Definition json_deserializer_error.h:37
di::Error error
Definition json_deserializer_error.h:39
di::String value
Definition json_deserializer_error.h:38
auto operator==(ParseValueError const &) const -> bool=default
Definition json_deserializer_error.h:20
auto operator==(ReadError const &) const -> bool=default
di::Error error
Definition json_deserializer_error.h:21
auto operator==(UnexpectedCharacterError const &) const -> bool=default
di::Optional< c32 > expected
Definition json_deserializer_error.h:58
c32 code_point
Definition json_deserializer_error.h:57
auto operator==(UnexpectedEndOfInputError const &) const -> bool=default
Definition json_deserializer_error.h:50
auto operator==(UnexpectedKeyError const &) const -> bool=default
di::String key
Definition json_deserializer_error.h:51
Definition in_place_type.h:5
Definition status_code_domain.h:16