ppforest2 v0.1.0
Projection Pursuit Decision Trees and Random Forests
Loading...
Searching...
No Matches
ppforest2::JsonReader Class Reference

A small DSL for extracting-and-validating values out of a JSON object with path-aware error messages. More...

#include <JsonReader.hpp>

Public Member Functions

 JsonReader (nlohmann::json const &j, std::string path)
 
JsonReader at (std::string const &key) const
 Descend into a required sub-object.
 
bool contains (std::string const &key) const
 Whether key is present on the wrapped object.
 
void forbid_key (std::string const &key, std::string const &reason) const
 Throw if key is present and non-null on the wrapped object.
 
nlohmann::json const & json () const
 The raw underlying JSON (escape hatch for unusual cases).
 
void only_keys (std::initializer_list< char const * > allowed) const
 Assert the wrapped object contains only the given keys.
 
template<typename T>
optional (std::string const &key, T fallback) const
 Extract an optional typed value, falling back to fallback.
 
std::string const & path () const
 The path prefix used in error messages.
 
template<typename T>
require (std::string const &key) const
 Extract a required typed value.
 
nlohmann::json const & require_array (std::string const &key) const
 Return a const reference to a required array field.
 
std::string require_enum (std::string const &key, std::initializer_list< char const * > allowed) const
 Extract a required string constrained to allowed values.
 
long long require_int (std::string const &key, long long min=std::numeric_limits< long long >::min(), long long max=std::numeric_limits< long long >::max()) const
 Extract a required integer value, optionally constrained.
 
void require_keys (std::initializer_list< char const * > keys) const
 Assert every key in keys is present on the wrapped object.
 
double require_number (std::string const &key, double min=-std::numeric_limits< double >::infinity(), double max=std::numeric_limits< double >::infinity()) const
 Extract a required number (double), optionally constrained.
 
void require_object () const
 Assert the wrapped value is a JSON object.
 
void require_string_array (std::string const &key, bool non_empty=false) const
 Assert key is an array of strings, optionally non-empty.
 
Discard-result siblings of <tt>require_*</tt> for validators that don't need the value.
void expect_enum (std::string const &key, std::initializer_list< char const * > allowed) const
 
void expect_int (std::string const &key, long long min=std::numeric_limits< long long >::min(), long long max=std::numeric_limits< long long >::max()) const
 
void expect_number (std::string const &key, double min=-std::numeric_limits< double >::infinity(), double max=std::numeric_limits< double >::infinity()) const
 
void expect_array (std::string const &key) const
 

Detailed Description

A small DSL for extracting-and-validating values out of a JSON object with path-aware error messages.

JsonReader wraps a nlohmann::json object and a dotted path (e.g. "config.pp"). Every extraction method throws std::runtime_error with a message that names the offending field:

"config.pp.lambda: expected number, got string" "config.pp: unexpected key 'lamda' (allowed: name, lambda)" "config.stop.min_size: must be in [2, ∞) (got 0)"

Used both at the top level (see serialization::validate_model_export) and inside every strategy's from_json. Unifies what validate_json_keys

  • j.at(k).get<T>() used to do piecemeal.

Scope is deliberately small:

  • typed field extraction (require<T> / optional<T>)
  • enum-like string validation (require_enum)
  • numeric range validation (require_number / require_int)
  • unknown-key rejection (only_keys)
  • nested-object descent (at)
  • array access (require_array)

The DSL is not a schema validator and cannot express composition (oneOf, allOf, recursive schemas). If you find yourself wanting those, bring in a real schema library instead of growing this file.

Constructor & Destructor Documentation

◆ JsonReader()

ppforest2::JsonReader::JsonReader ( nlohmann::json const & j,
std::string path )
Parameters
jThe JSON object this reader wraps.
pathDotted path used as the prefix for error messages (e.g. "config.pp"). The reader does not verify that j itself is an object at construction — use require_object() explicitly for that.

Member Function Documentation

◆ at()

JsonReader ppforest2::JsonReader::at ( std::string const & key) const

Descend into a required sub-object.

Exceptions
std::runtime_errorif key is missing or not an object.

◆ contains()

bool ppforest2::JsonReader::contains ( std::string const & key) const

Whether key is present on the wrapped object.

◆ expect_array()

void ppforest2::JsonReader::expect_array ( std::string const & key) const
inline

◆ expect_enum()

