JSON Convert Helpers
vix/json/convert.hpp provides safe JSON accessors and converters for Vix.cpp, built on nlohmann::json.
It removes repetitive boilerplate like:
contains()+is_*()checks everywhere- try/catch around
get<T>() - manual handling of missing keys and out-of-range indexes
It also includes helpers to convert Vix Simple JSON tokens into nlohmann::json.
Include
#include <vix/json/convert.hpp>
using namespace vix::json;Strictness levels
This header gives you four levels of strictness. Choose based on how much you trust the JSON.
Rule of thumb:
- External/user input: prefer
get_opt()orget_or() - Internal/trusted data: prefer
ensure()
1) ptr()
Returns a pointer to an element, or nullptr if missing or invalid.
ptr(obj, "key")->const Json*ptr(arr, idx)->const Json*
Use this when you want to branch without allocating, copying, or throwing.
2) get_opt<T>()
Returns std::optional<T>. It never throws.
It catches nlohmann::json::exception internally and returns std::nullopt if conversion fails.
3) get_or<T>()
Returns a value or a default when missing/invalid.
This is the most convenient option for external input when you have sensible defaults.
4) ensure<T>()
Strict conversion. It throws when:
- the JSON is not the expected shape
- a key is missing
- the type does not match
Use it when failure should be loud and immediate.
Types
This header uses the same core type alias as other JSON helpers:
using Json = nlohmann::json;ptr() reference
ptr(const Json& j, std::string_view key)
Returns a pointer to j[key] if j is an object and the key exists.
Json j = R"({"user":{"id":42}})"_json;
if (const Json* p = ptr(j, "user"))
{
// p points to {"id":42}
}Notes:
- Returns
nullptrwhenjis not an object - Returns
nullptrwhen key does not exist - This implementation allocates a temporary
std::stringfor the key for compatibility acrossnlohmann::jsonversions
ptr(const Json& j, std::size_t idx)
Returns a pointer to j[idx] if j is an array and idx is within bounds.
Json j = R"([10, 20, 30])"_json;
if (const Json* p = ptr(j, 1))
{
// *p is 20
}get_opt<T>() reference
Convert a value
Json j = R"({"id":42, "name":"Ada"})"_json;
auto id = get_opt<int>(j["id"]); // optional<int>(42)
auto name = get_opt<std::string>(j["name"]); // optional<string>("Ada")Convert from a pointer
const Json* p = ptr(j, "id");
auto id = get_opt<int>(p);Convert an object member by key
auto id = get_opt<int>(j, "id");Convert an array element by index
Json arr = R"([1,2,3])"_json;
auto v = get_opt<int>(arr, 2); // 3Behavior:
- returns
std::nulloptifjis null/discarded - returns
std::nulloptifget<T>()throws
get_or<T>() reference
Convert a value with a default
Json j = R"({"debug":"true"})"_json;
bool debug = get_or<bool>(j["debug"], false); // false (type mismatch)Convert an object member with a default
Json j = R"({"user":{"id":42}})"_json;
int id = get_or<int>(j["user"], "id", -1); // 42
int age = get_or<int>(j["user"], "age", 0); // 0 (missing key)Convert an array element with a default
Json xs = R"([10,20])"_json;
int v0 = get_or<int>(xs, 0, -1); // 10
int v2 = get_or<int>(xs, 2, -1); // -1 (out of bounds)ensure<T>() reference
Strict conversion of a value
Json j = R"({"id":42})"_json;
int id = ensure<int>(j["id"]); // okStrict conversion of an object member
ensure(obj, key) provides clearer errors:
- throws if
objis not an object - throws if key is missing
- throws with a message that includes the key on type mismatch
Json j = R"({"user":{"id":42}})"_json;
int id = ensure<int>(j["user"], "id"); // okExample failure cases you should expect:
ensure: not an objectensure: missing key 'id'ensure: type error for key 'id': ...
Tip: this is ideal for trusted config files or internal data where you want hard failures.
Converting Vix Simple JSON to nlohmann::json
This header also converts Vix Simple tokens into nlohmann::json.
Supported conversions:
- null -> null
- bool -> bool
- int64 -> integer
- double -> float
- string -> string
- array/object -> deep conversion
simple_to_json(token|kvs|array_t)
#include <vix/json/Simple.hpp>
#include <vix/json/convert.hpp>
using namespace vix::json;
// Suppose you parsed with the Simple parser:
vix::json::token t = /* ... */;
Json j = simple_to_json(t);
std::cout << j.dump(2) << "\n";to_json(...) convenience overloads
Aliases to keep naming consistent:
Json j1 = to_json(t);
vix::json::kvs obj = /* ... */;
Json j2 = to_json(obj);
vix::json::array_t arr = /* ... */;
Json j3 = to_json(arr);Practical patterns
Parsing external payload safely
Json body = /* request json */;
auto id = get_opt<int>(body, "id");
auto name = get_or<std::string>(body, "name", "anonymous");
if (!id)
{
// return 400: missing/invalid id
}Trusted config parsing strictly
Json cfg = /* config json */;
std::string host = ensure<std::string>(cfg, "host");
int port = ensure<int>(cfg, "port");
bool tls = get_or<bool>(cfg, "tls", false);Summary
vix/json/convert.hpp gives you predictable, low-boilerplate JSON access:
ptr()for pointer-style access without throwingget_opt<T>()for safe optional conversionget_or<T>()for defaults on missing/invalid dataensure<T>()for strict conversions with clear errorssimple_to_json()andto_json()for converting Vix Simple JSON intonlohmann::json