13 #include <daw/daw_string_view.h>
14 #include <daw/daw_traits.h>
15 #include <daw/daw_unreachable.h>
24 #include <string_view>
28 namespace json_details {
29 struct missing_member {
30 char const *member_name;
32 template<
typename StringView,
34 ( traits::not_same<StringView, missing_member>::value ),
35 std::nullptr_t> =
nullptr>
36 explicit constexpr missing_member( StringView name )
37 : member_name( std::data( name ) ) {
38 if( member_name and member_name[0] ==
'\a' ) {
39 member_name =
"no_name";
43 template<std::
size_t N>
44 explicit constexpr missing_member(
char const ( &s )[N] )
46 if( member_name and member_name[0] ==
'\a' ) {
47 member_name =
"no_name";
52 struct missing_token {
54 explicit constexpr missing_token(
char c )
60 enum class ErrorReason {
65 InvalidNumberUnexpectedQuoting,
72 InvalidStringHighASCII,
73 ExpectedKeyValueToStartWithBrace,
74 ExpectedKeyValueArrayToStartWithBracket,
92 ExpectedArrayOrClassStart,
95 AttemptToAccessPastEndOfValue,
96 OutOfOrderOrderedMembers,
97 MissingMemberNameOrEndOfClass,
100 ExpectedMemberNotFound,
101 ExpectedTokenNotFound,
102 UnexpectedJSONVariantType,
106 constexpr std::string_view reason_message( ErrorReason er ) {
107 using namespace std::string_view_literals;
109 case ErrorReason::Unknown:
110 return "Unknown reason for error"sv;
111 case ErrorReason::UnexpectedEndOfData:
112 return "Unexpected end of data"sv;
113 case ErrorReason::InvalidNumber:
114 return "Invalid Number"sv;
115 case ErrorReason::InvalidNumberStart:
116 return R
"(Invalid Number started, expected a "0123456789-")"sv;
117 case ErrorReason::InvalidNumberUnexpectedQuoting:
118 return "Unexpected double quote prior to number"sv;
119 case ErrorReason::InvalidTimestamp:
120 return "Invalid Timestamp"sv;
121 case ErrorReason::InvalidUTFEscape:
122 return "Invalid UTF Escape"sv;
123 case ErrorReason::InvalidUTFCodepoint:
124 return "Invalid UTF Codepoint"sv;
125 case ErrorReason::InvalidEndOfValue:
126 return R
"(Did not find \",}]" at end of value)"sv;
127 case ErrorReason::InvalidLiteral:
128 return "Literal data was corrupt"sv;
129 case ErrorReason::InvalidString:
130 return "Invalid or corrupt string"sv;
131 case ErrorReason::InvalidStringHighASCII:
132 return "String support limited to 0x20 < chr <= 0x7F when "
133 "DisallowHighEightBit is true"sv;
134 case ErrorReason::ExpectedKeyValueToStartWithBrace:
135 return "Expected key/value's JSON type to be of class type and "
138 case ErrorReason::ExpectedKeyValueArrayToStartWithBracket:
139 return "Expected key/value's JSON type to be of array type and "
142 case ErrorReason::InvalidArrayStart:
143 return "Expected array type to begin with '['"sv;
144 case ErrorReason::InvalidClassStart:
145 return "Expected class type to begin with '{'"sv;
146 case ErrorReason::InvalidStartOfValue:
147 return "Unexpected character data at start of value"sv;
148 case ErrorReason::InvalidTrue:
149 return "Expected true not found"sv;
150 case ErrorReason::InvalidFalse:
151 return "Expected false not found"sv;
152 case ErrorReason::InvalidNull:
153 return "Expected null not found"sv;
154 case ErrorReason::UnexpectedNull:
155 return "An unexpected null value was encountered while serializing"sv;
156 case ErrorReason::NumberIsNaN:
157 return "NaN encountered while serializing to JSON Number literal"sv;
158 case ErrorReason::NumberIsInf:
159 return "Infinity encountered while serializing to JSON Number literal"sv;
160 case ErrorReason::NumberOutOfRange:
161 return "Number is outside of the representable range"sv;
162 case ErrorReason::EmptyJSONDocument:
163 return "Attempt to parse an empty JSON document"sv;
164 case ErrorReason::EmptyJSONPath:
165 return "Empty JSON Path specified"sv;
166 case ErrorReason::JSONPathNotFound:
167 return "JSON Path specified not found in document"sv;
168 case ErrorReason::InvalidJSONPath:
169 return "Invalid JSON Path specified"sv;
170 case ErrorReason::NullOutputIterator:
171 return "Null pointer specified for output"sv;
172 case ErrorReason::MissingMemberNameOrEndOfClass:
173 return "Missing member name or end of class"sv;
174 case ErrorReason::MissingMemberName:
175 return "Missing member name"sv;
176 case ErrorReason::InvalidMemberName:
177 return "Member names must be JSON strings"sv;
178 case ErrorReason::ExpectedArrayOrClassStart:
179 return "Expected start of a JSON class or array"sv;
180 case ErrorReason::UnknownMember:
181 return "Could not find member in JSON class"sv;
182 case ErrorReason::InvalidBracketing:
183 return "Invalid Bracketing"sv;
184 case ErrorReason::AttemptToAccessPastEndOfValue:
185 return "A value of known size was accessed past the end"sv;
186 case ErrorReason::OutOfOrderOrderedMembers:
187 return "Order of ordered members must be ascending"sv;
188 case ErrorReason::MemberNotFound:
189 return "Expected member not found"sv;
190 case ErrorReason::TagMemberNotFound:
191 return "Expected tag member not found, they are required for tagged "
193 case ErrorReason::ExpectedMemberNotFound:
194 return "Expected member missing"sv;
195 case ErrorReason::ExpectedTokenNotFound:
196 return "Expected token missing"sv;
197 case ErrorReason::UnexpectedJSONVariantType:
198 return "Unexpected JSON Variant Type"sv;
199 case ErrorReason::TrailingComma:
200 return "Trailing comma"sv;
210 class json_exception {
211 ErrorReason m_reason = ErrorReason::Unknown;
216 explicit constexpr data_t(
char const *p )
218 explicit constexpr data_t(
char t )
221 char const *m_parse_loc =
nullptr;
224 constexpr json_exception( ) =
default;
226 explicit constexpr json_exception( ErrorReason reason )
227 : m_reason( reason ) {}
229 explicit constexpr json_exception( json_details::missing_member mm )
230 : m_reason( ErrorReason::MemberNotFound )
231 , m_data( mm.member_name ) {}
233 explicit constexpr json_exception( json_details::missing_token mt )
234 : m_reason( ErrorReason::ExpectedTokenNotFound )
235 , m_data( mt.token ) {}
237 explicit constexpr json_exception( json_details::missing_member mm,
238 std::string_view location )
239 : m_reason( ErrorReason::MemberNotFound )
240 , m_data( mm.member_name )
241 , m_parse_loc( std::data( location ) ) {}
243 explicit constexpr json_exception( json_details::missing_token mt,
244 char const *location )
245 : m_reason( ErrorReason::ExpectedTokenNotFound )
247 , m_parse_loc( location ) {}
249 explicit constexpr json_exception( ErrorReason reason,
250 char const *location )
252 , m_parse_loc( location ) {}
254 [[nodiscard]] constexpr ErrorReason reason_type( )
const {
258 [[nodiscard]]
inline std::string reason( )
const {
259 #if defined( __clang__ )
260 #pragma clang diagnostic push
261 #pragma clang diagnostic ignored "-Wswitch-enum"
264 case ErrorReason::MemberNotFound: {
265 using namespace std::string_literals;
266 return "Could not find required class member '"s +
267 static_cast<std::string
>( m_data.pointer ) +
"'"s;
269 case ErrorReason::ExpectedTokenNotFound: {
270 using namespace std::string_literals;
271 return "Could not find expected parse token '"s + m_data.token +
"'"s;
274 return std::string( ( reason_message( m_reason ) ) );
276 #if defined( __clang__ )
277 #pragma clang diagnostic pop
281 [[nodiscard]] constexpr
char const *parse_location( )
const {
292 to_formatted_string( json_exception
const &je,
293 char const *json_document =
nullptr ) {
294 using namespace std::string_literals;
295 std::string result =
"reason: "s + je.reason( );
296 if( json_document ==
nullptr or je.parse_location( ) ==
nullptr ) {
299 auto const previous_char_count =
300 std::min(
static_cast<std::size_t
>( 50 ),
301 static_cast<std::size_t
>( std::distance(
302 json_document, je.parse_location( ) + 1 ) ) );
303 auto const loc_data = std::string_view(
304 std::prev( je.parse_location( ),
305 static_cast<std::ptrdiff_t
>( previous_char_count ) ),
306 previous_char_count + 1 );
308 result +=
"\nlocation:\x1b[1m";
311 std::accumulate( std::data( loc_data ), daw::data_end( loc_data ),
312 std::string{ }, []( std::string s,
char c ) {
313 if( ( c !=
'\n' ) & ( c !=
'\r' ) ) {
319 result +=
"\x1b[0m\n";
Definition: daw_from_json.h:22
#define DAW_JSON_VER
Definition: version.h:11