You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
66 lines
2.1 KiB
66 lines
2.1 KiB
/* |
|
* Copyright 2025 Axel Waggershauser |
|
*/ |
|
// SPDX-License-Identifier: Apache-2.0 |
|
|
|
#pragma once |
|
|
|
#include "ZXAlgorithms.h" |
|
|
|
#include <cstring> |
|
#ifdef __cpp_lib_format // not available on gcc 12 |
|
#include <format> |
|
#endif |
|
#include <optional> |
|
#include <string> |
|
#include <string_view> |
|
|
|
namespace ZXing { |
|
|
|
std::string JsonEscapeStr(std::string_view str); |
|
std::string JsonUnEscapeStr(std::string_view str); |
|
|
|
template<typename T> |
|
inline std::string JsonProp(std::string_view key, const T& val, const T& ignore = {}) |
|
{ |
|
#define ZX_JSON_KEY_VAL(...) StrCat("\"", key, "\":", __VA_ARGS__, ',') |
|
#if !defined(__cpp_lib_to_chars) || !defined(__cpp_lib_format) // not available on older macOS / gcc 12 |
|
#define ZX_JSON_FMT_FLOAT(val) (std::to_string(int(val)) + '.' + std::to_string(int(val * 100) % 100)) |
|
#else |
|
#define ZX_JSON_FMT_FLOAT(val) std::format("{:.2f}", val) |
|
#endif |
|
|
|
if constexpr (std::is_same_v<T, bool>) |
|
return val != ignore ? ZX_JSON_KEY_VAL(val ? "true" : "false") : ""; |
|
else if constexpr (std::is_floating_point_v<T>) |
|
return val != ignore ? ZX_JSON_KEY_VAL(ZX_JSON_FMT_FLOAT(val)) : ""; |
|
else if constexpr (std::is_integral_v<T>) |
|
return val != ignore ? ZX_JSON_KEY_VAL(std::to_string(val)) : ""; |
|
else if constexpr (std::is_convertible_v<T, std::string_view>) |
|
return std::string_view(val) != std::string_view(ignore) ? ZX_JSON_KEY_VAL("\"", JsonEscapeStr(val), "\"") : ""; |
|
else |
|
static_assert("unsupported JSON value type"); |
|
#undef ZX_JSON_KEY_VAL |
|
} |
|
|
|
// Finds the (potentially escaped / raw) value of the provided key |
|
std::string_view JsonFind(std::string_view json, std::string_view key); |
|
|
|
template <typename T> |
|
inline std::optional<T> JsonGet(std::string_view json, std::string_view key) |
|
{ |
|
auto str = JsonFind(json, key); |
|
if (!str.data()) |
|
return std::nullopt; |
|
|
|
if constexpr (std::is_same_v<bool, T>) |
|
return str.empty() || Contains("1tT", str.front()) ? std::optional(true) : std::nullopt; |
|
else if constexpr (std::is_arithmetic_v<T>) |
|
return str.empty() ? std::nullopt : std::optional(FromString<T>(str)); |
|
else if constexpr (std::is_same_v<std::string, T>) |
|
return JsonUnEscapeStr(str); |
|
else |
|
static_assert("unsupported JSON value type"); |
|
} |
|
|
|
} // ZXing
|
|
|