载入中...
搜索中...
未找到
Schema.cpp
浏览该文件的文档.
1#include "schema/Schema.h"
2
5
6#include <simplesquirrel/simplesquirrel.hpp>
7
8#include <cstdio>
9#include <cstring>
10#include <string>
11#include <unordered_set>
12
13namespace eve::schema {
14
16
17Schema::Schema() = default;
18
19eve::Result<void> Schema::registerJson(const std::string& json) {
20 auto result = SchemaRegistry::registerFromJson(json);
21 if (!result.ok()) return eve::Result<void>::failure(result.status());
22 validationErrors_.clear();
24}
25
26namespace {
27
29ValueType typeFromSquirrel(ssq::Type type) {
30 switch (type) {
31 case ssq::Type::INTEGER: return ValueType::Integer;
32 case ssq::Type::FLOAT: return ValueType::Number;
33 case ssq::Type::BOOL: return ValueType::Boolean;
34 case ssq::Type::STRING: return ValueType::String;
35 case ssq::Type::ARRAY: return ValueType::Array;
36 case ssq::Type::TABLE: return ValueType::Object;
37 default: return ValueType::Any;
38 }
39}
40
42std::string scalarToJson(HSQUIRRELVM vm, SQInteger index) {
43 switch (sq_gettype(vm, index)) {
44 case OT_INTEGER: {
45 SQInteger value = 0;
46 if (SQ_SUCCEEDED(sq_getinteger(vm, index, &value))) return std::to_string(value);
47 break;
48 }
49 case OT_FLOAT: {
50 SQFloat value = 0;
51 if (SQ_SUCCEEDED(sq_getfloat(vm, index, &value))) {
52 char buffer[64];
53 std::snprintf(buffer, sizeof(buffer), "%g", static_cast<double>(value));
54 return buffer;
55 }
56 break;
57 }
58 case OT_BOOL: {
59 SQBool value = SQFalse;
60 if (SQ_SUCCEEDED(sq_getbool(vm, index, &value))) return value ? "true" : "false";
61 break;
62 }
63 case OT_STRING: {
64 const SQChar* value = nullptr;
65 if (SQ_SUCCEEDED(sq_getstring(vm, index, &value)) && value) {
66 std::string out = "\"";
67 for (const SQChar* p = value; *p; ++p) {
68 if (*p == '"' || *p == '\\') out += '\\';
69 out += *p;
70 }
71 out += '"';
72 return out;
73 }
74 break;
75 }
76 default: break;
77 }
78 return {};
79}
80
81bool getAttrString(HSQUIRRELVM vm, SQInteger tableIdx, const char* key, std::string& out) {
82 const SQInteger top = sq_gettop(vm);
83 sq_push(vm, tableIdx);
84 sq_pushstring(vm, key, static_cast<SQInteger>(std::strlen(key)));
85 bool found = false;
86 if (SQ_SUCCEEDED(sq_get(vm, -2)) && sq_gettype(vm, -1) == OT_STRING) {
87 const SQChar* value = nullptr;
88 if (SQ_SUCCEEDED(sq_getstring(vm, -1, &value)) && value) {
89 out = value;
90 found = true;
91 }
92 }
93 sq_settop(vm, top);
94 return found;
95}
96
97bool getAttrBool(HSQUIRRELVM vm, SQInteger tableIdx, const char* key, bool& out) {
98 const SQInteger top = sq_gettop(vm);
99 sq_push(vm, tableIdx);
100 sq_pushstring(vm, key, static_cast<SQInteger>(std::strlen(key)));
101 bool found = false;
102 if (SQ_SUCCEEDED(sq_get(vm, -2)) && sq_gettype(vm, -1) == OT_BOOL) {
103 SQBool value = SQFalse;
104 if (SQ_SUCCEEDED(sq_getbool(vm, -1, &value))) {
105 out = value != SQFalse;
106 found = true;
107 }
108 }
109 sq_settop(vm, top);
110 return found;
111}
112
113bool getAttrInt(HSQUIRRELVM vm, SQInteger tableIdx, const char* key, int& out) {
114 const SQInteger top = sq_gettop(vm);
115 sq_push(vm, tableIdx);
116 sq_pushstring(vm, key, static_cast<SQInteger>(std::strlen(key)));
117 bool found = false;
118 if (SQ_SUCCEEDED(sq_get(vm, -2)) && sq_gettype(vm, -1) == OT_INTEGER) {
119 SQInteger value = 0;
120 if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &value))) {
121 out = static_cast<int>(value);
122 found = true;
123 }
124 }
125 sq_settop(vm, top);
126 return found;
127}
128
129bool getAttrNumber(HSQUIRRELVM vm, SQInteger tableIdx, const char* key, double& out) {
130 const SQInteger top = sq_gettop(vm);
131 sq_push(vm, tableIdx);
132 sq_pushstring(vm, key, static_cast<SQInteger>(std::strlen(key)));
133 bool found = false;
134 if (SQ_SUCCEEDED(sq_get(vm, -2)) && sq_gettype(vm, -1) == OT_INTEGER) {
135 SQInteger value = 0;
136 if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &value))) {
137 out = static_cast<double>(value);
138 found = true;
139 }
140 } else if (SQ_SUCCEEDED(sq_get(vm, -2)) && sq_gettype(vm, -1) == OT_FLOAT) {
141 SQFloat value = 0;
142 if (SQ_SUCCEEDED(sq_getfloat(vm, -1, &value))) {
143 out = static_cast<double>(value);
144 found = true;
145 }
146 }
147 sq_settop(vm, top);
148 return found;
149}
150
151void getAttrStringArray(HSQUIRRELVM vm, SQInteger tableIdx, const char* key, std::vector<std::string>& out) {
152 const SQInteger top = sq_gettop(vm);
153 sq_push(vm, tableIdx);
154 sq_pushstring(vm, key, static_cast<SQInteger>(std::strlen(key)));
155 if (SQ_SUCCEEDED(sq_get(vm, -2)) && sq_gettype(vm, -1) == OT_ARRAY) {
156 const SQInteger arrayIdx = sq_gettop(vm);
157 const SQInteger length = sq_getsize(vm, arrayIdx);
158 for (SQInteger i = 0; i < length; ++i) {
159 sq_pushinteger(vm, i);
160 if (SQ_SUCCEEDED(sq_get(vm, arrayIdx)) && sq_gettype(vm, -1) == OT_STRING) {
161 const SQChar* value = nullptr;
162 if (SQ_SUCCEEDED(sq_getstring(vm, -1, &value)) && value) out.push_back(value);
163 }
164 sq_pop(vm, 1);
165 }
166 }
167 sq_settop(vm, top);
168}
169
170void applyFieldAttributes(HSQUIRRELVM vm, SQInteger attrsIdx, FieldDefinition& field) {
171 std::string text;
172 if (getAttrString(vm, attrsIdx, "type", text))
173 if (auto type = valueTypeFromString(text)) field.type = *type;
174 if (getAttrString(vm, attrsIdx, "elementType", text))
175 if (auto type = valueTypeFromString(text)) field.elementType = *type;
176 if (getAttrString(vm, attrsIdx, "title", text)) field.title = text;
177 if (getAttrString(vm, attrsIdx, "description", text)) field.description = text;
178 if (getAttrString(vm, attrsIdx, "reference", text)) field.reference = text;
179 if (getAttrString(vm, attrsIdx, "defaultJson", text)) field.defaultJson = text;
180 double number = 0.0;
181 if (getAttrNumber(vm, attrsIdx, "minimum", number) || getAttrNumber(vm, attrsIdx, "min", number))
182 field.minimum = number;
183 if (getAttrNumber(vm, attrsIdx, "maximum", number) || getAttrNumber(vm, attrsIdx, "max", number))
184 field.maximum = number;
185 int integer = 0;
186 if (getAttrInt(vm, attrsIdx, "minLength", integer)) field.minLength = integer;
187 if (getAttrInt(vm, attrsIdx, "maxLength", integer)) field.maxLength = integer;
188 bool boolean = false;
189 if (getAttrBool(vm, attrsIdx, "required", boolean)) field.required = boolean;
190 getAttrStringArray(vm, attrsIdx, "values", field.enumValues);
191 if (field.enumValues.empty()) getAttrStringArray(vm, attrsIdx, "enum", field.enumValues);
192}
193
194} // namespace
195
196eve::Result<void> Schema::registerFromClass(const ssq::Object& classOrInstance) {
197 const ssq::Type type = classOrInstance.getType();
198 if (type != ssq::Type::CLASS && type != ssq::Type::INSTANCE) {
201 "registerFromClass expects a class or an instance of a class", "class"));
202 }
203 HSQUIRRELVM vm = classOrInstance.getHandle();
204 const SQInteger top = sq_gettop(vm);
205
206 sq_pushobject(vm, classOrInstance.getRaw());
207 if (type == ssq::Type::INSTANCE && SQ_FAILED(sq_getclass(vm, -1))) {
208 sq_settop(vm, top);
210 "could not resolve the instance's class", "class"));
211 }
212 const SQInteger clsIdx = sq_gettop(vm);
213
214 SchemaDefinition definition;
215 const SQInteger metaTop = sq_gettop(vm);
216 sq_push(vm, clsIdx);
217 sq_pushnull(vm); // null key selects class-level attributes
218 if (SQ_SUCCEEDED(sq_getattributes(vm, -2)) && sq_gettype(vm, -1) == OT_TABLE) {
219 const SQInteger attrsIdx = sq_gettop(vm);
220 std::string meta;
221 if (getAttrString(vm, attrsIdx, "id", meta)) definition.id = meta;
222 if (getAttrString(vm, attrsIdx, "title", meta)) definition.title = meta;
223 if (getAttrString(vm, attrsIdx, "description", meta)) definition.description = meta;
224 int version = 1;
225 if (getAttrInt(vm, attrsIdx, "version", version)) definition.version = version;
226 bool strict = false;
227 if (getAttrBool(vm, attrsIdx, "additionalProperties", strict)) definition.additionalProperties = strict;
228 }
229 sq_settop(vm, metaTop);
230
231 if (definition.id.empty()) {
232 sq_settop(vm, top);
235 "schema id is required (set the class-level attribute 'id')", "schema.id"));
236 }
237
238 std::unordered_set<std::string> names;
239 sq_push(vm, clsIdx);
240 sq_pushnull(vm);
241 while (SQ_SUCCEEDED(sq_next(vm, -2))) {
242 if (sq_gettype(vm, -2) != OT_STRING) {
243 sq_pop(vm, 2);
244 continue;
245 }
246 const SQChar* memberName = nullptr;
247 if (!SQ_SUCCEEDED(sq_getstring(vm, -2, &memberName)) || !memberName) {
248 sq_pop(vm, 2);
249 continue;
250 }
251 const SQObjectType memberType = sq_gettype(vm, -1);
252 if (memberType == OT_CLOSURE || memberType == OT_NATIVECLOSURE) {
253 sq_pop(vm, 2);
254 continue;
255 }
256 const std::string name(memberName);
257 if (!names.insert(name).second) {
258 sq_pop(vm, 2);
259 continue;
260 }
261
262 FieldDefinition field;
263 field.name = name;
264 field.type = typeFromSquirrel(static_cast<ssq::Type>(memberType));
265 field.defaultJson = scalarToJson(vm, -1);
266
267 const SQInteger attrsTop = sq_gettop(vm);
268 sq_push(vm, clsIdx);
269 sq_pushstring(vm, field.name.c_str(), static_cast<SQInteger>(field.name.size()));
270 if (SQ_SUCCEEDED(sq_getattributes(vm, -2)) && sq_gettype(vm, -1) == OT_TABLE) {
271 applyFieldAttributes(vm, sq_gettop(vm), field);
272 }
273 sq_settop(vm, attrsTop);
274
275 definition.fields.push_back(std::move(field));
276 sq_pop(vm, 2);
277 }
278 sq_settop(vm, top);
279
280 auto result = SchemaRegistry::registerSchema(definition);
281 if (!result.ok()) return eve::Result<void>::failure(result.status());
282 validationErrors_.clear();
284}
285
288 validationErrors_.clear();
289}
290
291bool Schema::has(const std::string& id) const { return SchemaRegistry::find(id) != nullptr; }
292bool Schema::hasVersion(const std::string& id, int version) const {
293 return SchemaRegistry::resolve(id, version) != nullptr;
294}
296int Schema::getSchemaVersionCount(const std::string& id) const {
297 return static_cast<int>(SchemaRegistry::versions(id).size());
298}
299int Schema::getSchemaVersionAt(const std::string& id, int index) const {
300 const auto values = SchemaRegistry::versions(id);
301 return index >= 0 && static_cast<size_t>(index) < values.size() ? values[static_cast<size_t>(index)] : 0;
302}
303
304std::string Schema::getSchemaId(int index) const {
305 const auto values = SchemaRegistry::ids();
306 return index >= 0 && static_cast<size_t>(index) < values.size() ? values[index] : std::string{};
307}
308
309int Schema::getSchemaVersion(const std::string& id) const {
310 const auto* value = SchemaRegistry::find(id);
311 return value ? value->version : 0;
312}
313
314std::string Schema::getSchemaTitle(const std::string& id) const {
315 const auto* value = SchemaRegistry::find(id);
316 return value ? value->title : std::string{};
317}
318
319std::string Schema::getSchemaDescription(const std::string& id) const {
320 const auto* value = SchemaRegistry::find(id);
321 return value ? value->description : std::string{};
322}
323
324bool Schema::getSchemaAdditionalProperties(const std::string& id) const {
325 const auto* value = SchemaRegistry::find(id);
326 return value && value->additionalProperties;
327}
328
329const FieldDefinition* Schema::field(const std::string& id, int index) const {
330 const auto* value = SchemaRegistry::find(id);
331 if (!value || index < 0 || static_cast<size_t>(index) >= value->fields.size()) return nullptr;
332 return &value->fields[static_cast<size_t>(index)];
333}
334
335int Schema::getFieldCount(const std::string& id) const {
336 const auto* value = SchemaRegistry::find(id);
337 return value ? static_cast<int>(value->fields.size()) : 0;
338}
339
340std::string Schema::getFieldName(const std::string& id, int index) const {
341 const auto* value = field(id, index);
342 return value ? value->name : std::string{};
343}
344std::string Schema::getFieldType(const std::string& id, int index) const {
345 const auto* value = field(id, index);
346 return value ? valueTypeName(value->type) : std::string{};
347}
348std::string Schema::getFieldElementType(const std::string& id, int index) const {
349 const auto* value = field(id, index);
350 return value ? valueTypeName(value->elementType) : std::string{};
351}
352bool Schema::getFieldRequired(const std::string& id, int index) const {
353 const auto* value = field(id, index);
354 return value && value->required;
355}
356std::string Schema::getFieldTitle(const std::string& id, int index) const {
357 const auto* value = field(id, index);
358 return value ? value->title : std::string{};
359}
360std::string Schema::getFieldDescription(const std::string& id, int index) const {
361 const auto* value = field(id, index);
362 return value ? value->description : std::string{};
363}
364std::string Schema::getFieldReference(const std::string& id, int index) const {
365 const auto* value = field(id, index);
366 return value ? value->reference : std::string{};
367}
368std::string Schema::getFieldDefaultJson(const std::string& id, int index) const {
369 const auto* value = field(id, index);
370 return value ? value->defaultJson : std::string{};
371}
372bool Schema::getFieldHasMinimum(const std::string& id, int index) const {
373 const auto* value = field(id, index);
374 return value && value->minimum.has_value();
375}
376float Schema::getFieldMinimum(const std::string& id, int index) const {
377 const auto* value = field(id, index);
378 return value && value->minimum ? static_cast<float>(*value->minimum) : 0.f;
379}
380bool Schema::getFieldHasMaximum(const std::string& id, int index) const {
381 const auto* value = field(id, index);
382 return value && value->maximum.has_value();
383}
384float Schema::getFieldMaximum(const std::string& id, int index) const {
385 const auto* value = field(id, index);
386 return value && value->maximum ? static_cast<float>(*value->maximum) : 0.f;
387}
388int Schema::getFieldEnumCount(const std::string& id, int index) const {
389 const auto* value = field(id, index);
390 return value ? static_cast<int>(value->enumValues.size()) : 0;
391}
392std::string Schema::getFieldEnumValue(const std::string& id, int fieldIndex, int valueIndex) const {
393 const auto* value = field(id, fieldIndex);
394 if (!value || valueIndex < 0 || static_cast<size_t>(valueIndex) >= value->enumValues.size()) return {};
395 return value->enumValues[static_cast<size_t>(valueIndex)];
396}
397
398eve::Result<void> Schema::validateJson(const std::string& schemaId, const std::string& json) {
399 validationErrors_ = SchemaRegistry::validate(schemaId, json);
400 if (validationErrors_.empty()) return eve::Result<void>::success(eve::Status::success(eve::StatusCode::Applied));
401 const auto& error = validationErrors_.front();
404}
405eve::Result<void> Schema::validateJsonVersioned(const std::string& schemaId, int version, const std::string& json) {
406 validationErrors_ = SchemaRegistry::validate(schemaId, version, json);
407 if (validationErrors_.empty()) return eve::Result<void>::success(eve::Status::success(eve::StatusCode::Applied));
408 const auto& error = validationErrors_.front();
411}
412int Schema::getValidationErrorCount() const { return static_cast<int>(validationErrors_.size()); }
413std::string Schema::getValidationErrorPath(int index) const {
414 return index >= 0 && static_cast<size_t>(index) < validationErrors_.size()
415 ? validationErrors_[static_cast<size_t>(index)].path
416 : std::string{};
417}
418std::string Schema::getValidationErrorCode(int index) const {
419 return index >= 0 && static_cast<size_t>(index) < validationErrors_.size()
420 ? validationErrors_[static_cast<size_t>(index)].code
421 : std::string{};
422}
424 return index >= 0 && static_cast<size_t>(index) < validationErrors_.size()
425 ? validationErrors_[static_cast<size_t>(index)].message
426 : std::string{};
427}
428
429void Schema::expose(ssq::Table& table) {
430 auto cls = table.addClass(name, Schema::create, false);
431 expose(cls);
432}
433
434void Schema::expose(ssq::Class& cls) {
435 const HSQUIRRELVM vm = cls.getHandle();
436 cls.addFunc("getName", &Schema::getName);
437 cls.addFunc("registerJson", [vm](Schema* value, const std::string& json) {
438 if (!value) {
441 "schema facade must not be null", "schema")));
442 }
443 return eve::script::projectResult(vm, value->registerJson(json));
444 });
445 cls.addFunc("registerFromClass", [vm](Schema* value, const ssq::Object& classOrInstance) {
446 if (!value) {
449 "schema facade must not be null", "schema")));
450 }
451 return eve::script::projectResult(vm, value->registerFromClass(classOrInstance));
452 });
453 cls.addFunc("clear", &Schema::clear);
454 cls.addFunc("has", &Schema::has);
455 cls.addFunc("hasVersion", &Schema::hasVersion);
456 cls.addFunc("getSchemaCount", &Schema::getSchemaCount);
457 cls.addFunc("getSchemaVersionCount", &Schema::getSchemaVersionCount);
458 cls.addFunc("getSchemaVersionAt", &Schema::getSchemaVersionAt);
459 cls.addFunc("getSchemaId", &Schema::getSchemaId);
460 cls.addFunc("getSchemaVersion", &Schema::getSchemaVersion);
461 cls.addFunc("getSchemaTitle", &Schema::getSchemaTitle);
462 cls.addFunc("getSchemaDescription", &Schema::getSchemaDescription);
463 cls.addFunc("getSchemaAdditionalProperties", &Schema::getSchemaAdditionalProperties);
464 cls.addFunc("getFieldCount", &Schema::getFieldCount);
465 cls.addFunc("getFieldName", &Schema::getFieldName);
466 cls.addFunc("getFieldType", &Schema::getFieldType);
467 cls.addFunc("getFieldElementType", &Schema::getFieldElementType);
468 cls.addFunc("getFieldRequired", &Schema::getFieldRequired);
469 cls.addFunc("getFieldTitle", &Schema::getFieldTitle);
470 cls.addFunc("getFieldDescription", &Schema::getFieldDescription);
471 cls.addFunc("getFieldReference", &Schema::getFieldReference);
472 cls.addFunc("getFieldDefaultJson", &Schema::getFieldDefaultJson);
473 cls.addFunc("getFieldHasMinimum", &Schema::getFieldHasMinimum);
474 cls.addFunc("getFieldMinimum", &Schema::getFieldMinimum);
475 cls.addFunc("getFieldHasMaximum", &Schema::getFieldHasMaximum);
476 cls.addFunc("getFieldMaximum", &Schema::getFieldMaximum);
477 cls.addFunc("getFieldEnumCount", &Schema::getFieldEnumCount);
478 cls.addFunc("getFieldEnumValue", &Schema::getFieldEnumValue);
479 cls.addFunc("validateJson", [vm](Schema* value, const std::string& id, const std::string& json) {
480 if (!value) {
483 "schema facade must not be null", "schema")));
484 }
485 return eve::script::projectResult(vm, value->validateJson(id, json));
486 });
487 cls.addFunc("validateJsonVersioned",
488 [vm](Schema* value, const std::string& id, int version, const std::string& json) {
489 if (!value) {
492 eve::DiagnosticCode::InvalidArgument, "schema facade must not be null", "schema")));
493 }
494 return eve::script::projectResult(vm, value->validateJsonVersioned(id, version, json));
495 });
496 cls.addFunc("getValidationErrorCount", &Schema::getValidationErrorCount);
497 cls.addFunc("getValidationErrorPath", &Schema::getValidationErrorPath);
498 cls.addFunc("getValidationErrorCode", &Schema::getValidationErrorCode);
499 cls.addFunc("getValidationErrorMessage", &Schema::getValidationErrorMessage);
500}
501
502} // namespace eve::schema
double value
SQInteger top
bool strict
float length
Definition CaveMesh.cpp:94
struct SQVM * HSQUIRRELVM
glm::vec4 p[6]
HSQUIRRELVM vm
Definition ECS.cpp:20
HSQOBJECT cls
Definition ECS.cpp:21
std::map< std::string, Var > values
std::string message
DiagnosticCode code
std::uint32_t key
std::string text
std::string name
#define Module_IMPL(ModuleName, newExpr)
Definition Module.h:26
std::unique_ptr< gpgpu::GpuBuffer > buffer
Definition OnnxGpgpu.cpp:26
std::string error
Definition Package.cpp:60
std::string path
Definition PlayHost.cpp:110
double number
bool found
bool boolean
The single Squirrel projection for common Result, Status and Value.
uint32_t index
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
virtual std::string getName() const =0
Returns the name.
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
static Status success(StatusCode code=StatusCode::Ok)
Construct a successful status with an explicit non-error outcome.
Definition Status.h:81
Type type() const
Return the active value type.
static const SchemaDefinition * find(const std::string &id)
Finds the highest registered version for an id, or nullptr.
static std::vector< int > versions(const std::string &schemaId)
Returns all registered versions for an id in ascending order.
static void clear()
Clears all registered schemas.
static eve::Result< SchemaRegistrationStatus > registerSchema(const SchemaDefinition &definition)
Registers or replaces the exact (id, version) entry.
static std::vector< ValidationError > validate(const std::string &schemaId, const std::string &json)
Validates JSON text against the highest registered schema version.
static const SchemaDefinition * resolve(const std::string &schemaId, int schemaVersion)
Resolves one exact (schemaId, schemaVersion) pair, or nullptr.
static int count()
Returns the number of registered schema ids.
static std::vector< std::string > ids()
Returns registered schema ids, unique and in deterministic lexical order.
static eve::Result< SchemaRegistrationStatus > registerFromJson(const std::string &json)
Parses and registers or replaces one schema definition from JSON.
Script-facing facade for runtime schema registration and validation.
Definition Schema.h:16
std::string getFieldDefaultJson(const std::string &id, int index) const
Returns the optional default value as JSON text.
Definition Schema.cpp:368
int getFieldEnumCount(const std::string &id, int index) const
Returns the number of allowed string values.
Definition Schema.cpp:388
float getFieldMinimum(const std::string &id, int index) const
Returns a numeric minimum, or zero when absent.
Definition Schema.cpp:376
std::string getFieldElementType(const std::string &id, int index) const
Returns the element type name for an array field.
Definition Schema.cpp:348
std::string getSchemaId(int index) const
Returns the id at a deterministic enumeration index.
Definition Schema.cpp:304
std::string getValidationErrorPath(int index) const
Returns a failure's JSON Pointer-like path.
Definition Schema.cpp:413
std::string getFieldEnumValue(const std::string &id, int fieldIndex, int valueIndex) const
Returns one allowed string value.
Definition Schema.cpp:392
std::string getFieldReference(const std::string &id, int index) const
Returns the referenced definition/schema category.
Definition Schema.cpp:364
float getFieldMaximum(const std::string &id, int index) const
Returns a numeric maximum, or zero when absent.
Definition Schema.cpp:384
std::string getFieldName(const std::string &id, int index) const
Returns a field's stable name.
Definition Schema.cpp:340
std::string getFieldTitle(const std::string &id, int index) const
Returns the short editor-facing field title.
Definition Schema.cpp:356
bool getSchemaAdditionalProperties(const std::string &id) const
Returns whether undeclared object members are accepted.
Definition Schema.cpp:324
void clear()
Removes all registered schemas and cached validation errors.
Definition Schema.cpp:286
int getSchemaVersionCount(const std::string &id) const
Returns the number of registered versions for one schema id.
Definition Schema.cpp:296
eve::Result< void > registerJson(const std::string &json)
Registers or replaces a schema encoded as JSON.
Definition Schema.cpp:19
bool has(const std::string &id) const
Returns whether a stable schema id is registered.
Definition Schema.cpp:291
int getValidationErrorCount() const
Returns cached validation failure count.
Definition Schema.cpp:412
int getSchemaCount() const
Returns the number of registered schema ids.
Definition Schema.cpp:295
int getSchemaVersion(const std::string &id) const
Returns the highest registered schema version, or zero when absent.
Definition Schema.cpp:309
bool getFieldHasMinimum(const std::string &id, int index) const
Returns whether a numeric minimum constraint is present.
Definition Schema.cpp:372
std::string getFieldType(const std::string &id, int index) const
Returns a field's stable value type name.
Definition Schema.cpp:344
bool getFieldRequired(const std::string &id, int index) const
Returns whether a field must be present.
Definition Schema.cpp:352
std::string getSchemaDescription(const std::string &id) const
Returns a schema description, or an empty string when absent.
Definition Schema.cpp:319
std::string getFieldDescription(const std::string &id, int index) const
Returns the editor-facing field description.
Definition Schema.cpp:360
std::string getValidationErrorCode(int index) const
Returns a stable machine-readable failure code.
Definition Schema.cpp:418
bool hasVersion(const std::string &id, int version) const
Returns whether an exact schema id and version is registered.
Definition Schema.cpp:292
std::string getValidationErrorMessage(int index) const
Returns a human-readable failure description.
Definition Schema.cpp:423
eve::Result< void > validateJson(const std::string &schemaId, const std::string &json)
Validates JSON against the highest registered version and caches failures.
Definition Schema.cpp:398
std::string getSchemaTitle(const std::string &id) const
Returns a schema title, or an empty string when absent.
Definition Schema.cpp:314
eve::Result< void > validateJsonVersioned(const std::string &schemaId, int version, const std::string &json)
Validates JSON against one exact schema version.
Definition Schema.cpp:405
Schema()
Creates an empty facade over the process schema registry.
int getSchemaVersionAt(const std::string &id, int index) const
Returns a schema version at an ascending enumeration index.
Definition Schema.cpp:299
bool getFieldHasMaximum(const std::string &id, int index) const
Returns whether a numeric maximum constraint is present.
Definition Schema.cpp:380
int getFieldCount(const std::string &id) const
Returns the number of fields in a schema.
Definition Schema.cpp:335
eve::Result< void > registerFromClass(const ssq::Object &classOrInstance)
Registers a schema reflected from a script class or instance.
Definition Schema.cpp:196
const EditorValue * field(const EditorValue &value, const char *name)
std::optional< ValueType > valueTypeFromString(const std::string &name)
Converts a stable schema type name to its enum value.
const char * valueTypeName(ValueType type)
Returns the stable lowercase name of a schema value type.
ValueType
JSON-compatible value kinds understood by a schema field.
Definition SchemaTypes.h:16
ssq::Table projectResult(HSQUIRRELVM vm, Result< void > &&result)
Consume and project a void native Result using the common schema.
int64_t integer(const RuntimeTensor &v, size_t i=0)
Integer.
Metadata and validation constraints for one object member.
Definition SchemaTypes.h:77
Versioned runtime schema for a JSON object.
Definition SchemaTypes.h:93