/* * Copyright 2025 Axel Waggershauser */ // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ZXAlgorithms.h" #include #ifdef __cpp_lib_format // not available on gcc 12 #include #endif #include #include #include namespace ZXing { std::string JsonEscapeStr(std::string_view str); std::string JsonUnEscapeStr(std::string_view str); template 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) return val != ignore ? ZX_JSON_KEY_VAL(val ? "true" : "false") : ""; else if constexpr (std::is_floating_point_v) return val != ignore ? ZX_JSON_KEY_VAL(ZX_JSON_FMT_FLOAT(val)) : ""; else if constexpr (std::is_integral_v) return val != ignore ? ZX_JSON_KEY_VAL(std::to_string(val)) : ""; else if constexpr (std::is_convertible_v) 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 inline std::optional 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) return str.empty() || Contains("1tT", str.front()) ? std::optional(true) : std::nullopt; else if constexpr (std::is_arithmetic_v) return str.empty() ? std::nullopt : std::optional(FromString(str)); else if constexpr (std::is_same_v) return JsonUnEscapeStr(str); else static_assert("unsupported JSON value type"); } } // ZXing