169 std::function<void(
const nlohmann::ordered_json &j,
void *obj)>
readField;
174 std::function<void(nlohmann::ordered_json &j,
const void *obj)>
writeField;
228 template <
typename T>
232 static std::vector<FieldMeta> &fieldsMut()
234 static std::vector<FieldMeta> fs;
239 static std::vector<CrossFieldCheck> &checksMut()
241 static std::vector<CrossFieldCheck> cs;
246 static std::vector<ContextualCheck> &ctxChecksMut()
248 static std::vector<ContextualCheck> cs;
253 static std::function<void(T &)> &postReadHookMut()
255 static std::function<void(T &)> hook;
269 fieldsMut().push_back(std::move(meta));
278 checksMut().push_back(std::move(check));
287 ctxChecksMut().push_back(std::move(check));
295 postReadHookMut() = std::move(hook);
303 static const std::vector<FieldMeta> &
fields() {
return fieldsMut(); }
306 static const std::vector<CrossFieldCheck> &
checks() {
return checksMut(); }
328 for (
const auto &f :
fields())
332 f.readField(j, &obj);
334 catch (
const std::exception &e)
336 throw std::runtime_error(
337 fmt::format(
"Error reading config field '{}': {}", f.name, e.what()));
340 auto &hook = postReadHookMut();
354 for (
const auto &f :
fields())
355 f.writeField(j, &obj);
379 static nlohmann::ordered_json
emitSchema(
const std::string §ionDescription =
"")
381 nlohmann::ordered_json schema;
382 schema[
"type"] =
"object";
383 if (!sectionDescription.empty())
384 schema[
"description"] = sectionDescription;
385 auto &props = schema[
"properties"] = nlohmann::ordered_json::object();
386 for (
const auto &f :
fields())
387 props[f.name] = f.schemaEntry();
399 static std::vector<CheckResult>
validate(
const T &obj)
401 std::vector<CheckResult> failures;
402 for (
const auto &check :
checks())
404 auto r = check(
static_cast<const void *
>(&obj));
406 failures.push_back(std::move(
r));
421 auto r = check(
static_cast<const void *
>(&obj), ctx);
423 failures.push_back(std::move(
r));
443 if (!userJson.is_object())
445 for (
const auto &[key, val] : userJson.items())
448 for (
const auto &f :
fields())
458 throw std::runtime_error(
459 fmt::format(
"Unknown configuration key '{}'. Check spelling or "
460 "use --emit-schema to see valid keys.",
Core type aliases, constants, and metaprogramming utilities for the DNDS framework.
Assertion / error-handling macros and supporting helper functions.
JSON-to-Eigen conversion utilities and nlohmann_json helper macros.
Core 2D variable-length array container, the storage foundation of DNDSR.
Per-type singleton registry of config field metadata and validation checks.
static const std::vector< ContextualCheck > & contextualChecks()
All registered context-aware checks.
static bool registerField(FieldMeta meta)
Register a single field's metadata.
static bool registerCheck(CrossFieldCheck check)
Register a cross-field validation check (no runtime context needed).
static const std::vector< CrossFieldCheck > & checks()
All registered context-free checks.
static std::vector< CheckResult > validateWithContext(const T &obj, const ConfigContext &ctx)
Run all checks (both context-free and context-aware) on a struct instance.
static void readFromJson(const nlohmann::ordered_json &j, T &obj)
Deserialize all registered fields from a JSON object into a struct.
static const std::vector< FieldMeta > & fields()
All registered field descriptors, in declaration order.
static bool registerContextualCheck(ContextualCheck check)
Register a cross-field validation check that needs runtime context.
static void validateKeys(const nlohmann::ordered_json &userJson)
Check that every key in a user-supplied JSON object corresponds to a registered field....
static nlohmann::ordered_json emitSchema(const std::string §ionDescription="")
Emit a JSON Schema (draft-07) object describing all registered fields.
static void writeToJson(nlohmann::ordered_json &j, const T &obj)
Serialize all registered fields from a struct into a JSON object.
static std::vector< CheckResult > validate(const T &obj)
Run all context-free cross-field checks on a struct instance.
static void registerPostReadHook(std::function< void(T &)> hook)
Register a post-read hook called after all fields are deserialized. Useful for recomputing derived qu...
the host side operators are provided as implemented
std::function< CheckResult(const void *obj)> CrossFieldCheck
A cross-field validation check that does not require runtime context.
std::function< CheckResult(const void *obj, const ConfigContext &ctx)> ContextualCheck
A cross-field validation check that requires runtime context.
ConfigTypeTag
Enumerates the JSON Schema type associated with a config field.
Result of a single validation check.
Runtime context supplied to context-aware validation checks.
int modelCode
Integer code identifying the EulerModel enum value.
int nVars
Number of solution variables (model-dependent).
int gDim
Geometric dimension (2 or 3).
int dim
Spatial dimension (2 or 3).