void ppforest2::JsonReader::expect_enum ( std::string const & key,
std::initializer_list< char const * > allowed ) const
inline

◆ expect_int()

void ppforest2::JsonReader::expect_int ( std::string const & key,
long long min = std::numeric_limits<long long>::min(),
long long max = std::numeric_limits<long long>::max() ) const
inline

◆ expect_number()

void ppforest2::JsonReader::expect_number ( std::string const & key,
double min = -std::numeric_limits<double>::infinity(),
double max = std::numeric_limits<double>::infinity() ) const
inline

◆ forbid_key()

void ppforest2::JsonReader::forbid_key ( std::string const & key,
std::string const & reason ) const

Throw if key is present and non-null on the wrapped object.

Mode-homogeneous schemas use this to express "this field must be absent / null in this variant" — e.g. classification's meta.groups is required, regression's must be null.

◆ json()

nlohmann::json const & ppforest2::JsonReader::json ( ) const
inline

The raw underlying JSON (escape hatch for unusual cases).

◆ only_keys()

void ppforest2::JsonReader::only_keys ( std::initializer_list< char const * > allowed) const

Assert the wrapped object contains only the given keys.

Exceptions
std::runtime_errornaming the first unexpected key it finds (plus the list of allowed keys for context).

◆ optional()

template<typename T>
T ppforest2::JsonReader::optional ( std::string const & key,
T fallback ) const

Extract an optional typed value, falling back to fallback.

◆ path()

std::string const & ppforest2::JsonReader::path ( ) const
inline

The path prefix used in error messages.

◆ require()

template<typename T>
T ppforest2::JsonReader::require ( std::string const & key) const

Extract a required typed value.

Template Parameters
TTarget type (e.g. int, float, std::string).
Parameters
keyField name within the wrapped object.
Exceptions
`std::runtime_error`with the dotted path on missing keys or type mismatch.

◆ require_array()

nlohmann::json const & ppforest2::JsonReader::require_array ( std::string const & key) const

Return a const reference to a required array field.

Exceptions
std::runtime_errorif the key is missing or the value is not a JSON array.

◆ require_enum()

std::string ppforest2::JsonReader::require_enum ( std::string const & key,
std::initializer_list< char const * > allowed ) const

Extract a required string constrained to allowed values.

Exceptions
std::runtime_errorif the key is missing, not a string, or the value is not in the allowed set.

◆ require_int()

long long ppforest2::JsonReader::require_int ( std::string const & key,
long long min = std::numeric_limits< long long >::min(),
long long max = std::numeric_limits< long long >::max() ) const

Extract a required integer value, optionally constrained.

Accepts any JSON number whose value is an integer — both literals written without a fractional part (5) and equivalent numeric forms (5.0, 5e0). Non-integer fractions (5.5), non-finite numbers (NaN, Inf), and non-numeric types are rejected.

This matches JSON Schema's type: integer semantics, which is value-based: the spec (RFC 8259 §6) does not distinguish integer from non-integer JSON numbers at the format level, and JSON Schema defines integer as "any JSON number with zero fractional part." nlohmann's is_number_integer() is a parse-level tag (whether the literal had a decimal point) that's stricter than the spec — we deliberately don't inherit it. This means values round-tripped through languages that serialize all numbers uniformly (R, Python with default json.dumps) validate correctly.

Parameters
keyField name within the wrapped object.
minInclusive lower bound (default: no lower bound).
maxInclusive upper bound (default: no upper bound).

◆ require_keys()

void ppforest2::JsonReader::require_keys ( std::initializer_list< char const * > keys) const

Assert every key in keys is present on the wrapped object.

Mirror of only_keys: where that one rejects extra keys, this one rejects missing ones. Throws on the first absent key it finds.

◆ require_number()

double ppforest2::JsonReader::require_number ( std::string const & key,
double min = -std::numeric_limits< double >::infinity(),
double max = std::numeric_limits< double >::infinity() ) const

Extract a required number (double), optionally constrained.

◆ require_object()

void ppforest2::JsonReader::require_object ( ) const

Assert the wrapped value is a JSON object.

◆ require_string_array()

void ppforest2::JsonReader::require_string_array ( std::string const & key,
bool non_empty = false ) const

Assert key is an array of strings, optionally non-empty.

Exceptions
std::runtime_errorif the key is missing, not an array, empty (when non_empty is true), or contains non-string elements (path includes [i] for the offending index).

The documentation for this class was generated from the following file: