Test case
53 generated files · +6,530 −0test/inputs/schema/dart-runtime-type-names.schema
Aschema-cjsondefault / TopLevel.c+393 −0
| @@ -0,0 +1,393 @@ | ||
| 1 | +/** | |
| 2 | + * TopLevel.c | |
| 3 | + * This file has been autogenerated using quicktype https://github.com/quicktype/quicktype - DO NOT EDIT | |
| 4 | + */ | |
| 5 | + | |
| 6 | +#include "TopLevel.h" | |
| 7 | + | |
| 8 | +enum Status cJSON_GetStatusValue(const cJSON * j) { | |
| 9 | + enum Status x = 0; | |
| 10 | + if (NULL != j) { | |
| 11 | + if (!strcmp(cJSON_GetStringValue(j), "ready")) x = STATUS_READY; | |
| 12 | + else if (!strcmp(cJSON_GetStringValue(j), "done")) x = STATUS_DONE; | |
| 13 | + } | |
| 14 | + return x; | |
| 15 | +} | |
| 16 | + | |
| 17 | +cJSON * cJSON_CreateStatus(const enum Status x) { | |
| 18 | + cJSON * j = NULL; | |
| 19 | + switch (x) { | |
| 20 | + case STATUS_READY: j = cJSON_CreateString("ready"); break; | |
| 21 | + case STATUS_DONE: j = cJSON_CreateString("done"); break; | |
| 22 | + } | |
| 23 | + return j; | |
| 24 | +} | |
| 25 | + | |
| 26 | +struct DateTime * cJSON_ParseDateTime(const char * s) { | |
| 27 | + struct DateTime * x = NULL; | |
| 28 | + if (NULL != s) { | |
| 29 | + cJSON * j = cJSON_Parse(s); | |
| 30 | + if (NULL != j) { | |
| 31 | + x = cJSON_GetDateTimeValue(j); | |
| 32 | + cJSON_Delete(j); | |
| 33 | + } | |
| 34 | + } | |
| 35 | + return x; | |
| 36 | +} | |
| 37 | + | |
| 38 | +struct DateTime * cJSON_GetDateTimeValue(const cJSON * j) { | |
| 39 | + struct DateTime * x = NULL; | |
| 40 | + if (NULL != j) { | |
| 41 | + if (NULL != (x = cJSON_malloc(sizeof(struct DateTime)))) { | |
| 42 | + memset(x, 0, sizeof(struct DateTime)); | |
| 43 | + if (!cJSON_HasObjectItem(j, "value")) { cJSON_DeleteDateTime(x); return NULL; } | |
| 44 | + if (cJSON_HasObjectItem(j, "value")) { | |
| 45 | + if (!quicktype_cJSON_IsInteger(cJSON_GetObjectItemCaseSensitive(j, "value"))) { cJSON_DeleteDateTime(x); return NULL; } | |
| 46 | + x->value = cJSON_GetNumberValue(cJSON_GetObjectItemCaseSensitive(j, "value")); | |
| 47 | + } | |
| 48 | + } | |
| 49 | + } | |
| 50 | + return x; | |
| 51 | +} | |
| 52 | + | |
| 53 | +cJSON * cJSON_CreateDateTime(const struct DateTime * x) { | |
| 54 | + cJSON * j = NULL; | |
| 55 | + if (NULL != x) { | |
| 56 | + if (NULL != (j = cJSON_CreateObject())) { | |
| 57 | + cJSON_AddNumberToObject(j, "value", x->value); | |
| 58 | + } | |
| 59 | + } | |
| 60 | + return j; | |
| 61 | +} | |
| 62 | + | |
| 63 | +char * cJSON_PrintDateTime(const struct DateTime * x) { | |
| 64 | + char * s = NULL; | |
| 65 | + if (NULL != x) { | |
| 66 | + cJSON * j = cJSON_CreateDateTime(x); | |
| 67 | + if (NULL != j) { | |
| 68 | + s = cJSON_Print(j); | |
| 69 | + cJSON_Delete(j); | |
| 70 | + } | |
| 71 | + } | |
| 72 | + return s; | |
| 73 | +} | |
| 74 | + | |
| 75 | +void cJSON_DeleteDateTime(struct DateTime * x) { | |
| 76 | + if (NULL != x) { | |
| 77 | + cJSON_free(x); | |
| 78 | + } | |
| 79 | +} | |
| 80 | + | |
| 81 | +struct EnumValues * cJSON_ParseEnumValues(const char * s) { | |
| 82 | + struct EnumValues * x = NULL; | |
| 83 | + if (NULL != s) { | |
| 84 | + cJSON * j = cJSON_Parse(s); | |
| 85 | + if (NULL != j) { | |
| 86 | + x = cJSON_GetEnumValuesValue(j); | |
| 87 | + cJSON_Delete(j); | |
| 88 | + } | |
| 89 | + } | |
| 90 | + return x; | |
| 91 | +} | |
| 92 | + | |
| 93 | +struct EnumValues * cJSON_GetEnumValuesValue(const cJSON * j) { | |
| 94 | + struct EnumValues * x = NULL; | |
| 95 | + if (NULL != j) { | |
| 96 | + if (NULL != (x = cJSON_malloc(sizeof(struct EnumValues)))) { | |
| 97 | + memset(x, 0, sizeof(struct EnumValues)); | |
| 98 | + if (!cJSON_HasObjectItem(j, "label")) { cJSON_DeleteEnumValues(x); return NULL; } | |
| 99 | + if (cJSON_HasObjectItem(j, "label")) { | |
| 100 | + if (!cJSON_IsString(cJSON_GetObjectItemCaseSensitive(j, "label"))) { cJSON_DeleteEnumValues(x); return NULL; } | |
| 101 | + x->label = strdup(cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(j, "label"))); | |
| 102 | + } | |
| 103 | + else { | |
| 104 | + if (NULL != (x->label = cJSON_malloc(sizeof(char)))) { | |
| 105 | + x->label[0] = '\0'; | |
| 106 | + } | |
| 107 | + } | |
| 108 | + } | |
| 109 | + } | |
| 110 | + return x; | |
| 111 | +} | |
| 112 | + | |
| 113 | +cJSON * cJSON_CreateEnumValues(const struct EnumValues * x) { | |
| 114 | + cJSON * j = NULL; | |
| 115 | + if (NULL != x) { | |
| 116 | + if (NULL != (j = cJSON_CreateObject())) { | |
| 117 | + if (NULL != x->label) { | |
| 118 | + cJSON_AddStringToObject(j, "label", x->label); | |
| 119 | + } | |
| 120 | + else { | |
| 121 | + cJSON_AddStringToObject(j, "label", ""); | |
| 122 | + } | |
| 123 | + } | |
| 124 | + } | |
| 125 | + return j; | |
| 126 | +} | |
| 127 | + | |
| 128 | +char * cJSON_PrintEnumValues(const struct EnumValues * x) { | |
| 129 | + char * s = NULL; | |
| 130 | + if (NULL != x) { | |
| 131 | + cJSON * j = cJSON_CreateEnumValues(x); | |
| 132 | + if (NULL != j) { | |
| 133 | + s = cJSON_Print(j); | |
| 134 | + cJSON_Delete(j); | |
| 135 | + } | |
| 136 | + } | |
| 137 | + return s; | |
| 138 | +} | |
| 139 | + | |
| 140 | +void cJSON_DeleteEnumValues(struct EnumValues * x) { | |
| 141 | + if (NULL != x) { | |
| 142 | + if (NULL != x->label) { | |
| 143 | + cJSON_free(x->label); | |
| 144 | + } | |
| 145 | + cJSON_free(x); | |
| 146 | + } | |
| 147 | +} | |
| 148 | + | |
| 149 | +struct FormatException * cJSON_ParseFormatException(const char * s) { | |
| 150 | + struct FormatException * x = NULL; | |
| 151 | + if (NULL != s) { | |
| 152 | + cJSON * j = cJSON_Parse(s); | |
| 153 | + if (NULL != j) { | |
| 154 | + x = cJSON_GetFormatExceptionValue(j); | |
| 155 | + cJSON_Delete(j); | |
| 156 | + } | |
| 157 | + } | |
| 158 | + return x; | |
| 159 | +} | |
| 160 | + | |
| 161 | +struct FormatException * cJSON_GetFormatExceptionValue(const cJSON * j) { | |
| 162 | + struct FormatException * x = NULL; | |
| 163 | + if (NULL != j) { | |
| 164 | + if (NULL != (x = cJSON_malloc(sizeof(struct FormatException)))) { | |
| 165 | + memset(x, 0, sizeof(struct FormatException)); | |
| 166 | + if (!cJSON_HasObjectItem(j, "count")) { cJSON_DeleteFormatException(x); return NULL; } | |
| 167 | + if (cJSON_HasObjectItem(j, "count")) { | |
| 168 | + if (!quicktype_cJSON_IsInteger(cJSON_GetObjectItemCaseSensitive(j, "count"))) { cJSON_DeleteFormatException(x); return NULL; } | |
| 169 | + x->count = cJSON_GetNumberValue(cJSON_GetObjectItemCaseSensitive(j, "count")); | |
| 170 | + } | |
| 171 | + } | |
| 172 | + } | |
| 173 | + return x; | |
| 174 | +} | |
| 175 | + | |
| 176 | +cJSON * cJSON_CreateFormatException(const struct FormatException * x) { | |
| 177 | + cJSON * j = NULL; | |
| 178 | + if (NULL != x) { | |
| 179 | + if (NULL != (j = cJSON_CreateObject())) { | |
| 180 | + cJSON_AddNumberToObject(j, "count", x->count); | |
| 181 | + } | |
| 182 | + } | |
| 183 | + return j; | |
| 184 | +} | |
| 185 | + | |
| 186 | +char * cJSON_PrintFormatException(const struct FormatException * x) { | |
| 187 | + char * s = NULL; | |
| 188 | + if (NULL != x) { | |
| 189 | + cJSON * j = cJSON_CreateFormatException(x); | |
| 190 | + if (NULL != j) { | |
| 191 | + s = cJSON_Print(j); | |
| 192 | + cJSON_Delete(j); | |
| 193 | + } | |
| 194 | + } | |
| 195 | + return s; | |
| 196 | +} | |
| 197 | + | |
| 198 | +void cJSON_DeleteFormatException(struct FormatException * x) { | |
| 199 | + if (NULL != x) { | |
| 200 | + cJSON_free(x); | |
| 201 | + } | |
| 202 | +} | |
| 203 | + | |
| 204 | +struct RegExp * cJSON_ParseRegExp(const char * s) { | |
| 205 | + struct RegExp * x = NULL; | |
| 206 | + if (NULL != s) { | |
| 207 | + cJSON * j = cJSON_Parse(s); | |
| 208 | + if (NULL != j) { | |
| 209 | + x = cJSON_GetRegExpValue(j); | |
| 210 | + cJSON_Delete(j); | |
| 211 | + } | |
| 212 | + } | |
| 213 | + return x; | |
| 214 | +} | |
| 215 | + | |
| 216 | +struct RegExp * cJSON_GetRegExpValue(const cJSON * j) { | |
| 217 | + struct RegExp * x = NULL; | |
| 218 | + if (NULL != j) { | |
| 219 | + if (NULL != (x = cJSON_malloc(sizeof(struct RegExp)))) { | |
| 220 | + memset(x, 0, sizeof(struct RegExp)); | |
| 221 | + if (!cJSON_HasObjectItem(j, "active")) { cJSON_DeleteRegExp(x); return NULL; } | |
| 222 | + if (cJSON_HasObjectItem(j, "active")) { | |
| 223 | + if (!cJSON_IsBool(cJSON_GetObjectItemCaseSensitive(j, "active"))) { cJSON_DeleteRegExp(x); return NULL; } | |
| 224 | + x->active = cJSON_IsTrue(cJSON_GetObjectItemCaseSensitive(j, "active")); | |
| 225 | + } | |
| 226 | + } | |
| 227 | + } | |
| 228 | + return x; | |
| 229 | +} | |
| 230 | + | |
| 231 | +cJSON * cJSON_CreateRegExp(const struct RegExp * x) { | |
| 232 | + cJSON * j = NULL; | |
| 233 | + if (NULL != x) { | |
| 234 | + if (NULL != (j = cJSON_CreateObject())) { | |
| 235 | + cJSON_AddBoolToObject(j, "active", x->active); | |
| 236 | + } | |
| 237 | + } | |
| 238 | + return j; | |
| 239 | +} | |
| 240 | + | |
| 241 | +char * cJSON_PrintRegExp(const struct RegExp * x) { | |
| 242 | + char * s = NULL; | |
| 243 | + if (NULL != x) { | |
| 244 | + cJSON * j = cJSON_CreateRegExp(x); | |
| 245 | + if (NULL != j) { | |
| 246 | + s = cJSON_Print(j); | |
| 247 | + cJSON_Delete(j); | |
| 248 | + } | |
| 249 | + } | |
| 250 | + return s; | |
| 251 | +} | |
| 252 | + | |
| 253 | +void cJSON_DeleteRegExp(struct RegExp * x) { | |
| 254 | + if (NULL != x) { | |
| 255 | + cJSON_free(x); | |
| 256 | + } | |
| 257 | +} | |
| 258 | + | |
| 259 | +struct TopLevel * cJSON_ParseTopLevel(const char * s) { | |
| 260 | + struct TopLevel * x = NULL; | |
| 261 | + if (NULL != s) { | |
| 262 | + cJSON * j = cJSON_Parse(s); | |
| 263 | + if (NULL != j) { | |
| 264 | + x = cJSON_GetTopLevelValue(j); | |
| 265 | + cJSON_Delete(j); | |
| 266 | + } | |
| 267 | + } | |
| 268 | + return x; | |
| 269 | +} | |
| 270 | + | |
| 271 | +struct TopLevel * cJSON_GetTopLevelValue(const cJSON * j) { | |
| 272 | + struct TopLevel * x = NULL; | |
| 273 | + if (NULL != j) { | |
| 274 | + if (NULL != (x = cJSON_malloc(sizeof(struct TopLevel)))) { | |
| 275 | + memset(x, 0, sizeof(struct TopLevel)); | |
| 276 | + if (!cJSON_HasObjectItem(j, "code")) { cJSON_DeleteTopLevel(x); return NULL; } | |
| 277 | + if (cJSON_HasObjectItem(j, "code")) { | |
| 278 | + if (!cJSON_IsString(cJSON_GetObjectItemCaseSensitive(j, "code"))) { cJSON_DeleteTopLevel(x); return NULL; } | |
| 279 | + regex_t regex; regcomp(®ex, "^[a-z]+$", REG_EXTENDED); if (regexec(®ex, cJSON_GetObjectItemCaseSensitive(j, "code")->valuestring, 0, NULL, 0)) { regfree(®ex); cJSON_DeleteTopLevel(x); return NULL; } regfree(®ex); | |
| 280 | + if (strlen(cJSON_GetObjectItemCaseSensitive(j, "code")->valuestring) < 1) { cJSON_DeleteTopLevel(x); return NULL; } | |
| 281 | + x->code = strdup(cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(j, "code"))); | |
| 282 | + } | |
| 283 | + else { | |
| 284 | + if (NULL != (x->code = cJSON_malloc(sizeof(char)))) { | |
| 285 | + x->code[0] = '\0'; | |
| 286 | + } | |
| 287 | + } | |
| 288 | + if (!cJSON_HasObjectItem(j, "dateTime")) { cJSON_DeleteTopLevel(x); return NULL; } | |
| 289 | + if (cJSON_HasObjectItem(j, "dateTime")) { | |
| 290 | + if (!cJSON_IsObject(cJSON_GetObjectItemCaseSensitive(j, "dateTime"))) { cJSON_DeleteTopLevel(x); return NULL; } | |
| 291 | + x->date_time = cJSON_GetDateTimeValue(cJSON_GetObjectItemCaseSensitive(j, "dateTime")); | |
| 292 | + if (NULL == x->date_time) { cJSON_DeleteTopLevel(x); return NULL; } | |
| 293 | + } | |
| 294 | + if (!cJSON_HasObjectItem(j, "enumValues")) { cJSON_DeleteTopLevel(x); return NULL; } | |
| 295 | + if (cJSON_HasObjectItem(j, "enumValues")) { | |
| 296 | + if (!cJSON_IsObject(cJSON_GetObjectItemCaseSensitive(j, "enumValues"))) { cJSON_DeleteTopLevel(x); return NULL; } | |
| 297 | + x->enum_values = cJSON_GetEnumValuesValue(cJSON_GetObjectItemCaseSensitive(j, "enumValues")); | |
| 298 | + if (NULL == x->enum_values) { cJSON_DeleteTopLevel(x); return NULL; } | |
| 299 | + } | |
| 300 | + if (!cJSON_HasObjectItem(j, "formatException")) { cJSON_DeleteTopLevel(x); return NULL; } | |
| 301 | + if (cJSON_HasObjectItem(j, "formatException")) { | |
| 302 | + if (!cJSON_IsObject(cJSON_GetObjectItemCaseSensitive(j, "formatException"))) { cJSON_DeleteTopLevel(x); return NULL; } | |
| 303 | + x->format_exception = cJSON_GetFormatExceptionValue(cJSON_GetObjectItemCaseSensitive(j, "formatException")); | |
| 304 | + if (NULL == x->format_exception) { cJSON_DeleteTopLevel(x); return NULL; } | |
| 305 | + } | |
| 306 | + if (!cJSON_HasObjectItem(j, "regExp")) { cJSON_DeleteTopLevel(x); return NULL; } | |
| 307 | + if (cJSON_HasObjectItem(j, "regExp")) { | |
| 308 | + if (!cJSON_IsObject(cJSON_GetObjectItemCaseSensitive(j, "regExp"))) { cJSON_DeleteTopLevel(x); return NULL; } | |
| 309 | + x->reg_exp = cJSON_GetRegExpValue(cJSON_GetObjectItemCaseSensitive(j, "regExp")); | |
| 310 | + if (NULL == x->reg_exp) { cJSON_DeleteTopLevel(x); return NULL; } | |
| 311 | + } | |
| 312 | + if (!cJSON_HasObjectItem(j, "status")) { cJSON_DeleteTopLevel(x); return NULL; } | |
| 313 | + if (cJSON_HasObjectItem(j, "status")) { | |
| 314 | + if (!cJSON_IsString(cJSON_GetObjectItemCaseSensitive(j, "status"))) { cJSON_DeleteTopLevel(x); return NULL; } | |
| 315 | + if (!cJSON_IsString(cJSON_GetObjectItemCaseSensitive(j, "status")) || 0 == cJSON_GetStatusValue(cJSON_GetObjectItemCaseSensitive(j, "status"))) { cJSON_DeleteTopLevel(x); return NULL; } | |
| 316 | + x->status = cJSON_GetStatusValue(cJSON_GetObjectItemCaseSensitive(j, "status")); | |
| 317 | + } | |
| 318 | + if (!cJSON_HasObjectItem(j, "timestamp")) { cJSON_DeleteTopLevel(x); return NULL; } | |
| 319 | + if (cJSON_HasObjectItem(j, "timestamp")) { | |
| 320 | + if (!cJSON_IsString(cJSON_GetObjectItemCaseSensitive(j, "timestamp"))) { cJSON_DeleteTopLevel(x); return NULL; } | |
| 321 | + x->timestamp = strdup(cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(j, "timestamp"))); | |
| 322 | + } | |
| 323 | + else { | |
| 324 | + if (NULL != (x->timestamp = cJSON_malloc(sizeof(char)))) { | |
| 325 | + x->timestamp[0] = '\0'; | |
| 326 | + } | |
| 327 | + } | |
| 328 | + } | |
| 329 | + } | |
| 330 | + return x; | |
| 331 | +} | |
| 332 | + | |
| 333 | +cJSON * cJSON_CreateTopLevel(const struct TopLevel * x) { | |
| 334 | + cJSON * j = NULL; | |
| 335 | + if (NULL != x) { | |
| 336 | + if (NULL != (j = cJSON_CreateObject())) { | |
| 337 | + if (NULL != x->code) { | |
| 338 | + cJSON_AddStringToObject(j, "code", x->code); | |
| 339 | + } | |
| 340 | + else { | |
| 341 | + cJSON_AddStringToObject(j, "code", ""); | |
| 342 | + } | |
| 343 | + cJSON_AddItemToObject(j, "dateTime", cJSON_CreateDateTime(x->date_time)); | |
| 344 | + cJSON_AddItemToObject(j, "enumValues", cJSON_CreateEnumValues(x->enum_values)); | |
| 345 | + cJSON_AddItemToObject(j, "formatException", cJSON_CreateFormatException(x->format_exception)); | |
| 346 | + cJSON_AddItemToObject(j, "regExp", cJSON_CreateRegExp(x->reg_exp)); | |
| 347 | + cJSON_AddItemToObject(j, "status", cJSON_CreateStatus(x->status)); | |
| 348 | + if (NULL != x->timestamp) { | |
| 349 | + cJSON_AddStringToObject(j, "timestamp", x->timestamp); | |
| 350 | + } | |
| 351 | + else { | |
| 352 | + cJSON_AddStringToObject(j, "timestamp", ""); | |
| 353 | + } | |
| 354 | + } | |
| 355 | + } | |
| 356 | + return j; | |
| 357 | +} | |
| 358 | + | |
| 359 | +char * cJSON_PrintTopLevel(const struct TopLevel * x) { | |
| 360 | + char * s = NULL; | |
| 361 | + if (NULL != x) { | |
| 362 | + cJSON * j = cJSON_CreateTopLevel(x); | |
| 363 | + if (NULL != j) { | |
| 364 | + s = cJSON_Print(j); | |
| 365 | + cJSON_Delete(j); | |
| 366 | + } | |
| 367 | + } | |
| 368 | + return s; | |
| 369 | +} | |
| 370 | + | |
| 371 | +void cJSON_DeleteTopLevel(struct TopLevel * x) { | |
| 372 | + if (NULL != x) { | |
| 373 | + if (NULL != x->code) { | |
| 374 | + cJSON_free(x->code); | |
| 375 | + } | |
| 376 | + if (NULL != x->date_time) { | |
| 377 | + cJSON_DeleteDateTime(x->date_time); | |
| 378 | + } | |
| 379 | + if (NULL != x->enum_values) { | |
| 380 | + cJSON_DeleteEnumValues(x->enum_values); | |
| 381 | + } | |
| 382 | + if (NULL != x->format_exception) { | |
| 383 | + cJSON_DeleteFormatException(x->format_exception); | |
| 384 | + } | |
| 385 | + if (NULL != x->reg_exp) { | |
| 386 | + cJSON_DeleteRegExp(x->reg_exp); | |
| 387 | + } | |
| 388 | + if (NULL != x->timestamp) { | |
| 389 | + cJSON_free(x->timestamp); | |
| 390 | + } | |
| 391 | + cJSON_free(x); | |
| 392 | + } | |
| 393 | +} |
Aschema-cjsondefault / TopLevel.h+109 −0
| @@ -0,0 +1,109 @@ | ||
| 1 | +/** | |
| 2 | + * TopLevel.h | |
| 3 | + * This file has been autogenerated using quicktype https://github.com/quicktype/quicktype - DO NOT EDIT | |
| 4 | + * This file depends of https://github.com/DaveGamble/cJSON, https://github.com/joelguittet/c-list and https://github.com/joelguittet/c-hashtable | |
| 5 | + * To parse json data from json string use the following: struct <type> * data = cJSON_Parse<type>(<string>); | |
| 6 | + * To get json data from cJSON object use the following: struct <type> * data = cJSON_Get<type>Value(<cjson>); | |
| 7 | + * To get cJSON object from json data use the following: cJSON * cjson = cJSON_Create<type>(<data>); | |
| 8 | + * To print json string from json data use the following: char * string = cJSON_Print<type>(<data>); | |
| 9 | + * To delete json data use the following: cJSON_Delete<type>(<data>); | |
| 10 | + */ | |
| 11 | + | |
| 12 | +#ifndef __TOPLEVEL_H__ | |
| 13 | +#define __TOPLEVEL_H__ | |
| 14 | + | |
| 15 | +#ifdef __cplusplus | |
| 16 | +extern "C" { | |
| 17 | +#endif | |
| 18 | + | |
| 19 | +#include <stdint.h> | |
| 20 | +#include <stdbool.h> | |
| 21 | +#include <stdlib.h> | |
| 22 | +#include <string.h> | |
| 23 | +#include <regex.h> | |
| 24 | +#include <cJSON.h> | |
| 25 | +#include <hashtable.h> | |
| 26 | +#include <list.h> | |
| 27 | + | |
| 28 | +#define quicktype_cJSON_Duplicate(j) cJSON_Duplicate(j, true) | |
| 29 | +#define cJSON_Integer (1 << 18) | |
| 30 | +#define quicktype_cJSON_IsInteger(j) (cJSON_IsNumber(j) && (j)->valuedouble == (int64_t)(j)->valuedouble) | |
| 31 | +#ifndef cJSON_Bool | |
| 32 | +#define cJSON_Bool (cJSON_True | cJSON_False) | |
| 33 | +#endif | |
| 34 | +#ifndef cJSON_Map | |
| 35 | +#define cJSON_Map (1 << 16) | |
| 36 | +#endif | |
| 37 | +#ifndef cJSON_Enum | |
| 38 | +#define cJSON_Enum (1 << 17) | |
| 39 | +#endif | |
| 40 | + | |
| 41 | +struct DateTime { | |
| 42 | + int64_t value; | |
| 43 | +}; | |
| 44 | + | |
| 45 | +struct EnumValues { | |
| 46 | + char * label; | |
| 47 | +}; | |
| 48 | + | |
| 49 | +struct FormatException { | |
| 50 | + int64_t count; | |
| 51 | +}; | |
| 52 | + | |
| 53 | +struct RegExp { | |
| 54 | + bool active; | |
| 55 | +}; | |
| 56 | + | |
| 57 | +enum Status { | |
| 58 | + STATUS_READY = 1, | |
| 59 | + STATUS_DONE, | |
| 60 | +}; | |
| 61 | + | |
| 62 | +struct TopLevel { | |
| 63 | + char * code; | |
| 64 | + struct DateTime * date_time; | |
| 65 | + struct EnumValues * enum_values; | |
| 66 | + struct FormatException * format_exception; | |
| 67 | + struct RegExp * reg_exp; | |
| 68 | + enum Status status; | |
| 69 | + char * timestamp; | |
| 70 | +}; | |
| 71 | + | |
| 72 | +enum Status cJSON_GetStatusValue(const cJSON * j); | |
| 73 | +cJSON * cJSON_CreateStatus(const enum Status x); | |
| 74 | + | |
| 75 | +struct DateTime * cJSON_ParseDateTime(const char * s); | |
| 76 | +struct DateTime * cJSON_GetDateTimeValue(const cJSON * j); | |
| 77 | +cJSON * cJSON_CreateDateTime(const struct DateTime * x); | |
| 78 | +char * cJSON_PrintDateTime(const struct DateTime * x); | |
| 79 | +void cJSON_DeleteDateTime(struct DateTime * x); | |
| 80 | + | |
| 81 | +struct EnumValues * cJSON_ParseEnumValues(const char * s); | |
| 82 | +struct EnumValues * cJSON_GetEnumValuesValue(const cJSON * j); | |
| 83 | +cJSON * cJSON_CreateEnumValues(const struct EnumValues * x); | |
| 84 | +char * cJSON_PrintEnumValues(const struct EnumValues * x); | |
| 85 | +void cJSON_DeleteEnumValues(struct EnumValues * x); | |
| 86 | + | |
| 87 | +struct FormatException * cJSON_ParseFormatException(const char * s); | |
| 88 | +struct FormatException * cJSON_GetFormatExceptionValue(const cJSON * j); | |
| 89 | +cJSON * cJSON_CreateFormatException(const struct FormatException * x); | |
| 90 | +char * cJSON_PrintFormatException(const struct FormatException * x); | |
| 91 | +void cJSON_DeleteFormatException(struct FormatException * x); | |
| 92 | + | |
| 93 | +struct RegExp * cJSON_ParseRegExp(const char * s); | |
| 94 | +struct RegExp * cJSON_GetRegExpValue(const cJSON * j); | |
| 95 | +cJSON * cJSON_CreateRegExp(const struct RegExp * x); | |
| 96 | +char * cJSON_PrintRegExp(const struct RegExp * x); | |
| 97 | +void cJSON_DeleteRegExp(struct RegExp * x); | |
| 98 | + | |
| 99 | +struct TopLevel * cJSON_ParseTopLevel(const char * s); | |
| 100 | +struct TopLevel * cJSON_GetTopLevelValue(const cJSON * j); | |
| 101 | +cJSON * cJSON_CreateTopLevel(const struct TopLevel * x); | |
| 102 | +char * cJSON_PrintTopLevel(const struct TopLevel * x); | |
| 103 | +void cJSON_DeleteTopLevel(struct TopLevel * x); | |
| 104 | + | |
| 105 | +#ifdef __cplusplus | |
| 106 | +} | |
| 107 | +#endif | |
| 108 | + | |
| 109 | +#endif /* __TOPLEVEL_H__ */ |
Aschema-cplusplusdefault / quicktype.hpp+368 −0
| @@ -0,0 +1,368 @@ | ||
| 1 | +// To parse this JSON data, first install | |
| 2 | +// | |
| 3 | +// json.hpp https://github.com/nlohmann/json | |
| 4 | +// | |
| 5 | +// Then include this file, and then do | |
| 6 | +// | |
| 7 | +// TopLevel data = nlohmann::json::parse(jsonString); | |
| 8 | + | |
| 9 | +#pragma once | |
| 10 | + | |
| 11 | +#include "json.hpp" | |
| 12 | + | |
| 13 | +#include <optional> | |
| 14 | +#include <stdexcept> | |
| 15 | +#include <regex> | |
| 16 | + | |
| 17 | +namespace quicktype { | |
| 18 | + using nlohmann::json; | |
| 19 | + | |
| 20 | + class ClassMemberConstraints { | |
| 21 | + private: | |
| 22 | + std::optional<int64_t> min_int_value; | |
| 23 | + std::optional<int64_t> max_int_value; | |
| 24 | + std::optional<double> min_double_value; | |
| 25 | + std::optional<double> max_double_value; | |
| 26 | + std::optional<size_t> min_length; | |
| 27 | + std::optional<size_t> max_length; | |
| 28 | + std::optional<std::string> pattern; | |
| 29 | + | |
| 30 | + public: | |
| 31 | + ClassMemberConstraints( | |
| 32 | + std::optional<int64_t> min_int_value, | |
| 33 | + std::optional<int64_t> max_int_value, | |
| 34 | + std::optional<double> min_double_value, | |
| 35 | + std::optional<double> max_double_value, | |
| 36 | + std::optional<size_t> min_length, | |
| 37 | + std::optional<size_t> max_length, | |
| 38 | + std::optional<std::string> pattern | |
| 39 | + ) : min_int_value(min_int_value), max_int_value(max_int_value), min_double_value(min_double_value), max_double_value(max_double_value), min_length(min_length), max_length(max_length), pattern(pattern) {} | |
| 40 | + ClassMemberConstraints() = default; | |
| 41 | + virtual ~ClassMemberConstraints() = default; | |
| 42 | + | |
| 43 | + void set_min_int_value(int64_t min_int_value) { this->min_int_value = min_int_value; } | |
| 44 | + auto get_min_int_value() const { return min_int_value; } | |
| 45 | + | |
| 46 | + void set_max_int_value(int64_t max_int_value) { this->max_int_value = max_int_value; } | |
| 47 | + auto get_max_int_value() const { return max_int_value; } | |
| 48 | + | |
| 49 | + void set_min_double_value(double min_double_value) { this->min_double_value = min_double_value; } | |
| 50 | + auto get_min_double_value() const { return min_double_value; } | |
| 51 | + | |
| 52 | + void set_max_double_value(double max_double_value) { this->max_double_value = max_double_value; } | |
| 53 | + auto get_max_double_value() const { return max_double_value; } | |
| 54 | + | |
| 55 | + void set_min_length(size_t min_length) { this->min_length = min_length; } | |
| 56 | + auto get_min_length() const { return min_length; } | |
| 57 | + | |
| 58 | + void set_max_length(size_t max_length) { this->max_length = max_length; } | |
| 59 | + auto get_max_length() const { return max_length; } | |
| 60 | + | |
| 61 | + void set_pattern(const std::string & pattern) { this->pattern = pattern; } | |
| 62 | + auto get_pattern() const { return pattern; } | |
| 63 | + }; | |
| 64 | + | |
| 65 | + class ClassMemberConstraintException : public std::runtime_error { | |
| 66 | + public: | |
| 67 | + ClassMemberConstraintException(const std::string & msg) : std::runtime_error(msg) {} | |
| 68 | + }; | |
| 69 | + | |
| 70 | + class ValueTooLowException : public ClassMemberConstraintException { | |
| 71 | + public: | |
| 72 | + ValueTooLowException(const std::string & msg) : ClassMemberConstraintException(msg) {} | |
| 73 | + }; | |
| 74 | + | |
| 75 | + class ValueTooHighException : public ClassMemberConstraintException { | |
| 76 | + public: | |
| 77 | + ValueTooHighException(const std::string & msg) : ClassMemberConstraintException(msg) {} | |
| 78 | + }; | |
| 79 | + | |
| 80 | + class ValueTooShortException : public ClassMemberConstraintException { | |
| 81 | + public: | |
| 82 | + ValueTooShortException(const std::string & msg) : ClassMemberConstraintException(msg) {} | |
| 83 | + }; | |
| 84 | + | |
| 85 | + class ValueTooLongException : public ClassMemberConstraintException { | |
| 86 | + public: | |
| 87 | + ValueTooLongException(const std::string & msg) : ClassMemberConstraintException(msg) {} | |
| 88 | + }; | |
| 89 | + | |
| 90 | + class InvalidPatternException : public ClassMemberConstraintException { | |
| 91 | + public: | |
| 92 | + InvalidPatternException(const std::string & msg) : ClassMemberConstraintException(msg) {} | |
| 93 | + }; | |
| 94 | + | |
| 95 | + inline void CheckConstraint(const std::string & name, const ClassMemberConstraints & c, int64_t value) { | |
| 96 | + if (c.get_min_int_value() != std::nullopt && value < *c.get_min_int_value()) { | |
| 97 | + throw ValueTooLowException ("Value too low for " + name + " (" + std::to_string(value) + "<" + std::to_string(*c.get_min_int_value()) + ")"); | |
| 98 | + } | |
| 99 | + | |
| 100 | + if (c.get_max_int_value() != std::nullopt && value > *c.get_max_int_value()) { | |
| 101 | + throw ValueTooHighException ("Value too high for " + name + " (" + std::to_string(value) + ">" + std::to_string(*c.get_max_int_value()) + ")"); | |
| 102 | + } | |
| 103 | + } | |
| 104 | + | |
| 105 | + inline void CheckConstraint(const std::string & name, const ClassMemberConstraints & c, const std::optional<int64_t> & value) { | |
| 106 | + if (value) { | |
| 107 | + CheckConstraint(name, c, *value); | |
| 108 | + } | |
| 109 | + } | |
| 110 | + | |
| 111 | + inline void CheckConstraint(const std::string & name, const ClassMemberConstraints & c, double value) { | |
| 112 | + if (c.get_min_double_value() != std::nullopt && value < *c.get_min_double_value()) { | |
| 113 | + throw ValueTooLowException ("Value too low for " + name + " (" + std::to_string(value) + "<" + std::to_string(*c.get_min_double_value()) + ")"); | |
| 114 | + } | |
| 115 | + | |
| 116 | + if (c.get_max_double_value() != std::nullopt && value > *c.get_max_double_value()) { | |
| 117 | + throw ValueTooHighException ("Value too high for " + name + " (" + std::to_string(value) + ">" + std::to_string(*c.get_max_double_value()) + ")"); | |
| 118 | + } | |
| 119 | + } | |
| 120 | + | |
| 121 | + inline void CheckConstraint(const std::string & name, const ClassMemberConstraints & c, const std::optional<double> & value) { | |
| 122 | + if (value) { | |
| 123 | + CheckConstraint(name, c, *value); | |
| 124 | + } | |
| 125 | + } | |
| 126 | + | |
| 127 | + inline void CheckConstraint(const std::string & name, const ClassMemberConstraints & c, const std::string & value) { | |
| 128 | + if (c.get_min_length() != std::nullopt && value.length() < *c.get_min_length()) { | |
| 129 | + throw ValueTooShortException ("Value too short for " + name + " (" + std::to_string(value.length()) + "<" + std::to_string(*c.get_min_length()) + ")"); | |
| 130 | + } | |
| 131 | + | |
| 132 | + if (c.get_max_length() != std::nullopt && value.length() > *c.get_max_length()) { | |
| 133 | + throw ValueTooLongException ("Value too long for " + name + " (" + std::to_string(value.length()) + ">" + std::to_string(*c.get_max_length()) + ")"); | |
| 134 | + } | |
| 135 | + | |
| 136 | + if (c.get_pattern() != std::nullopt) { | |
| 137 | + std::smatch result; | |
| 138 | + std::regex_search(value, result, std::regex( *c.get_pattern() )); | |
| 139 | + if (result.empty()) { | |
| 140 | + throw InvalidPatternException ("Value doesn't match pattern for " + name + " (" + value +" != " + *c.get_pattern() + ")"); | |
| 141 | + } | |
| 142 | + } | |
| 143 | + } | |
| 144 | + | |
| 145 | + inline void CheckConstraint(const std::string & name, const ClassMemberConstraints & c, const std::optional<std::string> & value) { | |
| 146 | + if (value) { | |
| 147 | + CheckConstraint(name, c, *value); | |
| 148 | + } | |
| 149 | + } | |
| 150 | + | |
| 151 | + #ifndef NLOHMANN_UNTYPED_quicktype_HELPER | |
| 152 | + #define NLOHMANN_UNTYPED_quicktype_HELPER | |
| 153 | + inline json get_untyped(const json & j, const char * property) { | |
| 154 | + if (j.find(property) != j.end()) { | |
| 155 | + return j.at(property).get<json>(); | |
| 156 | + } | |
| 157 | + return json(); | |
| 158 | + } | |
| 159 | + | |
| 160 | + inline json get_untyped(const json & j, std::string property) { | |
| 161 | + return get_untyped(j, property.data()); | |
| 162 | + } | |
| 163 | + #endif | |
| 164 | + | |
| 165 | + class DateTime { | |
| 166 | + public: | |
| 167 | + DateTime() = default; | |
| 168 | + virtual ~DateTime() = default; | |
| 169 | + | |
| 170 | + private: | |
| 171 | + int64_t value; | |
| 172 | + | |
| 173 | + public: | |
| 174 | + const int64_t & get_value() const { return value; } | |
| 175 | + int64_t & get_mutable_value() { return value; } | |
| 176 | + void set_value(const int64_t & value) { this->value = value; } | |
| 177 | + }; | |
| 178 | + | |
| 179 | + class EnumValues { | |
| 180 | + public: | |
| 181 | + EnumValues() = default; | |
| 182 | + virtual ~EnumValues() = default; | |
| 183 | + | |
| 184 | + private: | |
| 185 | + std::string label; | |
| 186 | + | |
| 187 | + public: | |
| 188 | + const std::string & get_label() const { return label; } | |
| 189 | + std::string & get_mutable_label() { return label; } | |
| 190 | + void set_label(const std::string & value) { this->label = value; } | |
| 191 | + }; | |
| 192 | + | |
| 193 | + class FormatException { | |
| 194 | + public: | |
| 195 | + FormatException() = default; | |
| 196 | + virtual ~FormatException() = default; | |
| 197 | + | |
| 198 | + private: | |
| 199 | + int64_t count; | |
| 200 | + | |
| 201 | + public: | |
| 202 | + const int64_t & get_count() const { return count; } | |
| 203 | + int64_t & get_mutable_count() { return count; } | |
| 204 | + void set_count(const int64_t & value) { this->count = value; } | |
| 205 | + }; | |
| 206 | + | |
| 207 | + class RegExp { | |
| 208 | + public: | |
| 209 | + RegExp() = default; | |
| 210 | + virtual ~RegExp() = default; | |
| 211 | + | |
| 212 | + private: | |
| 213 | + bool active; | |
| 214 | + | |
| 215 | + public: | |
| 216 | + const bool & get_active() const { return active; } | |
| 217 | + bool & get_mutable_active() { return active; } | |
| 218 | + void set_active(const bool & value) { this->active = value; } | |
| 219 | + }; | |
| 220 | + | |
| 221 | + enum class Status : int { READY, DONE }; | |
| 222 | + | |
| 223 | + class TopLevel { | |
| 224 | + public: | |
| 225 | + TopLevel() : | |
| 226 | + code_constraint(std::nullopt, std::nullopt, std::nullopt, std::nullopt, 1, std::nullopt, std::string("^[a-z]+$")) | |
| 227 | + {} | |
| 228 | + virtual ~TopLevel() = default; | |
| 229 | + | |
| 230 | + private: | |
| 231 | + std::string code; | |
| 232 | + ClassMemberConstraints code_constraint; | |
| 233 | + DateTime date_time; | |
| 234 | + EnumValues enum_values; | |
| 235 | + FormatException format_exception; | |
| 236 | + RegExp reg_exp; | |
| 237 | + Status status; | |
| 238 | + std::string timestamp; | |
| 239 | + | |
| 240 | + public: | |
| 241 | + const std::string & get_code() const { return code; } | |
| 242 | + std::string & get_mutable_code() { return code; } | |
| 243 | + void set_code(const std::string & value) { CheckConstraint("code", code_constraint, value); this->code = value; } | |
| 244 | + | |
| 245 | + const DateTime & get_date_time() const { return date_time; } | |
| 246 | + DateTime & get_mutable_date_time() { return date_time; } | |
| 247 | + void set_date_time(const DateTime & value) { this->date_time = value; } | |
| 248 | + | |
| 249 | + const EnumValues & get_enum_values() const { return enum_values; } | |
| 250 | + EnumValues & get_mutable_enum_values() { return enum_values; } | |
| 251 | + void set_enum_values(const EnumValues & value) { this->enum_values = value; } | |
| 252 | + | |
| 253 | + const FormatException & get_format_exception() const { return format_exception; } | |
| 254 | + FormatException & get_mutable_format_exception() { return format_exception; } | |
| 255 | + void set_format_exception(const FormatException & value) { this->format_exception = value; } | |
| 256 | + | |
| 257 | + const RegExp & get_reg_exp() const { return reg_exp; } | |
| 258 | + RegExp & get_mutable_reg_exp() { return reg_exp; } | |
| 259 | + void set_reg_exp(const RegExp & value) { this->reg_exp = value; } | |
| 260 | + | |
| 261 | + const Status & get_status() const { return status; } | |
| 262 | + Status & get_mutable_status() { return status; } | |
| 263 | + void set_status(const Status & value) { this->status = value; } | |
| 264 | + | |
| 265 | + const std::string & get_timestamp() const { return timestamp; } | |
| 266 | + std::string & get_mutable_timestamp() { return timestamp; } | |
| 267 | + void set_timestamp(const std::string & value) { this->timestamp = value; } | |
| 268 | + }; | |
| 269 | +} | |
| 270 | + | |
| 271 | +namespace quicktype { | |
| 272 | + void from_json(const json & j, DateTime & x); | |
| 273 | + void to_json(json & j, const DateTime & x); | |
| 274 | + | |
| 275 | + void from_json(const json & j, EnumValues & x); | |
| 276 | + void to_json(json & j, const EnumValues & x); | |
| 277 | + | |
| 278 | + void from_json(const json & j, FormatException & x); | |
| 279 | + void to_json(json & j, const FormatException & x); | |
| 280 | + | |
| 281 | + void from_json(const json & j, RegExp & x); | |
| 282 | + void to_json(json & j, const RegExp & x); | |
| 283 | + | |
| 284 | + void from_json(const json & j, TopLevel & x); | |
| 285 | + void to_json(json & j, const TopLevel & x); | |
| 286 | + | |
| 287 | + void from_json(const json & j, Status & x); | |
| 288 | + void to_json(json & j, const Status & x); | |
| 289 | + | |
| 290 | + inline void from_json(const json & j, DateTime& x) { | |
| 291 | + if (!j.is_object()) throw std::runtime_error("Expected object"); | |
| 292 | + if (j.find("value") != j.end() && !j.at("value").is_number_integer()) throw std::runtime_error("Expected integer"); | |
| 293 | + x.set_value(j.at("value").get<int64_t>()); | |
| 294 | + } | |
| 295 | + | |
| 296 | + inline void to_json(json & j, const DateTime & x) { | |
| 297 | + j = json::object(); | |
| 298 | + j["value"] = x.get_value(); | |
| 299 | + } | |
| 300 | + | |
| 301 | + inline void from_json(const json & j, EnumValues& x) { | |
| 302 | + if (!j.is_object()) throw std::runtime_error("Expected object"); | |
| 303 | + x.set_label(j.at("label").get<std::string>()); | |
| 304 | + } | |
| 305 | + | |
| 306 | + inline void to_json(json & j, const EnumValues & x) { | |
| 307 | + j = json::object(); | |
| 308 | + j["label"] = x.get_label(); | |
| 309 | + } | |
| 310 | + | |
| 311 | + inline void from_json(const json & j, FormatException& x) { | |
| 312 | + if (!j.is_object()) throw std::runtime_error("Expected object"); | |
| 313 | + if (j.find("count") != j.end() && !j.at("count").is_number_integer()) throw std::runtime_error("Expected integer"); | |
| 314 | + x.set_count(j.at("count").get<int64_t>()); | |
| 315 | + } | |
| 316 | + | |
| 317 | + inline void to_json(json & j, const FormatException & x) { | |
| 318 | + j = json::object(); | |
| 319 | + j["count"] = x.get_count(); | |
| 320 | + } | |
| 321 | + | |
| 322 | + inline void from_json(const json & j, RegExp& x) { | |
| 323 | + if (!j.is_object()) throw std::runtime_error("Expected object"); | |
| 324 | + x.set_active(j.at("active").get<bool>()); | |
| 325 | + } | |
| 326 | + | |
| 327 | + inline void to_json(json & j, const RegExp & x) { | |
| 328 | + j = json::object(); | |
| 329 | + j["active"] = x.get_active(); | |
| 330 | + } | |
| 331 | + | |
| 332 | + inline void from_json(const json & j, TopLevel& x) { | |
| 333 | + if (!j.is_object()) throw std::runtime_error("Expected object"); | |
| 334 | + x.set_code(j.at("code").get<std::string>()); | |
| 335 | + x.set_date_time(j.at("dateTime").get<DateTime>()); | |
| 336 | + x.set_enum_values(j.at("enumValues").get<EnumValues>()); | |
| 337 | + x.set_format_exception(j.at("formatException").get<FormatException>()); | |
| 338 | + x.set_reg_exp(j.at("regExp").get<RegExp>()); | |
| 339 | + x.set_status(j.at("status").get<Status>()); | |
| 340 | + if (j.find("timestamp") != j.end() && !std::regex_match(j.at("timestamp").get<std::string>(), std::regex("^[0-9]{4}-[0-9]{2}-[0-9]{2}T.*$"))) throw std::runtime_error("Expected date-time"); | |
| 341 | + x.set_timestamp(j.at("timestamp").get<std::string>()); | |
| 342 | + } | |
| 343 | + | |
| 344 | + inline void to_json(json & j, const TopLevel & x) { | |
| 345 | + j = json::object(); | |
| 346 | + j["code"] = x.get_code(); | |
| 347 | + j["dateTime"] = x.get_date_time(); | |
| 348 | + j["enumValues"] = x.get_enum_values(); | |
| 349 | + j["formatException"] = x.get_format_exception(); | |
| 350 | + j["regExp"] = x.get_reg_exp(); | |
| 351 | + j["status"] = x.get_status(); | |
| 352 | + j["timestamp"] = x.get_timestamp(); | |
| 353 | + } | |
| 354 | + | |
| 355 | + inline void from_json(const json & j, Status & x) { | |
| 356 | + if (j == "ready") x = Status::READY; | |
| 357 | + else if (j == "done") x = Status::DONE; | |
| 358 | + else { throw std::runtime_error("Cannot deserialize to enumeration \"Status\""); } | |
| 359 | + } | |
| 360 | + | |
| 361 | + inline void to_json(json & j, const Status & x) { | |
| 362 | + switch (x) { | |
| 363 | + case Status::READY: j = "ready"; break; | |
| 364 | + case Status::DONE: j = "done"; break; | |
| 365 | + default: throw std::runtime_error("Unexpected value in enumeration \"Status\": " + std::to_string(static_cast<int>(x))); | |
| 366 | + } | |
| 367 | + } | |
| 368 | +} |
Aschema-crystaldefault / TopLevel.cr+47 −0
| @@ -0,0 +1,47 @@ | ||
| 1 | +require "json" | |
| 2 | + | |
| 3 | +class TopLevel | |
| 4 | + include JSON::Serializable | |
| 5 | + | |
| 6 | + property code : String | |
| 7 | + | |
| 8 | + @[JSON::Field(key: "dateTime")] | |
| 9 | + property date_time : DateTime | |
| 10 | + | |
| 11 | + @[JSON::Field(key: "enumValues")] | |
| 12 | + property enum_values : EnumValues | |
| 13 | + | |
| 14 | + @[JSON::Field(key: "formatException")] | |
| 15 | + property format_exception : FormatException | |
| 16 | + | |
| 17 | + @[JSON::Field(key: "regExp")] | |
| 18 | + property reg_exp : RegExp | |
| 19 | + | |
| 20 | + property status : String | |
| 21 | + | |
| 22 | + property timestamp : String | |
| 23 | +end | |
| 24 | + | |
| 25 | +class DateTime | |
| 26 | + include JSON::Serializable | |
| 27 | + | |
| 28 | + property value : Int64 | |
| 29 | +end | |
| 30 | + | |
| 31 | +class EnumValues | |
| 32 | + include JSON::Serializable | |
| 33 | + | |
| 34 | + property label : String | |
| 35 | +end | |
| 36 | + | |
| 37 | +class FormatException | |
| 38 | + include JSON::Serializable | |
| 39 | + | |
| 40 | + property count : Int64 | |
| 41 | +end | |
| 42 | + | |
| 43 | +class RegExp | |
| 44 | + include JSON::Serializable | |
| 45 | + | |
| 46 | + property active : Bool | |
| 47 | +end |
Aschema-csharp-recordsdefault / QuickType.cs+176 −0
| @@ -0,0 +1,176 @@ | ||
| 1 | +// <auto-generated /> | |
| 2 | +// | |
| 3 | +// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do: | |
| 4 | +// | |
| 5 | +// using QuickType; | |
| 6 | +// | |
| 7 | +// var topLevel = TopLevel.FromJson(jsonString); | |
| 8 | +#nullable enable | |
| 9 | +#pragma warning disable CS8618 | |
| 10 | +#pragma warning disable CS8601 | |
| 11 | +#pragma warning disable CS8602 | |
| 12 | +#pragma warning disable CS8603 | |
| 13 | +#pragma warning disable CS8604 | |
| 14 | +#pragma warning disable CS8625 | |
| 15 | +#pragma warning disable CS8765 | |
| 16 | + | |
| 17 | +namespace QuickType | |
| 18 | +{ | |
| 19 | + using System; | |
| 20 | + using System.Collections.Generic; | |
| 21 | + | |
| 22 | + using System.Globalization; | |
| 23 | + using Newtonsoft.Json; | |
| 24 | + using Newtonsoft.Json.Converters; | |
| 25 | + | |
| 26 | + public partial record TopLevel | |
| 27 | + { | |
| 28 | + [JsonProperty("code", Required = Required.Always)] | |
| 29 | + [JsonConverter(typeof(MinMaxLengthCheckConverter))] | |
| 30 | + public string Code { get; set; } | |
| 31 | + | |
| 32 | + [JsonProperty("dateTime", Required = Required.Always)] | |
| 33 | + public DateTime DateTime { get; set; } | |
| 34 | + | |
| 35 | + [JsonProperty("enumValues", Required = Required.Always)] | |
| 36 | + public EnumValues EnumValues { get; set; } | |
| 37 | + | |
| 38 | + [JsonProperty("formatException", Required = Required.Always)] | |
| 39 | + public FormatException FormatException { get; set; } | |
| 40 | + | |
| 41 | + [JsonProperty("regExp", Required = Required.Always)] | |
| 42 | + public RegExp RegExp { get; set; } | |
| 43 | + | |
| 44 | + [JsonProperty("status", Required = Required.Always)] | |
| 45 | + public Status Status { get; set; } | |
| 46 | + | |
| 47 | + [JsonProperty("timestamp", Required = Required.Always)] | |
| 48 | + public DateTimeOffset Timestamp { get; set; } | |
| 49 | + } | |
| 50 | + | |
| 51 | + public partial record DateTime | |
| 52 | + { | |
| 53 | + [JsonProperty("value", Required = Required.Always)] | |
| 54 | + public long Value { get; set; } | |
| 55 | + } | |
| 56 | + | |
| 57 | + public partial record EnumValues | |
| 58 | + { | |
| 59 | + [JsonProperty("label", Required = Required.Always)] | |
| 60 | + public string Label { get; set; } | |
| 61 | + } | |
| 62 | + | |
| 63 | + public partial record FormatException | |
| 64 | + { | |
| 65 | + [JsonProperty("count", Required = Required.Always)] | |
| 66 | + public long Count { get; set; } | |
| 67 | + } | |
| 68 | + | |
| 69 | + public partial record RegExp | |
| 70 | + { | |
| 71 | + [JsonProperty("active", Required = Required.Always)] | |
| 72 | + public bool Active { get; set; } | |
| 73 | + } | |
| 74 | + | |
| 75 | + public enum Status { Ready, Done }; | |
| 76 | + | |
| 77 | + public partial record TopLevel | |
| 78 | + { | |
| 79 | + public static TopLevel FromJson(string json) => JsonConvert.DeserializeObject<TopLevel>(json, QuickType.Converter.Settings); | |
| 80 | + } | |
| 81 | + | |
| 82 | + public static partial class Serialize | |
| 83 | + { | |
| 84 | + public static string ToJson(this TopLevel self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings); | |
| 85 | + } | |
| 86 | + | |
| 87 | + internal static partial class Converter | |
| 88 | + { | |
| 89 | + public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings | |
| 90 | + { | |
| 91 | + MetadataPropertyHandling = MetadataPropertyHandling.Ignore, | |
| 92 | + DateParseHandling = DateParseHandling.None, | |
| 93 | + Converters = | |
| 94 | + { | |
| 95 | + StatusConverter.Singleton, | |
| 96 | + new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } | |
| 97 | + }, | |
| 98 | + }; | |
| 99 | + } | |
| 100 | + | |
| 101 | + internal class MinMaxLengthCheckConverter : JsonConverter | |
| 102 | + { | |
| 103 | + public override bool CanConvert(Type t) => t == typeof(string); | |
| 104 | + | |
| 105 | + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) | |
| 106 | + { | |
| 107 | + var value = serializer.Deserialize<string>(reader); | |
| 108 | + if (value.Length >= 1) | |
| 109 | + { | |
| 110 | + return value; | |
| 111 | + } | |
| 112 | + throw new Exception("Cannot unmarshal type string"); | |
| 113 | + } | |
| 114 | + | |
| 115 | + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) | |
| 116 | + { | |
| 117 | + var value = (string)untypedValue; | |
| 118 | + if (value.Length >= 1) | |
| 119 | + { | |
| 120 | + serializer.Serialize(writer, value); | |
| 121 | + return; | |
| 122 | + } | |
| 123 | + throw new Exception("Cannot marshal type string"); | |
| 124 | + } | |
| 125 | + | |
| 126 | + public static readonly MinMaxLengthCheckConverter Singleton = new MinMaxLengthCheckConverter(); | |
| 127 | + } | |
| 128 | + | |
| 129 | + internal class StatusConverter : JsonConverter | |
| 130 | + { | |
| 131 | + public override bool CanConvert(Type t) => t == typeof(Status) || t == typeof(Status?); | |
| 132 | + | |
| 133 | + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) | |
| 134 | + { | |
| 135 | + if (reader.TokenType == JsonToken.Null) return null; | |
| 136 | + var value = serializer.Deserialize<string>(reader); | |
| 137 | + switch (value) | |
| 138 | + { | |
| 139 | + case "ready": | |
| 140 | + return Status.Ready; | |
| 141 | + case "done": | |
| 142 | + return Status.Done; | |
| 143 | + } | |
| 144 | + throw new Exception("Cannot unmarshal type Status"); | |
| 145 | + } | |
| 146 | + | |
| 147 | + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) | |
| 148 | + { | |
| 149 | + if (untypedValue == null) | |
| 150 | + { | |
| 151 | + serializer.Serialize(writer, null); | |
| 152 | + return; | |
| 153 | + } | |
| 154 | + var value = (Status)untypedValue; | |
| 155 | + switch (value) | |
| 156 | + { | |
| 157 | + case Status.Ready: | |
| 158 | + serializer.Serialize(writer, "ready"); | |
| 159 | + return; | |
| 160 | + case Status.Done: | |
| 161 | + serializer.Serialize(writer, "done"); | |
| 162 | + return; | |
| 163 | + } | |
| 164 | + throw new Exception("Cannot marshal type Status"); | |
| 165 | + } | |
| 166 | + | |
| 167 | + public static readonly StatusConverter Singleton = new StatusConverter(); | |
| 168 | + } | |
| 169 | +} | |
| 170 | +#pragma warning restore CS8618 | |
| 171 | +#pragma warning restore CS8601 | |
| 172 | +#pragma warning restore CS8602 | |
| 173 | +#pragma warning restore CS8603 | |
| 174 | +#pragma warning restore CS8604 | |
| 175 | +#pragma warning restore CS8625 | |
| 176 | +#pragma warning restore CS8765 |
Aschema-csharp-SystemTextJsondefault / QuickType.cs+283 −0
| @@ -0,0 +1,283 @@ | ||
| 1 | +// <auto-generated /> | |
| 2 | +// | |
| 3 | +// To parse this JSON data, add NuGet 'System.Text.Json' then do: | |
| 4 | +// | |
| 5 | +// using QuickType; | |
| 6 | +// | |
| 7 | +// var topLevel = TopLevel.FromJson(jsonString); | |
| 8 | +#nullable enable | |
| 9 | +#pragma warning disable CS8618 | |
| 10 | +#pragma warning disable CS8601 | |
| 11 | +#pragma warning disable CS8602 | |
| 12 | +#pragma warning disable CS8603 | |
| 13 | + | |
| 14 | +namespace QuickType | |
| 15 | +{ | |
| 16 | + using System; | |
| 17 | + using System.Collections.Generic; | |
| 18 | + | |
| 19 | + using System.Text.Json; | |
| 20 | + using System.Text.Json.Serialization; | |
| 21 | + using System.Globalization; | |
| 22 | + | |
| 23 | + public partial class TopLevel | |
| 24 | + { | |
| 25 | + [JsonRequired] | |
| 26 | + [JsonPropertyName("code")] | |
| 27 | + [JsonConverter(typeof(MinMaxLengthCheckConverter))] | |
| 28 | + public string Code { get; set; } | |
| 29 | + | |
| 30 | + [JsonRequired] | |
| 31 | + [JsonPropertyName("dateTime")] | |
| 32 | + public DateTime DateTime { get; set; } | |
| 33 | + | |
| 34 | + [JsonRequired] | |
| 35 | + [JsonPropertyName("enumValues")] | |
| 36 | + public EnumValues EnumValues { get; set; } | |
| 37 | + | |
| 38 | + [JsonRequired] | |
| 39 | + [JsonPropertyName("formatException")] | |
| 40 | + public FormatException FormatException { get; set; } | |
| 41 | + | |
| 42 | + [JsonRequired] | |
| 43 | + [JsonPropertyName("regExp")] | |
| 44 | + public RegExp RegExp { get; set; } | |
| 45 | + | |
| 46 | + [JsonRequired] | |
| 47 | + [JsonPropertyName("status")] | |
| 48 | + public Status Status { get; set; } | |
| 49 | + | |
| 50 | + [JsonRequired] | |
| 51 | + [JsonPropertyName("timestamp")] | |
| 52 | + public DateTimeOffset Timestamp { get; set; } | |
| 53 | + } | |
| 54 | + | |
| 55 | + public partial class DateTime | |
| 56 | + { | |
| 57 | + [JsonRequired] | |
| 58 | + [JsonPropertyName("value")] | |
| 59 | + public long Value { get; set; } | |
| 60 | + } | |
| 61 | + | |
| 62 | + public partial class EnumValues | |
| 63 | + { | |
| 64 | + [JsonRequired] | |
| 65 | + [JsonPropertyName("label")] | |
| 66 | + public string Label { get; set; } | |
| 67 | + } | |
| 68 | + | |
| 69 | + public partial class FormatException | |
| 70 | + { | |
| 71 | + [JsonRequired] | |
| 72 | + [JsonPropertyName("count")] | |
| 73 | + public long Count { get; set; } | |
| 74 | + } | |
| 75 | + | |
| 76 | + public partial class RegExp | |
| 77 | + { | |
| 78 | + [JsonRequired] | |
| 79 | + [JsonPropertyName("active")] | |
| 80 | + public bool Active { get; set; } | |
| 81 | + } | |
| 82 | + | |
| 83 | + public enum Status { Ready, Done }; | |
| 84 | + | |
| 85 | + public partial class TopLevel | |
| 86 | + { | |
| 87 | + public static TopLevel FromJson(string json) => global::System.Text.Json.JsonSerializer.Deserialize<TopLevel>(json, QuickType.Converter.Settings); | |
| 88 | + } | |
| 89 | + | |
| 90 | + public static partial class Serialize | |
| 91 | + { | |
| 92 | + public static string ToJson(this TopLevel self) => JsonSerializer.Serialize(self, QuickType.Converter.Settings); | |
| 93 | + } | |
| 94 | + | |
| 95 | + internal static partial class Converter | |
| 96 | + { | |
| 97 | + public static readonly JsonSerializerOptions Settings = new(JsonSerializerDefaults.General) | |
| 98 | + { | |
| 99 | + Converters = | |
| 100 | + { | |
| 101 | + StatusConverter.Singleton, | |
| 102 | + new DateOnlyConverter(), | |
| 103 | + new TimeOnlyConverter(), | |
| 104 | + IsoDateTimeOffsetConverter.Singleton | |
| 105 | + }, | |
| 106 | + }; | |
| 107 | + } | |
| 108 | + | |
| 109 | + internal class MinMaxLengthCheckConverter : JsonConverter<string> | |
| 110 | + { | |
| 111 | + public override bool CanConvert(Type t) => t == typeof(string); | |
| 112 | + | |
| 113 | + public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | |
| 114 | + { | |
| 115 | + var value = reader.GetString(); | |
| 116 | + if (value.Length >= 1) | |
| 117 | + { | |
| 118 | + return value; | |
| 119 | + } | |
| 120 | + throw new JsonException("Cannot unmarshal type string"); | |
| 121 | + } | |
| 122 | + | |
| 123 | + public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) | |
| 124 | + { | |
| 125 | + if (value.Length >= 1) | |
| 126 | + { | |
| 127 | + JsonSerializer.Serialize(writer, value, options); | |
| 128 | + return; | |
| 129 | + } | |
| 130 | + throw new NotSupportedException("Cannot marshal type string"); | |
| 131 | + } | |
| 132 | + | |
| 133 | + public static readonly MinMaxLengthCheckConverter Singleton = new MinMaxLengthCheckConverter(); | |
| 134 | + } | |
| 135 | + | |
| 136 | + internal class StatusConverter : JsonConverter<Status> | |
| 137 | + { | |
| 138 | + public override bool CanConvert(Type t) => t == typeof(Status); | |
| 139 | + | |
| 140 | + public override Status Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | |
| 141 | + { | |
| 142 | + var value = reader.GetString(); | |
| 143 | + switch (value) | |
| 144 | + { | |
| 145 | + case "ready": | |
| 146 | + return Status.Ready; | |
| 147 | + case "done": | |
| 148 | + return Status.Done; | |
| 149 | + } | |
| 150 | + throw new JsonException("Cannot unmarshal type Status"); | |
| 151 | + } | |
| 152 | + | |
| 153 | + public override void Write(Utf8JsonWriter writer, Status value, JsonSerializerOptions options) | |
| 154 | + { | |
| 155 | + switch (value) | |
| 156 | + { | |
| 157 | + case Status.Ready: | |
| 158 | + JsonSerializer.Serialize(writer, "ready", options); | |
| 159 | + return; | |
| 160 | + case Status.Done: | |
| 161 | + JsonSerializer.Serialize(writer, "done", options); | |
| 162 | + return; | |
| 163 | + } | |
| 164 | + throw new NotSupportedException("Cannot marshal type Status"); | |
| 165 | + } | |
| 166 | + | |
| 167 | + public static readonly StatusConverter Singleton = new StatusConverter(); | |
| 168 | + } | |
| 169 | + | |
| 170 | + public class DateOnlyConverter : JsonConverter<DateOnly> | |
| 171 | + { | |
| 172 | + private readonly string serializationFormat; | |
| 173 | + public DateOnlyConverter() : this(null) { } | |
| 174 | + | |
| 175 | + public DateOnlyConverter(string? serializationFormat) | |
| 176 | + { | |
| 177 | + this.serializationFormat = serializationFormat ?? "yyyy-MM-dd"; | |
| 178 | + } | |
| 179 | + | |
| 180 | + public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | |
| 181 | + { | |
| 182 | + var value = reader.GetString(); | |
| 183 | + return DateOnly.Parse(value!); | |
| 184 | + } | |
| 185 | + | |
| 186 | + public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options) | |
| 187 | + => writer.WriteStringValue(value.ToString(serializationFormat)); | |
| 188 | + } | |
| 189 | + | |
| 190 | + public class TimeOnlyConverter : JsonConverter<TimeOnly> | |
| 191 | + { | |
| 192 | + private readonly string serializationFormat; | |
| 193 | + | |
| 194 | + public TimeOnlyConverter() : this(null) { } | |
| 195 | + | |
| 196 | + public TimeOnlyConverter(string? serializationFormat) | |
| 197 | + { | |
| 198 | + this.serializationFormat = serializationFormat ?? "HH:mm:ss.fff"; | |
| 199 | + } | |
| 200 | + | |
| 201 | + public override TimeOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | |
| 202 | + { | |
| 203 | + var value = reader.GetString(); | |
| 204 | + return TimeOnly.Parse(value!); | |
| 205 | + } | |
| 206 | + | |
| 207 | + public override void Write(Utf8JsonWriter writer, TimeOnly value, JsonSerializerOptions options) | |
| 208 | + => writer.WriteStringValue(value.ToString(serializationFormat)); | |
| 209 | + } | |
| 210 | + | |
| 211 | + internal class IsoDateTimeOffsetConverter : JsonConverter<DateTimeOffset> | |
| 212 | + { | |
| 213 | + public override bool CanConvert(Type t) => t == typeof(DateTimeOffset); | |
| 214 | + | |
| 215 | + private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"; | |
| 216 | + | |
| 217 | + private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind; | |
| 218 | + private string? _dateTimeFormat; | |
| 219 | + private CultureInfo? _culture; | |
| 220 | + | |
| 221 | + public DateTimeStyles DateTimeStyles | |
| 222 | + { | |
| 223 | + get => _dateTimeStyles; | |
| 224 | + set => _dateTimeStyles = value; | |
| 225 | + } | |
| 226 | + | |
| 227 | + public string? DateTimeFormat | |
| 228 | + { | |
| 229 | + get => _dateTimeFormat ?? string.Empty; | |
| 230 | + set => _dateTimeFormat = (string.IsNullOrEmpty(value)) ? null : value; | |
| 231 | + } | |
| 232 | + | |
| 233 | + public CultureInfo Culture | |
| 234 | + { | |
| 235 | + get => _culture ?? CultureInfo.CurrentCulture; | |
| 236 | + set => _culture = value; | |
| 237 | + } | |
| 238 | + | |
| 239 | + public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options) | |
| 240 | + { | |
| 241 | + string text; | |
| 242 | + | |
| 243 | + | |
| 244 | + if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal | |
| 245 | + || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal) | |
| 246 | + { | |
| 247 | + value = value.ToUniversalTime(); | |
| 248 | + } | |
| 249 | + | |
| 250 | + text = value.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture); | |
| 251 | + | |
| 252 | + writer.WriteStringValue(text); | |
| 253 | + } | |
| 254 | + | |
| 255 | + public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | |
| 256 | + { | |
| 257 | + string? dateText = reader.GetString(); | |
| 258 | + | |
| 259 | + if (string.IsNullOrEmpty(dateText) == false) | |
| 260 | + { | |
| 261 | + if (!string.IsNullOrEmpty(_dateTimeFormat)) | |
| 262 | + { | |
| 263 | + return DateTimeOffset.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles); | |
| 264 | + } | |
| 265 | + else | |
| 266 | + { | |
| 267 | + return DateTimeOffset.Parse(dateText, Culture, _dateTimeStyles); | |
| 268 | + } | |
| 269 | + } | |
| 270 | + else | |
| 271 | + { | |
| 272 | + return default(DateTimeOffset); | |
| 273 | + } | |
| 274 | + } | |
| 275 | + | |
| 276 | + | |
| 277 | + public static readonly IsoDateTimeOffsetConverter Singleton = new IsoDateTimeOffsetConverter(); | |
| 278 | + } | |
| 279 | +} | |
| 280 | +#pragma warning restore CS8618 | |
| 281 | +#pragma warning restore CS8601 | |
| 282 | +#pragma warning restore CS8602 | |
| 283 | +#pragma warning restore CS8603 |
Aschema-csharpdefault / QuickType.cs+176 −0
| @@ -0,0 +1,176 @@ | ||
| 1 | +// <auto-generated /> | |
| 2 | +// | |
| 3 | +// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do: | |
| 4 | +// | |
| 5 | +// using QuickType; | |
| 6 | +// | |
| 7 | +// var topLevel = TopLevel.FromJson(jsonString); | |
| 8 | +#nullable enable | |
| 9 | +#pragma warning disable CS8618 | |
| 10 | +#pragma warning disable CS8601 | |
| 11 | +#pragma warning disable CS8602 | |
| 12 | +#pragma warning disable CS8603 | |
| 13 | +#pragma warning disable CS8604 | |
| 14 | +#pragma warning disable CS8625 | |
| 15 | +#pragma warning disable CS8765 | |
| 16 | + | |
| 17 | +namespace QuickType | |
| 18 | +{ | |
| 19 | + using System; | |
| 20 | + using System.Collections.Generic; | |
| 21 | + | |
| 22 | + using System.Globalization; | |
| 23 | + using Newtonsoft.Json; | |
| 24 | + using Newtonsoft.Json.Converters; | |
| 25 | + | |
| 26 | + public partial class TopLevel | |
| 27 | + { | |
| 28 | + [JsonProperty("code", Required = Required.Always)] | |
| 29 | + [JsonConverter(typeof(MinMaxLengthCheckConverter))] | |
| 30 | + public string Code { get; set; } | |
| 31 | + | |
| 32 | + [JsonProperty("dateTime", Required = Required.Always)] | |
| 33 | + public DateTime DateTime { get; set; } | |
| 34 | + | |
| 35 | + [JsonProperty("enumValues", Required = Required.Always)] | |
| 36 | + public EnumValues EnumValues { get; set; } | |
| 37 | + | |
| 38 | + [JsonProperty("formatException", Required = Required.Always)] | |
| 39 | + public FormatException FormatException { get; set; } | |
| 40 | + | |
| 41 | + [JsonProperty("regExp", Required = Required.Always)] | |
| 42 | + public RegExp RegExp { get; set; } | |
| 43 | + | |
| 44 | + [JsonProperty("status", Required = Required.Always)] | |
| 45 | + public Status Status { get; set; } | |
| 46 | + | |
| 47 | + [JsonProperty("timestamp", Required = Required.Always)] | |
| 48 | + public DateTimeOffset Timestamp { get; set; } | |
| 49 | + } | |
| 50 | + | |
| 51 | + public partial class DateTime | |
| 52 | + { | |
| 53 | + [JsonProperty("value", Required = Required.Always)] | |
| 54 | + public long Value { get; set; } | |
| 55 | + } | |
| 56 | + | |
| 57 | + public partial class EnumValues | |
| 58 | + { | |
| 59 | + [JsonProperty("label", Required = Required.Always)] | |
| 60 | + public string Label { get; set; } | |
| 61 | + } | |
| 62 | + | |
| 63 | + public partial class FormatException | |
| 64 | + { | |
| 65 | + [JsonProperty("count", Required = Required.Always)] | |
| 66 | + public long Count { get; set; } | |
| 67 | + } | |
| 68 | + | |
| 69 | + public partial class RegExp | |
| 70 | + { | |
| 71 | + [JsonProperty("active", Required = Required.Always)] | |
| 72 | + public bool Active { get; set; } | |
| 73 | + } | |
| 74 | + | |
| 75 | + public enum Status { Ready, Done }; | |
| 76 | + | |
| 77 | + public partial class TopLevel | |
| 78 | + { | |
| 79 | + public static TopLevel FromJson(string json) => JsonConvert.DeserializeObject<TopLevel>(json, QuickType.Converter.Settings); | |
| 80 | + } | |
| 81 | + | |
| 82 | + public static partial class Serialize | |
| 83 | + { | |
| 84 | + public static string ToJson(this TopLevel self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings); | |
| 85 | + } | |
| 86 | + | |
| 87 | + internal static partial class Converter | |
| 88 | + { | |
| 89 | + public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings | |
| 90 | + { | |
| 91 | + MetadataPropertyHandling = MetadataPropertyHandling.Ignore, | |
| 92 | + DateParseHandling = DateParseHandling.None, | |
| 93 | + Converters = | |
| 94 | + { | |
| 95 | + StatusConverter.Singleton, | |
| 96 | + new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } | |
| 97 | + }, | |
| 98 | + }; | |
| 99 | + } | |
| 100 | + | |
| 101 | + internal class MinMaxLengthCheckConverter : JsonConverter | |
| 102 | + { | |
| 103 | + public override bool CanConvert(Type t) => t == typeof(string); | |
| 104 | + | |
| 105 | + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) | |
| 106 | + { | |
| 107 | + var value = serializer.Deserialize<string>(reader); | |
| 108 | + if (value.Length >= 1) | |
| 109 | + { | |
| 110 | + return value; | |
| 111 | + } | |
| 112 | + throw new Exception("Cannot unmarshal type string"); | |
| 113 | + } | |
| 114 | + | |
| 115 | + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) | |
| 116 | + { | |
| 117 | + var value = (string)untypedValue; | |
| 118 | + if (value.Length >= 1) | |
| 119 | + { | |
| 120 | + serializer.Serialize(writer, value); | |
| 121 | + return; | |
| 122 | + } | |
| 123 | + throw new Exception("Cannot marshal type string"); | |
| 124 | + } | |
| 125 | + | |
| 126 | + public static readonly MinMaxLengthCheckConverter Singleton = new MinMaxLengthCheckConverter(); | |
| 127 | + } | |
| 128 | + | |
| 129 | + internal class StatusConverter : JsonConverter | |
| 130 | + { | |
| 131 | + public override bool CanConvert(Type t) => t == typeof(Status) || t == typeof(Status?); | |
| 132 | + | |
| 133 | + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) | |
| 134 | + { | |
| 135 | + if (reader.TokenType == JsonToken.Null) return null; | |
| 136 | + var value = serializer.Deserialize<string>(reader); | |
| 137 | + switch (value) | |
| 138 | + { | |
| 139 | + case "ready": | |
| 140 | + return Status.Ready; | |
| 141 | + case "done": | |
| 142 | + return Status.Done; | |
| 143 | + } | |
| 144 | + throw new Exception("Cannot unmarshal type Status"); | |
| 145 | + } | |
| 146 | + | |
| 147 | + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) | |
| 148 | + { | |
| 149 | + if (untypedValue == null) | |
| 150 | + { | |
| 151 | + serializer.Serialize(writer, null); | |
| 152 | + return; | |
| 153 | + } | |
| 154 | + var value = (Status)untypedValue; | |
| 155 | + switch (value) | |
| 156 | + { | |
| 157 | + case Status.Ready: | |
| 158 | + serializer.Serialize(writer, "ready"); | |
| 159 | + return; | |
| 160 | + case Status.Done: | |
| 161 | + serializer.Serialize(writer, "done"); | |
| 162 | + return; | |
| 163 | + } | |
| 164 | + throw new Exception("Cannot marshal type Status"); | |
| 165 | + } | |
| 166 | + | |
| 167 | + public static readonly StatusConverter Singleton = new StatusConverter(); | |
| 168 | + } | |
| 169 | +} | |
| 170 | +#pragma warning restore CS8618 | |
| 171 | +#pragma warning restore CS8601 | |
| 172 | +#pragma warning restore CS8602 | |
| 173 | +#pragma warning restore CS8603 | |
| 174 | +#pragma warning restore CS8604 | |
| 175 | +#pragma warning restore CS8625 | |
| 176 | +#pragma warning restore CS8765 |
Aschema-dartdefault / TopLevel.dart+135 −0
| @@ -0,0 +1,135 @@ | ||
| 1 | +// To parse this JSON data, do | |
| 2 | +// | |
| 3 | +// final topLevel = topLevelFromJson(jsonString); | |
| 4 | + | |
| 5 | +import 'dart:convert'; | |
| 6 | + | |
| 7 | +TopLevel topLevelFromJson(String str) => TopLevel.fromJson(json.decode(str)); | |
| 8 | + | |
| 9 | +String topLevelToJson(TopLevel data) => json.encode(data.toJson()); | |
| 10 | + | |
| 11 | +class TopLevel { | |
| 12 | + final String code; | |
| 13 | + final DateTimeClass dateTime; | |
| 14 | + final EnumValuesClass enumValues; | |
| 15 | + final FormatExceptionClass formatException; | |
| 16 | + final RegExpClass regExp; | |
| 17 | + final Status status; | |
| 18 | + final DateTime timestamp; | |
| 19 | + | |
| 20 | + TopLevel({ | |
| 21 | + required this.code, | |
| 22 | + required this.dateTime, | |
| 23 | + required this.enumValues, | |
| 24 | + required this.formatException, | |
| 25 | + required this.regExp, | |
| 26 | + required this.status, | |
| 27 | + required this.timestamp, | |
| 28 | + }); | |
| 29 | + | |
| 30 | + factory TopLevel.fromJson(Map<String, dynamic> json) => TopLevel( | |
| 31 | + code: ((x) => RegExp("^[a-z]+\u0024").hasMatch(x) ? x : throw FormatException("Expected matching string"))(((x) => x.length >= 1 && true ? x : throw FormatException("Expected bounded string"))(json["code"])), | |
| 32 | + dateTime: DateTimeClass.fromJson(json["dateTime"]), | |
| 33 | + enumValues: EnumValuesClass.fromJson(json["enumValues"]), | |
| 34 | + formatException: FormatExceptionClass.fromJson(json["formatException"]), | |
| 35 | + regExp: RegExpClass.fromJson(json["regExp"]), | |
| 36 | + status: statusValues.map[json["status"]]!, | |
| 37 | + timestamp: DateTime.parse(json["timestamp"]), | |
| 38 | + ); | |
| 39 | + | |
| 40 | + Map<String, dynamic> toJson() => { | |
| 41 | + "code": code, | |
| 42 | + "dateTime": dateTime.toJson(), | |
| 43 | + "enumValues": enumValues.toJson(), | |
| 44 | + "formatException": formatException.toJson(), | |
| 45 | + "regExp": regExp.toJson(), | |
| 46 | + "status": statusValues.reverse[status], | |
| 47 | + "timestamp": timestamp.toIso8601String(), | |
| 48 | + }; | |
| 49 | +} | |
| 50 | + | |
| 51 | +class DateTimeClass { | |
| 52 | + final int value; | |
| 53 | + | |
| 54 | + DateTimeClass({ | |
| 55 | + required this.value, | |
| 56 | + }); | |
| 57 | + | |
| 58 | + factory DateTimeClass.fromJson(Map<String, dynamic> json) => DateTimeClass( | |
| 59 | + value: json["value"], | |
| 60 | + ); | |
| 61 | + | |
| 62 | + Map<String, dynamic> toJson() => { | |
| 63 | + "value": value, | |
| 64 | + }; | |
| 65 | +} | |
| 66 | + | |
| 67 | +class EnumValuesClass { | |
| 68 | + final String label; | |
| 69 | + | |
| 70 | + EnumValuesClass({ | |
| 71 | + required this.label, | |
| 72 | + }); | |
| 73 | + | |
| 74 | + factory EnumValuesClass.fromJson(Map<String, dynamic> json) => EnumValuesClass( | |
| 75 | + label: json["label"], | |
| 76 | + ); | |
| 77 | + | |
| 78 | + Map<String, dynamic> toJson() => { | |
| 79 | + "label": label, | |
| 80 | + }; | |
| 81 | +} | |
| 82 | + | |
| 83 | +class FormatExceptionClass { | |
| 84 | + final int count; | |
| 85 | + | |
| 86 | + FormatExceptionClass({ | |
| 87 | + required this.count, | |
| 88 | + }); | |
| 89 | + | |
| 90 | + factory FormatExceptionClass.fromJson(Map<String, dynamic> json) => FormatExceptionClass( | |
| 91 | + count: json["count"], | |
| 92 | + ); | |
| 93 | + | |
| 94 | + Map<String, dynamic> toJson() => { | |
| 95 | + "count": count, | |
| 96 | + }; | |
| 97 | +} | |
| 98 | + | |
| 99 | +class RegExpClass { | |
| 100 | + final bool active; | |
| 101 | + | |
| 102 | + RegExpClass({ | |
| 103 | + required this.active, | |
| 104 | + }); | |
| 105 | + | |
| 106 | + factory RegExpClass.fromJson(Map<String, dynamic> json) => RegExpClass( | |
| 107 | + active: json["active"], | |
| 108 | + ); | |
| 109 | + | |
| 110 | + Map<String, dynamic> toJson() => { | |
| 111 | + "active": active, | |
| 112 | + }; | |
| 113 | +} | |
| 114 | + | |
| 115 | +enum Status { | |
| 116 | + READY, | |
| 117 | + DONE | |
| 118 | +} | |
| 119 | + | |
| 120 | +final statusValues = EnumValues({ | |
| 121 | + "ready": Status.READY, | |
| 122 | + "done": Status.DONE | |
| 123 | +}); | |
| 124 | + | |
| 125 | +class EnumValues<T> { | |
| 126 | + Map<String, T> map; | |
| 127 | + late Map<T, String> reverseMap; | |
| 128 | + | |
| 129 | + EnumValues(this.map); | |
| 130 | + | |
| 131 | + Map<T, String> get reverse { | |
| 132 | + reverseMap = map.map((k, v) => MapEntry(v, k)); | |
| 133 | + return reverseMap; | |
| 134 | + } | |
| 135 | +} |
Aschema-elixirdefault / QuickType.ex+273 −0
| @@ -0,0 +1,273 @@ | ||
| 1 | +# This file was autogenerated using quicktype https://github.com/quicktype/quicktype | |
| 2 | +# | |
| 3 | +# Add Jason to your mix.exs | |
| 4 | +# | |
| 5 | +# Decode a JSON string: TopLevel.from_json(data) | |
| 6 | +# Encode into a JSON string: TopLevel.to_json(struct) | |
| 7 | + | |
| 8 | +defmodule DateTimeClass do | |
| 9 | + @enforce_keys [:value] | |
| 10 | + defstruct [:value] | |
| 11 | + | |
| 12 | + @type t :: %__MODULE__{ | |
| 13 | + value: integer() | |
| 14 | + } | |
| 15 | + | |
| 16 | + def decode_value(value) when is_integer(value), do: value | |
| 17 | + def decode_value(_), do: {:error, "Unexpected type when decoding DateTimeClass.value"} | |
| 18 | + | |
| 19 | + def encode_value(value) when is_integer(value), do: value | |
| 20 | + def encode_value(_), do: {:error, "Unexpected type when encoding DateTimeClass.value"} | |
| 21 | + | |
| 22 | + def from_map(m) do | |
| 23 | + %DateTimeClass{ | |
| 24 | + value: decode_value(m["value"]), | |
| 25 | + } | |
| 26 | + end | |
| 27 | + | |
| 28 | + def from_json(json) do | |
| 29 | + json | |
| 30 | + |> Jason.decode!() | |
| 31 | + |> from_map() | |
| 32 | + end | |
| 33 | + | |
| 34 | + def to_map(struct) do | |
| 35 | + %{ | |
| 36 | + "value" => struct.value, | |
| 37 | + } | |
| 38 | + end | |
| 39 | + | |
| 40 | + def to_json(struct) do | |
| 41 | + struct | |
| 42 | + |> to_map() | |
| 43 | + |> Jason.encode!() | |
| 44 | + end | |
| 45 | +end | |
| 46 | + | |
| 47 | +defmodule EnumValues do | |
| 48 | + @enforce_keys [:label] | |
| 49 | + defstruct [:label] | |
| 50 | + | |
| 51 | + @type t :: %__MODULE__{ | |
| 52 | + label: String.t() | |
| 53 | + } | |
| 54 | + | |
| 55 | + def decode_label(value) when is_binary(value), do: value | |
| 56 | + def decode_label(_), do: {:error, "Unexpected type when decoding EnumValues.label"} | |
| 57 | + | |
| 58 | + def encode_label(value) when is_binary(value), do: value | |
| 59 | + def encode_label(_), do: {:error, "Unexpected type when encoding EnumValues.label"} | |
| 60 | + | |
| 61 | + def from_map(m) do | |
| 62 | + %EnumValues{ | |
| 63 | + label: decode_label(m["label"]), | |
| 64 | + } | |
| 65 | + end | |
| 66 | + | |
| 67 | + def from_json(json) do | |
| 68 | + json | |
| 69 | + |> Jason.decode!() | |
| 70 | + |> from_map() | |
| 71 | + end | |
| 72 | + | |
| 73 | + def to_map(struct) do | |
| 74 | + %{ | |
| 75 | + "label" => struct.label, | |
| 76 | + } | |
| 77 | + end | |
| 78 | + | |
| 79 | + def to_json(struct) do | |
| 80 | + struct | |
| 81 | + |> to_map() | |
| 82 | + |> Jason.encode!() | |
| 83 | + end | |
| 84 | +end | |
| 85 | + | |
| 86 | +defmodule FormatException do | |
| 87 | + @enforce_keys [:count] | |
| 88 | + defstruct [:count] | |
| 89 | + | |
| 90 | + @type t :: %__MODULE__{ | |
| 91 | + count: integer() | |
| 92 | + } | |
| 93 | + | |
| 94 | + def decode_count(value) when is_integer(value), do: value | |
| 95 | + def decode_count(_), do: {:error, "Unexpected type when decoding FormatException.count"} | |
| 96 | + | |
| 97 | + def encode_count(value) when is_integer(value), do: value | |
| 98 | + def encode_count(_), do: {:error, "Unexpected type when encoding FormatException.count"} | |
| 99 | + | |
| 100 | + def from_map(m) do | |
| 101 | + %FormatException{ | |
| 102 | + count: decode_count(m["count"]), | |
| 103 | + } | |
| 104 | + end | |
| 105 | + | |
| 106 | + def from_json(json) do | |
| 107 | + json | |
| 108 | + |> Jason.decode!() | |
| 109 | + |> from_map() | |
| 110 | + end | |
| 111 | + | |
| 112 | + def to_map(struct) do | |
| 113 | + %{ | |
| 114 | + "count" => struct.count, | |
| 115 | + } | |
| 116 | + end | |
| 117 | + | |
| 118 | + def to_json(struct) do | |
| 119 | + struct | |
| 120 | + |> to_map() | |
| 121 | + |> Jason.encode!() | |
| 122 | + end | |
| 123 | +end | |
| 124 | + | |
| 125 | +defmodule RegExp do | |
| 126 | + @enforce_keys [:active] | |
| 127 | + defstruct [:active] | |
| 128 | + | |
| 129 | + @type t :: %__MODULE__{ | |
| 130 | + active: boolean() | |
| 131 | + } | |
| 132 | + | |
| 133 | + def decode_active(value) when is_boolean(value), do: value | |
| 134 | + def decode_active(_), do: {:error, "Unexpected type when decoding RegExp.active"} | |
| 135 | + | |
| 136 | + def encode_active(value) when is_boolean(value), do: value | |
| 137 | + def encode_active(_), do: {:error, "Unexpected type when encoding RegExp.active"} | |
| 138 | + | |
| 139 | + def from_map(m) do | |
| 140 | + %RegExp{ | |
| 141 | + active: decode_active(m["active"]), | |
| 142 | + } | |
| 143 | + end | |
| 144 | + | |
| 145 | + def from_json(json) do | |
| 146 | + json | |
| 147 | + |> Jason.decode!() | |
| 148 | + |> from_map() | |
| 149 | + end | |
| 150 | + | |
| 151 | + def to_map(struct) do | |
| 152 | + %{ | |
| 153 | + "active" => struct.active, | |
| 154 | + } | |
| 155 | + end | |
| 156 | + | |
| 157 | + def to_json(struct) do | |
| 158 | + struct | |
| 159 | + |> to_map() | |
| 160 | + |> Jason.encode!() | |
| 161 | + end | |
| 162 | +end | |
| 163 | + | |
| 164 | +defmodule Status do | |
| 165 | + @valid_enum_members [ | |
| 166 | + :ready, | |
| 167 | + :done, | |
| 168 | + ] | |
| 169 | + | |
| 170 | + def valid_atom?(value), do: value in @valid_enum_members | |
| 171 | + | |
| 172 | + def valid_atom_string?(value) do | |
| 173 | + try do | |
| 174 | + atom = String.to_existing_atom(value) | |
| 175 | + atom in @valid_enum_members | |
| 176 | + rescue | |
| 177 | + ArgumentError -> false | |
| 178 | + end | |
| 179 | + end | |
| 180 | + | |
| 181 | + def encode(value) do | |
| 182 | + if valid_atom?(value) do | |
| 183 | + Atom.to_string(value) | |
| 184 | + else | |
| 185 | + {:error, "Unexpected value when encoding atom: #{inspect(value)}"} | |
| 186 | + end | |
| 187 | + end | |
| 188 | + | |
| 189 | + def decode(value) do | |
| 190 | + if valid_atom_string?(value) do | |
| 191 | + String.to_existing_atom(value) | |
| 192 | + else | |
| 193 | + {:error, "Unexpected value when decoding atom: #{inspect(value)}"} | |
| 194 | + end | |
| 195 | + end | |
| 196 | + | |
| 197 | + def from_json(json) do | |
| 198 | + json | |
| 199 | + |> Jason.decode!() | |
| 200 | + |> decode() | |
| 201 | + end | |
| 202 | + | |
| 203 | + def to_json(data) do | |
| 204 | + data | |
| 205 | + |> encode() | |
| 206 | + |> Jason.encode!() | |
| 207 | + end | |
| 208 | +end | |
| 209 | + | |
| 210 | +defmodule TopLevel do | |
| 211 | + @enforce_keys [:code, :date_time, :enum_values, :format_exception, :reg_exp, :status, :timestamp] | |
| 212 | + defstruct [:code, :date_time, :enum_values, :format_exception, :reg_exp, :status, :timestamp] | |
| 213 | + | |
| 214 | + @type t :: %__MODULE__{ | |
| 215 | + code: String.t(), | |
| 216 | + date_time: DateTimeClass.t(), | |
| 217 | + enum_values: EnumValues.t(), | |
| 218 | + format_exception: FormatException.t(), | |
| 219 | + reg_exp: RegExp.t(), | |
| 220 | + status: Status.t(), | |
| 221 | + timestamp: String.t() | |
| 222 | + } | |
| 223 | + | |
| 224 | + def decode_code(value) when is_binary(value) do | |
| 225 | + if String.length(value) >= 1 and Regex.match?(Regex.compile!("^[a-z]+$"), value), do: value, else: raise(ArgumentError) | |
| 226 | + end | |
| 227 | + def decode_code(_), do: {:error, "Unexpected type when decoding TopLevel.code"} | |
| 228 | + | |
| 229 | + def encode_code(value) when is_binary(value), do: value | |
| 230 | + def encode_code(_), do: {:error, "Unexpected type when encoding TopLevel.code"} | |
| 231 | + | |
| 232 | + def decode_timestamp(value) when is_binary(value), do: value | |
| 233 | + def decode_timestamp(_), do: {:error, "Unexpected type when decoding TopLevel.timestamp"} | |
| 234 | + | |
| 235 | + def encode_timestamp(value) when is_binary(value), do: value | |
| 236 | + def encode_timestamp(_), do: {:error, "Unexpected type when encoding TopLevel.timestamp"} | |
| 237 | + | |
| 238 | + def from_map(m) do | |
| 239 | + %TopLevel{ | |
| 240 | + code: decode_code(m["code"]), | |
| 241 | + date_time: DateTimeClass.from_map(m["dateTime"]), | |
| 242 | + enum_values: EnumValues.from_map(m["enumValues"]), | |
| 243 | + format_exception: FormatException.from_map(m["formatException"]), | |
| 244 | + reg_exp: RegExp.from_map(m["regExp"]), | |
| 245 | + status: Status.decode(m["status"]), | |
| 246 | + timestamp: decode_timestamp(m["timestamp"]), | |
| 247 | + } | |
| 248 | + end | |
| 249 | + | |
| 250 | + def from_json(json) do | |
| 251 | + json | |
| 252 | + |> Jason.decode!() | |
| 253 | + |> from_map() | |
| 254 | + end | |
| 255 | + | |
| 256 | + def to_map(struct) do | |
| 257 | + %{ | |
| 258 | + "code" => struct.code, | |
| 259 | + "dateTime" => DateTimeClass.to_map(struct.date_time), | |
| 260 | + "enumValues" => EnumValues.to_map(struct.enum_values), | |
| 261 | + "formatException" => FormatException.to_map(struct.format_exception), | |
| 262 | + "regExp" => RegExp.to_map(struct.reg_exp), | |
| 263 | + "status" => Status.encode(struct.status), | |
| 264 | + "timestamp" => struct.timestamp, | |
| 265 | + } | |
| 266 | + end | |
| 267 | + | |
| 268 | + def to_json(struct) do | |
| 269 | + struct | |
| 270 | + |> to_map() | |
| 271 | + |> Jason.encode!() | |
| 272 | + end | |
| 273 | +end |
Aschema-elmdefault / QuickType.elm+159 −0
| @@ -0,0 +1,159 @@ | ||
| 1 | +-- To decode the JSON data, add this file to your project, run | |
| 2 | +-- | |
| 3 | +-- elm install NoRedInk/elm-json-decode-pipeline | |
| 4 | +-- | |
| 5 | +-- add these imports | |
| 6 | +-- | |
| 7 | +-- import Json.Decode exposing (decodeString) | |
| 8 | +-- import QuickType exposing (quickType) | |
| 9 | +-- | |
| 10 | +-- and you're off to the races with | |
| 11 | +-- | |
| 12 | +-- decodeString quickType myJsonString | |
| 13 | + | |
| 14 | +module QuickType exposing | |
| 15 | + ( QuickType | |
| 16 | + , quickTypeToString | |
| 17 | + , quickType | |
| 18 | + , DateTime | |
| 19 | + , EnumValues | |
| 20 | + , FormatException | |
| 21 | + , RegExp | |
| 22 | + , Status(..) | |
| 23 | + ) | |
| 24 | + | |
| 25 | +import Json.Decode as Jdec | |
| 26 | +import Json.Decode.Pipeline as Jpipe | |
| 27 | +import Json.Encode as Jenc | |
| 28 | +import Dict exposing (Dict) | |
| 29 | + | |
| 30 | +type alias QuickType = | |
| 31 | + { code : String | |
| 32 | + , dateTime : DateTime | |
| 33 | + , enumValues : EnumValues | |
| 34 | + , formatException : FormatException | |
| 35 | + , regExp : RegExp | |
| 36 | + , status : Status | |
| 37 | + , timestamp : String | |
| 38 | + } | |
| 39 | + | |
| 40 | +type alias DateTime = | |
| 41 | + { value : Int | |
| 42 | + } | |
| 43 | + | |
| 44 | +type alias EnumValues = | |
| 45 | + { label : String | |
| 46 | + } | |
| 47 | + | |
| 48 | +type alias FormatException = | |
| 49 | + { count : Int | |
| 50 | + } | |
| 51 | + | |
| 52 | +type alias RegExp = | |
| 53 | + { active : Bool | |
| 54 | + } | |
| 55 | + | |
| 56 | +type Status | |
| 57 | + = Ready | |
| 58 | + | Done | |
| 59 | + | |
| 60 | +-- decoders and encoders | |
| 61 | +optionalField key decoder fallback = | |
| 62 | + Jdec.dict Jdec.value | |
| 63 | + |> Jdec.andThen (\m -> | |
| 64 | + case Dict.get key m of | |
| 65 | + Nothing -> Jdec.succeed fallback | |
| 66 | + Just x -> Jdec.decodeValue decoder x |> Result.map Jdec.succeed |> Result.withDefault (Jdec.fail ("Invalid " ++ key))) | |
| 67 | + | |
| 68 | +quickTypeToString : QuickType -> String | |
| 69 | +quickTypeToString r = Jenc.encode 0 (encodeQuickType r) | |
| 70 | + | |
| 71 | +quickType : Jdec.Decoder QuickType | |
| 72 | +quickType = | |
| 73 | + Jdec.succeed QuickType | |
| 74 | + |> Jpipe.required "code" (Jdec.andThen (\x -> if String.length x >= 1 && True then Jdec.succeed x else Jdec.fail "String length out of range") Jdec.string) | |
| 75 | + |> Jpipe.required "dateTime" dateTime | |
| 76 | + |> Jpipe.required "enumValues" enumValues | |
| 77 | + |> Jpipe.required "formatException" formatException | |
| 78 | + |> Jpipe.required "regExp" regExp | |
| 79 | + |> Jpipe.required "status" status | |
| 80 | + |> Jpipe.required "timestamp" Jdec.string | |
| 81 | + | |
| 82 | +encodeQuickType : QuickType -> Jenc.Value | |
| 83 | +encodeQuickType x = | |
| 84 | + Jenc.object | |
| 85 | + [ ("code", Jenc.string x.code) | |
| 86 | + , ("dateTime", encodeDateTime x.dateTime) | |
| 87 | + , ("enumValues", encodeEnumValues x.enumValues) | |
| 88 | + , ("formatException", encodeFormatException x.formatException) | |
| 89 | + , ("regExp", encodeRegExp x.regExp) | |
| 90 | + , ("status", encodeStatus x.status) | |
| 91 | + , ("timestamp", Jenc.string x.timestamp) | |
| 92 | + ] | |
| 93 | + | |
| 94 | +dateTime : Jdec.Decoder DateTime | |
| 95 | +dateTime = | |
| 96 | + Jdec.succeed DateTime | |
| 97 | + |> Jpipe.required "value" Jdec.int | |
| 98 | + | |
| 99 | +encodeDateTime : DateTime -> Jenc.Value | |
| 100 | +encodeDateTime x = | |
| 101 | + Jenc.object | |
| 102 | + [ ("value", Jenc.int x.value) | |
| 103 | + ] | |
| 104 | + | |
| 105 | +enumValues : Jdec.Decoder EnumValues | |
| 106 | +enumValues = | |
| 107 | + Jdec.succeed EnumValues | |
| 108 | + |> Jpipe.required "label" Jdec.string | |
| 109 | + | |
| 110 | +encodeEnumValues : EnumValues -> Jenc.Value | |
| 111 | +encodeEnumValues x = | |
| 112 | + Jenc.object | |
| 113 | + [ ("label", Jenc.string x.label) | |
| 114 | + ] | |
| 115 | + | |
| 116 | +formatException : Jdec.Decoder FormatException | |
| 117 | +formatException = | |
| 118 | + Jdec.succeed FormatException | |
| 119 | + |> Jpipe.required "count" Jdec.int | |
| 120 | + | |
| 121 | +encodeFormatException : FormatException -> Jenc.Value | |
| 122 | +encodeFormatException x = | |
| 123 | + Jenc.object | |
| 124 | + [ ("count", Jenc.int x.count) | |
| 125 | + ] | |
| 126 | + | |
| 127 | +regExp : Jdec.Decoder RegExp | |
| 128 | +regExp = | |
| 129 | + Jdec.succeed RegExp | |
| 130 | + |> Jpipe.required "active" Jdec.bool | |
| 131 | + | |
| 132 | +encodeRegExp : RegExp -> Jenc.Value | |
| 133 | +encodeRegExp x = | |
| 134 | + Jenc.object | |
| 135 | + [ ("active", Jenc.bool x.active) | |
| 136 | + ] | |
| 137 | + | |
| 138 | +status : Jdec.Decoder Status | |
| 139 | +status = | |
| 140 | + Jdec.string | |
| 141 | + |> Jdec.andThen (\str -> | |
| 142 | + case str of | |
| 143 | + "ready" -> Jdec.succeed Ready | |
| 144 | + "done" -> Jdec.succeed Done | |
| 145 | + somethingElse -> Jdec.fail <| "Invalid Status: " ++ somethingElse | |
| 146 | + ) | |
| 147 | + | |
| 148 | +encodeStatus : Status -> Jenc.Value | |
| 149 | +encodeStatus x = case x of | |
| 150 | + Ready -> Jenc.string "ready" | |
| 151 | + Done -> Jenc.string "done" | |
| 152 | + | |
| 153 | +--- encoder helpers | |
| 154 | + | |
| 155 | +makeNullableEncoder : (a -> Jenc.Value) -> Maybe a -> Jenc.Value | |
| 156 | +makeNullableEncoder f m = | |
| 157 | + case m of | |
| 158 | + Just x -> f x | |
| 159 | + Nothing -> Jenc.null |
Aschema-flowdefault / TopLevel.js+261 −0
| @@ -0,0 +1,261 @@ | ||
| 1 | +// @flow | |
| 2 | + | |
| 3 | +// To parse this data: | |
| 4 | +// | |
| 5 | +// const Convert = require("./TopLevel"); | |
| 6 | +// | |
| 7 | +// const topLevel = Convert.toTopLevel(json); | |
| 8 | +// | |
| 9 | +// These functions will throw an error if the JSON doesn't | |
| 10 | +// match the expected interface, even if the JSON is valid. | |
| 11 | + | |
| 12 | +export type TopLevel = { | |
| 13 | + code: string; | |
| 14 | + dateTime: DateTime; | |
| 15 | + enumValues: EnumValues; | |
| 16 | + formatException: FormatException; | |
| 17 | + regExp: RegExp; | |
| 18 | + status: Status; | |
| 19 | + timestamp: Date; | |
| 20 | +}; | |
| 21 | + | |
| 22 | +export type DateTime = { | |
| 23 | + value: number; | |
| 24 | + [property: string]: mixed | number; | |
| 25 | +}; | |
| 26 | + | |
| 27 | +export type EnumValues = { | |
| 28 | + label: string; | |
| 29 | + [property: string]: mixed | string; | |
| 30 | +}; | |
| 31 | + | |
| 32 | +export type FormatException = { | |
| 33 | + count: number; | |
| 34 | + [property: string]: mixed | number; | |
| 35 | +}; | |
| 36 | + | |
| 37 | +export type RegExp = { | |
| 38 | + active: boolean; | |
| 39 | + [property: string]: mixed | boolean; | |
| 40 | +}; | |
| 41 | + | |
| 42 | +export type Status = | |
| 43 | + "ready" | |
| 44 | + | "done"; | |
| 45 | + | |
| 46 | +// Converts JSON strings to/from your types | |
| 47 | +// and asserts the results of JSON.parse at runtime | |
| 48 | +function toTopLevel(json: string): TopLevel { | |
| 49 | + return cast(JSON.parse(json), r("TopLevel")); | |
| 50 | +} | |
| 51 | + | |
| 52 | +function topLevelToJson(value: TopLevel): string { | |
| 53 | + return JSON.stringify(uncast(value, r("TopLevel")), null, 2); | |
| 54 | +} | |
| 55 | + | |
| 56 | +function invalidValue(typ: any, val: any, key: any, parent: any = '') { | |
| 57 | + const prettyTyp = prettyTypeName(typ); | |
| 58 | + const parentText = parent ? ` on ${parent}` : ''; | |
| 59 | + const keyText = key ? ` for key "${key}"` : ''; | |
| 60 | + throw Error(`Invalid value${keyText}${parentText}. Expected ${prettyTyp} but got ${JSON.stringify(val)}`); | |
| 61 | +} | |
| 62 | + | |
| 63 | +function prettyTypeName(typ: any): string { | |
| 64 | + if (Array.isArray(typ)) { | |
| 65 | + if (typ.length === 2 && typ[0] === undefined) { | |
| 66 | + return `an optional ${prettyTypeName(typ[1])}`; | |
| 67 | + } else { | |
| 68 | + return `one of [${typ.map(a => { return prettyTypeName(a); }).join(", ")}]`; | |
| 69 | + } | |
| 70 | + } else if (typeof typ === "object" && typ.literal !== undefined) { | |
| 71 | + return typ.literal; | |
| 72 | + } else { | |
| 73 | + return typeof typ; | |
| 74 | + } | |
| 75 | +} | |
| 76 | + | |
| 77 | +function jsonToJSProps(typ: any): any { | |
| 78 | + if (typ.jsonToJS === undefined) { | |
| 79 | + const map: any = {}; | |
| 80 | + typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ }); | |
| 81 | + typ.jsonToJS = map; | |
| 82 | + } | |
| 83 | + return typ.jsonToJS; | |
| 84 | +} | |
| 85 | + | |
| 86 | +function jsToJSONProps(typ: any): any { | |
| 87 | + if (typ.jsToJSON === undefined) { | |
| 88 | + const map: any = {}; | |
| 89 | + typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ }); | |
| 90 | + typ.jsToJSON = map; | |
| 91 | + } | |
| 92 | + return typ.jsToJSON; | |
| 93 | +} | |
| 94 | + | |
| 95 | +function transform(val: any, typ: any, getProps: any, key: any = '', parent: any = ''): any { | |
| 96 | + function transformPrimitive(typ: string, val: any): any { | |
| 97 | + if (typeof typ === typeof val) return val; | |
| 98 | + return invalidValue(typ, val, key, parent); | |
| 99 | + } | |
| 100 | + | |
| 101 | + function transformUnion(typs: any[], val: any): any { | |
| 102 | + // val must validate against one typ in typs | |
| 103 | + const l = typs.length; | |
| 104 | + for (let i = 0; i < l; i++) { | |
| 105 | + const typ = typs[i]; | |
| 106 | + try { | |
| 107 | + return transform(val, typ, getProps); | |
| 108 | + } catch (_) {} | |
| 109 | + } | |
| 110 | + return invalidValue(typs, val, key, parent); | |
| 111 | + } | |
| 112 | + | |
| 113 | + function transformEnum(cases: string[], val: any): any { | |
| 114 | + if (cases.indexOf(val) !== -1) return val; | |
| 115 | + return invalidValue(cases.map(a => { return l(a); }), val, key, parent); | |
| 116 | + } | |
| 117 | + | |
| 118 | + function transformArray(typ: any, val: any): any { | |
| 119 | + // val must be an array with no invalid elements | |
| 120 | + if (!Array.isArray(val)) return invalidValue(l("array"), val, key, parent); | |
| 121 | + | |
| 122 | + return val.map(el => transform(el, typ, getProps)); | |
| 123 | + } | |
| 124 | + | |
| 125 | + function transformDate(val: any): any { | |
| 126 | + if (val === null) { | |
| 127 | + return null; | |
| 128 | + } | |
| 129 | + const d = new Date(val); | |
| 130 | + if (isNaN(d.valueOf())) { | |
| 131 | + return invalidValue(l("Date"), val, key, parent); | |
| 132 | + } | |
| 133 | + return d; | |
| 134 | + } | |
| 135 | + | |
| 136 | + function transformObject(props: { [k: string]: any }, additional: any, val: any): any { | |
| 137 | + if (val === null || typeof val !== "object" || Array.isArray(val)) { | |
| 138 | + return invalidValue(l(ref || "object"), val, key, parent); | |
| 139 | + } | |
| 140 | + const result: any = {}; | |
| 141 | + Object.getOwnPropertyNames(props).forEach(key => { | |
| 142 | + const prop = props[key]; | |
| 143 | + const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined; | |
| 144 | + result[prop.key] = transform(v, prop.typ, getProps, key, ref); | |
| 145 | + }); | |
| 146 | + Object.getOwnPropertyNames(val).forEach(key => { | |
| 147 | + if (!Object.prototype.hasOwnProperty.call(props, key)) { | |
| 148 | + result[key] = transform(val[key], additional, getProps, key, ref); | |
| 149 | + } | |
| 150 | + }); | |
| 151 | + return result; | |
| 152 | + } | |
| 153 | + | |
| 154 | + if (typ === "any") return val; | |
| 155 | + if (typ === null) { | |
| 156 | + if (val === null) return val; | |
| 157 | + return invalidValue(typ, val, key, parent); | |
| 158 | + } | |
| 159 | + if (typ === false) return invalidValue(typ, val, key, parent); | |
| 160 | + let ref: any = undefined; | |
| 161 | + while (typeof typ === "object" && typ.ref !== undefined) { | |
| 162 | + ref = typ.ref; | |
| 163 | + typ = typeMap[typ.ref]; | |
| 164 | + } | |
| 165 | + if (Array.isArray(typ)) return transformEnum(typ, val); | |
| 166 | + if (typeof typ === "object") { | |
| 167 | + return typ.hasOwnProperty("pattern") ? typeof val === "string" && new RegExp(typ.pattern).test(val) ? val : invalidValue(typ, val, key, parent) | |
| 168 | + : typ.hasOwnProperty("string") ? typeof val === "string" && (typ.min === undefined || val.length >= typ.min) && (typ.max === undefined || val.length <= typ.max) ? transform(val, typ.string, getProps, key, parent) : invalidValue(typ, val, key, parent) | |
| 169 | + : typ.hasOwnProperty("number") ? typeof val === "number" && (typ.min === undefined || val >= typ.min) && (typ.max === undefined || val <= typ.max) ? transform(val, typ.number, getProps, key, parent) : invalidValue(typ, val, key, parent) | |
| 170 | + : typ.hasOwnProperty("integer") ? typeof val === "number" && val % 1 === 0 ? val : invalidValue(l("integer"), val, key, parent) | |
| 171 | + : typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val) | |
| 172 | + : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) | |
| 173 | + : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) | |
| 174 | + : invalidValue(typ, val, key, parent); | |
| 175 | + } | |
| 176 | + // Numbers can be parsed by Date but shouldn't be. | |
| 177 | + if (typ === Date && typeof val !== "number") return transformDate(val); | |
| 178 | + return transformPrimitive(typ, val); | |
| 179 | +} | |
| 180 | + | |
| 181 | +function cast<T>(val: any, typ: any): T { | |
| 182 | + return transform(val, typ, jsonToJSProps); | |
| 183 | +} | |
| 184 | + | |
| 185 | +function uncast<T>(val: T, typ: any): any { | |
| 186 | + return transform(val, typ, jsToJSONProps); | |
| 187 | +} | |
| 188 | + | |
| 189 | +function l(typ: any) { | |
| 190 | + return { literal: typ }; | |
| 191 | +} | |
| 192 | + | |
| 193 | +function a(typ: any) { | |
| 194 | + return { arrayItems: typ }; | |
| 195 | +} | |
| 196 | + | |
| 197 | +function i(typ: any) { | |
| 198 | + return { integer: typ }; | |
| 199 | +} | |
| 200 | + | |
| 201 | +function p(pattern: any) { | |
| 202 | + return { pattern }; | |
| 203 | +} | |
| 204 | + | |
| 205 | +function s(typ: any, min: any, max: any) { | |
| 206 | + return { string: typ, min, max }; | |
| 207 | +} | |
| 208 | + | |
| 209 | +function n(typ: any, min: any, max: any) { | |
| 210 | + return { number: typ, min, max }; | |
| 211 | +} | |
| 212 | + | |
| 213 | +function u(...typs: any[]) { | |
| 214 | + return { unionMembers: typs }; | |
| 215 | +} | |
| 216 | + | |
| 217 | +function o(props: any[], additional: any) { | |
| 218 | + return { props, additional }; | |
| 219 | +} | |
| 220 | + | |
| 221 | +function m(additional: any) { | |
| 222 | + const props: any[] = []; | |
| 223 | + return { props, additional }; | |
| 224 | +} | |
| 225 | + | |
| 226 | +function r(name: string) { | |
| 227 | + return { ref: name }; | |
| 228 | +} | |
| 229 | + | |
| 230 | +const typeMap: any = { | |
| 231 | + "TopLevel": o([ | |
| 232 | + { json: "code", js: "code", typ: s(p("^[a-z]+$"), 1, undefined) }, | |
| 233 | + { json: "dateTime", js: "dateTime", typ: r("DateTime") }, | |
| 234 | + { json: "enumValues", js: "enumValues", typ: r("EnumValues") }, | |
| 235 | + { json: "formatException", js: "formatException", typ: r("FormatException") }, | |
| 236 | + { json: "regExp", js: "regExp", typ: r("RegExp") }, | |
| 237 | + { json: "status", js: "status", typ: r("Status") }, | |
| 238 | + { json: "timestamp", js: "timestamp", typ: Date }, | |
| 239 | + ], false), | |
| 240 | + "DateTime": o([ | |
| 241 | + { json: "value", js: "value", typ: i(0) }, | |
| 242 | + ], "any"), | |
| 243 | + "EnumValues": o([ | |
| 244 | + { json: "label", js: "label", typ: "" }, | |
| 245 | + ], "any"), | |
| 246 | + "FormatException": o([ | |
| 247 | + { json: "count", js: "count", typ: i(0) }, | |
| 248 | + ], "any"), | |
| 249 | + "RegExp": o([ | |
| 250 | + { json: "active", js: "active", typ: true }, | |
| 251 | + ], "any"), | |
| 252 | + "Status": [ | |
| 253 | + "ready", | |
| 254 | + "done", | |
| 255 | + ], | |
| 256 | +}; | |
| 257 | + | |
| 258 | +module.exports = { | |
| 259 | + "topLevelToJson": topLevelToJson, | |
| 260 | + "toTopLevel": toTopLevel, | |
| 261 | +}; |
Aschema-golangdefault / quicktype.go+66 −0
| @@ -0,0 +1,66 @@ | ||
| 1 | +// Code generated from JSON Schema using quicktype. DO NOT EDIT. | |
| 2 | +// To parse and unparse this JSON data, add this code to your project and do: | |
| 3 | +// | |
| 4 | +// topLevel, err := UnmarshalTopLevel(bytes) | |
| 5 | +// bytes, err = topLevel.Marshal() | |
| 6 | + | |
| 7 | +package main | |
| 8 | + | |
| 9 | +import "time" | |
| 10 | + | |
| 11 | +import "encoding/json" | |
| 12 | + | |
| 13 | +func UnmarshalTopLevel(data []byte) (TopLevel, error) { | |
| 14 | + var r TopLevel | |
| 15 | + err := json.Unmarshal(data, &r) | |
| 16 | + return r, err | |
| 17 | +} | |
| 18 | + | |
| 19 | +func (r *TopLevel) Marshal() ([]byte, error) { | |
| 20 | + return json.Marshal(r) | |
| 21 | +} | |
| 22 | + | |
| 23 | +type TopLevel struct { | |
| 24 | + Code string `json:"code"` | |
| 25 | + DateTime DateTime `json:"dateTime"` | |
| 26 | + EnumValues EnumValues `json:"enumValues"` | |
| 27 | + FormatException FormatException `json:"formatException"` | |
| 28 | + RegExp RegExp `json:"regExp"` | |
| 29 | + Status Status `json:"status"` | |
| 30 | + Timestamp time.Time `json:"timestamp"` | |
| 31 | +} | |
| 32 | + | |
| 33 | +type DateTime struct { | |
| 34 | + Value int64 `json:"value"` | |
| 35 | +} | |
| 36 | + | |
| 37 | +type EnumValues struct { | |
| 38 | + Label string `json:"label"` | |
| 39 | +} | |
| 40 | + | |
| 41 | +type FormatException struct { | |
| 42 | + Count int64 `json:"count"` | |
| 43 | +} | |
| 44 | + | |
| 45 | +type RegExp struct { | |
| 46 | + Active bool `json:"active"` | |
| 47 | +} | |
| 48 | + | |
| 49 | +type Status string | |
| 50 | + | |
| 51 | +const ( | |
| 52 | + Ready Status = "ready" | |
| 53 | + Done Status = "done" | |
| 54 | +) | |
| 55 | + | |
| 56 | +type invalidStatus string | |
| 57 | +func (x invalidStatus) Error() string { return "invalid Status: " + string(x) } | |
| 58 | + | |
| 59 | +func (x *Status) UnmarshalJSON(data []byte) error { | |
| 60 | + var value string | |
| 61 | + if err := json.Unmarshal(data, &value); err != nil { return err } | |
| 62 | + switch Status(value) { | |
| 63 | + case Ready, Done: *x = Status(value); return nil | |
| 64 | + } | |
| 65 | + return invalidStatus(value) | |
| 66 | +} |
Aschema-haskelldefault / QuickType.hs+124 −0
| @@ -0,0 +1,124 @@ | ||
| 1 | +{-# LANGUAGE StrictData #-} | |
| 2 | +{-# LANGUAGE OverloadedStrings #-} | |
| 3 | + | |
| 4 | +module QuickType | |
| 5 | + ( QuickType (..) | |
| 6 | + , DateTime (..) | |
| 7 | + , EnumValues (..) | |
| 8 | + , FormatException (..) | |
| 9 | + , RegExp (..) | |
| 10 | + , Status (..) | |
| 11 | + , decodeTopLevel | |
| 12 | + ) where | |
| 13 | + | |
| 14 | +import Data.Aeson | |
| 15 | +import Data.Aeson.Types (emptyObject) | |
| 16 | +import Data.ByteString.Lazy (ByteString) | |
| 17 | +import Data.HashMap.Strict (HashMap) | |
| 18 | +import Data.Text (Text) | |
| 19 | + | |
| 20 | +data QuickType = QuickType | |
| 21 | + { codeQuickType :: Text | |
| 22 | + , dateTimeQuickType :: DateTime | |
| 23 | + , enumValuesQuickType :: EnumValues | |
| 24 | + , formatExceptionQuickType :: FormatException | |
| 25 | + , regExpQuickType :: RegExp | |
| 26 | + , statusQuickType :: Status | |
| 27 | + , timestampQuickType :: Text | |
| 28 | + } deriving (Show) | |
| 29 | + | |
| 30 | +data DateTime = DateTime | |
| 31 | + { valueDateTime :: Int | |
| 32 | + } deriving (Show) | |
| 33 | + | |
| 34 | +data EnumValues = EnumValues | |
| 35 | + { labelEnumValues :: Text | |
| 36 | + } deriving (Show) | |
| 37 | + | |
| 38 | +data FormatException = FormatException | |
| 39 | + { countFormatException :: Int | |
| 40 | + } deriving (Show) | |
| 41 | + | |
| 42 | +data RegExp = RegExp | |
| 43 | + { activeRegExp :: Bool | |
| 44 | + } deriving (Show) | |
| 45 | + | |
| 46 | +data Status | |
| 47 | + = ReadyStatus | |
| 48 | + | DoneStatus | |
| 49 | + deriving (Show) | |
| 50 | + | |
| 51 | +decodeTopLevel :: ByteString -> Maybe QuickType | |
| 52 | +decodeTopLevel = decode | |
| 53 | + | |
| 54 | +instance ToJSON QuickType where | |
| 55 | + toJSON (QuickType codeQuickType dateTimeQuickType enumValuesQuickType formatExceptionQuickType regExpQuickType statusQuickType timestampQuickType) = | |
| 56 | + object | |
| 57 | + [ "code" .= codeQuickType | |
| 58 | + , "dateTime" .= dateTimeQuickType | |
| 59 | + , "enumValues" .= enumValuesQuickType | |
| 60 | + , "formatException" .= formatExceptionQuickType | |
| 61 | + , "regExp" .= regExpQuickType | |
| 62 | + , "status" .= statusQuickType | |
| 63 | + , "timestamp" .= timestampQuickType | |
| 64 | + ] | |
| 65 | + | |
| 66 | +instance FromJSON QuickType where | |
| 67 | + parseJSON (Object v) = QuickType | |
| 68 | + <$> v .: "code" | |
| 69 | + <*> v .: "dateTime" | |
| 70 | + <*> v .: "enumValues" | |
| 71 | + <*> v .: "formatException" | |
| 72 | + <*> v .: "regExp" | |
| 73 | + <*> v .: "status" | |
| 74 | + <*> v .: "timestamp" | |
| 75 | + | |
| 76 | +instance ToJSON DateTime where | |
| 77 | + toJSON (DateTime valueDateTime) = | |
| 78 | + object | |
| 79 | + [ "value" .= valueDateTime | |
| 80 | + ] | |
| 81 | + | |
| 82 | +instance FromJSON DateTime where | |
| 83 | + parseJSON (Object v) = DateTime | |
| 84 | + <$> v .: "value" | |
| 85 | + | |
| 86 | +instance ToJSON EnumValues where | |
| 87 | + toJSON (EnumValues labelEnumValues) = | |
| 88 | + object | |
| 89 | + [ "label" .= labelEnumValues | |
| 90 | + ] | |
| 91 | + | |
| 92 | +instance FromJSON EnumValues where | |
| 93 | + parseJSON (Object v) = EnumValues | |
| 94 | + <$> v .: "label" | |
| 95 | + | |
| 96 | +instance ToJSON FormatException where | |
| 97 | + toJSON (FormatException countFormatException) = | |
| 98 | + object | |
| 99 | + [ "count" .= countFormatException | |
| 100 | + ] | |
| 101 | + | |
| 102 | +instance FromJSON FormatException where | |
| 103 | + parseJSON (Object v) = FormatException | |
| 104 | + <$> v .: "count" | |
| 105 | + | |
| 106 | +instance ToJSON RegExp where | |
| 107 | + toJSON (RegExp activeRegExp) = | |
| 108 | + object | |
| 109 | + [ "active" .= activeRegExp | |
| 110 | + ] | |
| 111 | + | |
| 112 | +instance FromJSON RegExp where | |
| 113 | + parseJSON (Object v) = RegExp | |
| 114 | + <$> v .: "active" | |
| 115 | + | |
| 116 | +instance ToJSON Status where | |
| 117 | + toJSON ReadyStatus = "ready" | |
| 118 | + toJSON DoneStatus = "done" | |
| 119 | + | |
| 120 | +instance FromJSON Status where | |
| 121 | + parseJSON = withText "Status" parseText | |
| 122 | + where | |
| 123 | + parseText "ready" = return ReadyStatus | |
| 124 | + parseText "done" = return DoneStatus |
Aschema-java-datetime-legacydefault / src / main / java / io / quicktype / Converter.java+124 −0
| @@ -0,0 +1,124 @@ | ||
| 1 | +// To use this code, add the following Maven dependency to your project: | |
| 2 | +// | |
| 3 | +// | |
| 4 | +// com.fasterxml.jackson.core : jackson-databind : 2.9.0 | |
| 5 | +// | |
| 6 | +// | |
| 7 | +// Import this package: | |
| 8 | +// | |
| 9 | +// import io.quicktype.Converter; | |
| 10 | +// | |
| 11 | +// Then you can deserialize a JSON string with | |
| 12 | +// | |
| 13 | +// TopLevel data = Converter.fromJsonString(jsonString); | |
| 14 | + | |
| 15 | +package io.quicktype; | |
| 16 | + | |
| 17 | +import java.io.IOException; | |
| 18 | +import com.fasterxml.jackson.databind.*; | |
| 19 | +import com.fasterxml.jackson.databind.module.SimpleModule; | |
| 20 | +import com.fasterxml.jackson.core.JsonParser; | |
| 21 | +import com.fasterxml.jackson.core.JsonProcessingException; | |
| 22 | +import com.fasterxml.jackson.core.type.TypeReference; | |
| 23 | +import java.util.*; | |
| 24 | +import java.util.Date; | |
| 25 | +import java.text.SimpleDateFormat; | |
| 26 | + | |
| 27 | +public class Converter { | |
| 28 | + // Date-time helpers | |
| 29 | + | |
| 30 | + private static final String[] DATE_TIME_FORMATS = { | |
| 31 | + "yyyy-MM-dd'T'HH:mm:ss.SX", | |
| 32 | + "yyyy-MM-dd'T'HH:mm:ss.S", | |
| 33 | + "yyyy-MM-dd'T'HH:mm:ssX", | |
| 34 | + "yyyy-MM-dd'T'HH:mm:ss", | |
| 35 | + "yyyy-MM-dd HH:mm:ss.SX", | |
| 36 | + "yyyy-MM-dd HH:mm:ss.S", | |
| 37 | + "yyyy-MM-dd HH:mm:ssX", | |
| 38 | + "yyyy-MM-dd HH:mm:ss", | |
| 39 | + "HH:mm:ss.SZ", | |
| 40 | + "HH:mm:ss.S", | |
| 41 | + "HH:mm:ssZ", | |
| 42 | + "HH:mm:ss", | |
| 43 | + "yyyy-MM-dd", | |
| 44 | + }; | |
| 45 | + | |
| 46 | + public static Date parseAllDateTimeString(String str) { | |
| 47 | + str = str.replaceFirst("(\\.\\d{3})\\d+", "$1"); | |
| 48 | + for (String format : DATE_TIME_FORMATS) { | |
| 49 | + try { | |
| 50 | + return new SimpleDateFormat(format).parse(str); | |
| 51 | + } catch (Exception ex) { | |
| 52 | + // Ignored | |
| 53 | + } | |
| 54 | + } | |
| 55 | + return null; | |
| 56 | + } | |
| 57 | + | |
| 58 | + public static String serializeDateTime(Date datetime) { | |
| 59 | + return new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZ").format(datetime); | |
| 60 | + } | |
| 61 | + | |
| 62 | + public static String serializeDate(Date datetime) { | |
| 63 | + return new SimpleDateFormat("yyyy-MM-dd").format(datetime); | |
| 64 | + } | |
| 65 | + | |
| 66 | + public static String serializeTime(Date datetime) { | |
| 67 | + return new SimpleDateFormat("hh:mm:ssZ").format(datetime); | |
| 68 | + } | |
| 69 | + // Serialize/deserialize helpers | |
| 70 | + | |
| 71 | + public static TopLevel fromJsonString(String json) throws IOException { | |
| 72 | + return getObjectReader().readValue(json); | |
| 73 | + } | |
| 74 | + | |
| 75 | + public static String toJsonString(TopLevel obj) throws JsonProcessingException { | |
| 76 | + return getObjectWriter().writeValueAsString(obj); | |
| 77 | + } | |
| 78 | + | |
| 79 | + private static ObjectReader reader; | |
| 80 | + private static ObjectWriter writer; | |
| 81 | + | |
| 82 | + private static void instantiateMapper() { | |
| 83 | + ObjectMapper mapper = new ObjectMapper(); | |
| 84 | + mapper.findAndRegisterModules(); | |
| 85 | + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); | |
| 86 | + mapper.configure(DeserializationFeature.ACCEPT_FLOAT_AS_INT, false); | |
| 87 | + mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); | |
| 88 | + SimpleModule module = new SimpleModule(); | |
| 89 | + module.addDeserializer(Date.class, new JsonDeserializer<Date>() { | |
| 90 | + @Override | |
| 91 | + public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { | |
| 92 | + String value = jsonParser.getText(); | |
| 93 | + return Converter.parseAllDateTimeString(value); | |
| 94 | + } | |
| 95 | + }); | |
| 96 | + module.addDeserializer(Date.class, new JsonDeserializer<Date>() { | |
| 97 | + @Override | |
| 98 | + public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { | |
| 99 | + String value = jsonParser.getText(); | |
| 100 | + return Converter.parseAllDateTimeString(value); | |
| 101 | + } | |
| 102 | + }); | |
| 103 | + module.addDeserializer(Date.class, new JsonDeserializer<Date>() { | |
| 104 | + @Override | |
| 105 | + public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { | |
| 106 | + String value = jsonParser.getText(); | |
| 107 | + return Converter.parseAllDateTimeString(value); | |
| 108 | + } | |
| 109 | + }); | |
| 110 | + mapper.registerModule(module); | |
| 111 | + reader = mapper.readerFor(TopLevel.class); | |
| 112 | + writer = mapper.writerFor(TopLevel.class); | |
| 113 | + } | |
| 114 | + | |
| 115 | + private static ObjectReader getObjectReader() { | |
| 116 | + if (reader == null) instantiateMapper(); | |
| 117 | + return reader; | |
| 118 | + } | |
| 119 | + | |
| 120 | + private static ObjectWriter getObjectWriter() { | |
| 121 | + if (writer == null) instantiateMapper(); | |
| 122 | + return writer; | |
| 123 | + } | |
| 124 | +} |
Aschema-java-datetime-legacydefault / src / main / java / io / quicktype / DateTime.java+12 −0
| @@ -0,0 +1,12 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class DateTime { | |
| 6 | + private long value; | |
| 7 | + | |
| 8 | + @JsonProperty("value") | |
| 9 | + public long getValue() { return value; } | |
| 10 | + @JsonProperty("value") | |
| 11 | + public void setValue(long value) { this.value = value; } | |
| 12 | +} |
Aschema-java-datetime-legacydefault / src / main / java / io / quicktype / EnumValues.java+12 −0
| @@ -0,0 +1,12 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class EnumValues { | |
| 6 | + private String label; | |
| 7 | + | |
| 8 | + @JsonProperty("label") | |
| 9 | + public String getLabel() { return label; } | |
| 10 | + @JsonProperty("label") | |
| 11 | + public void setLabel(String value) { this.label = value; } | |
| 12 | +} |
Aschema-java-datetime-legacydefault / src / main / java / io / quicktype / FormatException.java+12 −0
| @@ -0,0 +1,12 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class FormatException { | |
| 6 | + private long count; | |
| 7 | + | |
| 8 | + @JsonProperty("count") | |
| 9 | + public long getCount() { return count; } | |
| 10 | + @JsonProperty("count") | |
| 11 | + public void setCount(long value) { this.count = value; } | |
| 12 | +} |
Aschema-java-datetime-legacydefault / src / main / java / io / quicktype / RegExp.java+12 −0
| @@ -0,0 +1,12 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class RegExp { | |
| 6 | + private boolean active; | |
| 7 | + | |
| 8 | + @JsonProperty("active") | |
| 9 | + public boolean getActive() { return active; } | |
| 10 | + @JsonProperty("active") | |
| 11 | + public void setActive(boolean value) { this.active = value; } | |
| 12 | +} |
Aschema-java-datetime-legacydefault / src / main / java / io / quicktype / Status.java+24 −0
| @@ -0,0 +1,24 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import java.io.IOException; | |
| 4 | +import com.fasterxml.jackson.annotation.*; | |
| 5 | + | |
| 6 | +public enum Status { | |
| 7 | + READY, DONE; | |
| 8 | + | |
| 9 | + @JsonValue | |
| 10 | + public String toValue() { | |
| 11 | + switch (this) { | |
| 12 | + case READY: return "ready"; | |
| 13 | + case DONE: return "done"; | |
| 14 | + } | |
| 15 | + return null; | |
| 16 | + } | |
| 17 | + | |
| 18 | + @JsonCreator | |
| 19 | + public static Status forValue(String value) throws IOException { | |
| 20 | + if (value.equals("ready")) return READY; | |
| 21 | + if (value.equals("done")) return DONE; | |
| 22 | + throw new IOException("Cannot deserialize Status"); | |
| 23 | + } | |
| 24 | +} |
Aschema-java-datetime-legacydefault / src / main / java / io / quicktype / TopLevel.java+51 −0
| @@ -0,0 +1,51 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | +import java.util.Date; | |
| 5 | + | |
| 6 | +public class TopLevel { | |
| 7 | + private String code; | |
| 8 | + private DateTime dateTime; | |
| 9 | + private EnumValues enumValues; | |
| 10 | + private FormatException formatException; | |
| 11 | + private RegExp regExp; | |
| 12 | + private Status status; | |
| 13 | + private Date timestamp; | |
| 14 | + | |
| 15 | + @JsonProperty("code") | |
| 16 | + public String getCode() { return code; } | |
| 17 | + @JsonProperty("code") | |
| 18 | + public void setCode(String value) { this.code = value; } | |
| 19 | + | |
| 20 | + @JsonProperty("dateTime") | |
| 21 | + public DateTime getDateTime() { return dateTime; } | |
| 22 | + @JsonProperty("dateTime") | |
| 23 | + public void setDateTime(DateTime value) { this.dateTime = value; } | |
| 24 | + | |
| 25 | + @JsonProperty("enumValues") | |
| 26 | + public EnumValues getEnumValues() { return enumValues; } | |
| 27 | + @JsonProperty("enumValues") | |
| 28 | + public void setEnumValues(EnumValues value) { this.enumValues = value; } | |
| 29 | + | |
| 30 | + @JsonProperty("formatException") | |
| 31 | + public FormatException getFormatException() { return formatException; } | |
| 32 | + @JsonProperty("formatException") | |
| 33 | + public void setFormatException(FormatException value) { this.formatException = value; } | |
| 34 | + | |
| 35 | + @JsonProperty("regExp") | |
| 36 | + public RegExp getRegExp() { return regExp; } | |
| 37 | + @JsonProperty("regExp") | |
| 38 | + public void setRegExp(RegExp value) { this.regExp = value; } | |
| 39 | + | |
| 40 | + @JsonProperty("status") | |
| 41 | + public Status getStatus() { return status; } | |
| 42 | + @JsonProperty("status") | |
| 43 | + public void setStatus(Status value) { this.status = value; } | |
| 44 | + | |
| 45 | + @JsonProperty("timestamp") | |
| 46 | + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX", timezone = "UTC") | |
| 47 | + public Date getTimestamp() { return timestamp; } | |
| 48 | + @JsonProperty("timestamp") | |
| 49 | + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX", timezone = "UTC") | |
| 50 | + public void setTimestamp(Date value) { this.timestamp = value; } | |
| 51 | +} |
Aschema-java-lombokdefault / src / main / java / io / quicktype / Converter.java+103 −0
| @@ -0,0 +1,103 @@ | ||
| 1 | +// To use this code, add the following Maven dependency to your project: | |
| 2 | +// | |
| 3 | +// | |
| 4 | +// com.fasterxml.jackson.core : jackson-databind : 2.9.0 | |
| 5 | +// com.fasterxml.jackson.datatype : jackson-datatype-jsr310 : 2.9.0 | |
| 6 | +// | |
| 7 | +// Import this package: | |
| 8 | +// | |
| 9 | +// import io.quicktype.Converter; | |
| 10 | +// | |
| 11 | +// Then you can deserialize a JSON string with | |
| 12 | +// | |
| 13 | +// TopLevel data = Converter.fromJsonString(jsonString); | |
| 14 | + | |
| 15 | +package io.quicktype; | |
| 16 | + | |
| 17 | +import java.io.IOException; | |
| 18 | +import com.fasterxml.jackson.databind.*; | |
| 19 | +import com.fasterxml.jackson.databind.module.SimpleModule; | |
| 20 | +import com.fasterxml.jackson.core.JsonParser; | |
| 21 | +import com.fasterxml.jackson.core.JsonProcessingException; | |
| 22 | +import com.fasterxml.jackson.core.type.TypeReference; | |
| 23 | +import java.util.*; | |
| 24 | +import java.time.LocalDate; | |
| 25 | +import java.time.OffsetDateTime; | |
| 26 | +import java.time.OffsetTime; | |
| 27 | +import java.time.ZoneOffset; | |
| 28 | +import java.time.ZonedDateTime; | |
| 29 | +import java.time.format.DateTimeFormatter; | |
| 30 | +import java.time.format.DateTimeFormatterBuilder; | |
| 31 | +import java.time.temporal.ChronoField; | |
| 32 | + | |
| 33 | +public class Converter { | |
| 34 | + // Date-time helpers | |
| 35 | + | |
| 36 | + private static final DateTimeFormatter DATE_TIME_FORMATTER = new DateTimeFormatterBuilder() | |
| 37 | + .appendOptional(DateTimeFormatter.ISO_DATE_TIME) | |
| 38 | + .appendOptional(DateTimeFormatter.ISO_OFFSET_DATE_TIME) | |
| 39 | + .appendOptional(DateTimeFormatter.ISO_INSTANT) | |
| 40 | + .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SX")) | |
| 41 | + .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssX")) | |
| 42 | + .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) | |
| 43 | + .toFormatter() | |
| 44 | + .withZone(ZoneOffset.UTC); | |
| 45 | + | |
| 46 | + public static OffsetDateTime parseDateTimeString(String str) { | |
| 47 | + return ZonedDateTime.from(Converter.DATE_TIME_FORMATTER.parse(str)).toOffsetDateTime(); | |
| 48 | + } | |
| 49 | + | |
| 50 | + private static final DateTimeFormatter TIME_FORMATTER = new DateTimeFormatterBuilder() | |
| 51 | + .appendOptional(DateTimeFormatter.ISO_TIME) | |
| 52 | + .appendOptional(DateTimeFormatter.ISO_OFFSET_TIME) | |
| 53 | + .parseDefaulting(ChronoField.YEAR, 2020) | |
| 54 | + .parseDefaulting(ChronoField.MONTH_OF_YEAR, 1) | |
| 55 | + .parseDefaulting(ChronoField.DAY_OF_MONTH, 1) | |
| 56 | + .toFormatter() | |
| 57 | + .withZone(ZoneOffset.UTC); | |
| 58 | + | |
| 59 | + public static OffsetTime parseTimeString(String str) { | |
| 60 | + return ZonedDateTime.from(Converter.TIME_FORMATTER.parse(str)).toOffsetDateTime().toOffsetTime(); | |
| 61 | + } | |
| 62 | + // Serialize/deserialize helpers | |
| 63 | + | |
| 64 | + public static TopLevel fromJsonString(String json) throws IOException { | |
| 65 | + return getObjectReader().readValue(json); | |
| 66 | + } | |
| 67 | + | |
| 68 | + public static String toJsonString(TopLevel obj) throws JsonProcessingException { | |
| 69 | + return getObjectWriter().writeValueAsString(obj); | |
| 70 | + } | |
| 71 | + | |
| 72 | + private static ObjectReader reader; | |
| 73 | + private static ObjectWriter writer; | |
| 74 | + | |
| 75 | + private static void instantiateMapper() { | |
| 76 | + ObjectMapper mapper = new ObjectMapper(); | |
| 77 | + mapper.findAndRegisterModules(); | |
| 78 | + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); | |
| 79 | + mapper.configure(DeserializationFeature.ACCEPT_FLOAT_AS_INT, false); | |
| 80 | + mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); | |
| 81 | + SimpleModule module = new SimpleModule(); | |
| 82 | + module.addDeserializer(OffsetDateTime.class, new JsonDeserializer<OffsetDateTime>() { | |
| 83 | + @Override | |
| 84 | + public OffsetDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { | |
| 85 | + String value = jsonParser.getText(); | |
| 86 | + return Converter.parseDateTimeString(value); | |
| 87 | + } | |
| 88 | + }); | |
| 89 | + mapper.registerModule(module); | |
| 90 | + reader = mapper.readerFor(TopLevel.class); | |
| 91 | + writer = mapper.writerFor(TopLevel.class); | |
| 92 | + } | |
| 93 | + | |
| 94 | + private static ObjectReader getObjectReader() { | |
| 95 | + if (reader == null) instantiateMapper(); | |
| 96 | + return reader; | |
| 97 | + } | |
| 98 | + | |
| 99 | + private static ObjectWriter getObjectWriter() { | |
| 100 | + if (writer == null) instantiateMapper(); | |
| 101 | + return writer; | |
| 102 | + } | |
| 103 | +} |
Aschema-java-lombokdefault / src / main / java / io / quicktype / DateTime.java+12 −0
| @@ -0,0 +1,12 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class DateTime { | |
| 6 | + private long value; | |
| 7 | + | |
| 8 | + @JsonProperty("value") | |
| 9 | + public long getValue() { return value; } | |
| 10 | + @JsonProperty("value") | |
| 11 | + public void setValue(long value) { this.value = value; } | |
| 12 | +} |
Aschema-java-lombokdefault / src / main / java / io / quicktype / EnumValues.java+12 −0
| @@ -0,0 +1,12 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class EnumValues { | |
| 6 | + private String label; | |
| 7 | + | |
| 8 | + @JsonProperty("label") | |
| 9 | + public String getLabel() { return label; } | |
| 10 | + @JsonProperty("label") | |
| 11 | + public void setLabel(String value) { this.label = value; } | |
| 12 | +} |
Aschema-java-lombokdefault / src / main / java / io / quicktype / FormatException.java+12 −0
| @@ -0,0 +1,12 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class FormatException { | |
| 6 | + private long count; | |
| 7 | + | |
| 8 | + @JsonProperty("count") | |
| 9 | + public long getCount() { return count; } | |
| 10 | + @JsonProperty("count") | |
| 11 | + public void setCount(long value) { this.count = value; } | |
| 12 | +} |
Aschema-java-lombokdefault / src / main / java / io / quicktype / RegExp.java+12 −0
| @@ -0,0 +1,12 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class RegExp { | |
| 6 | + private boolean active; | |
| 7 | + | |
| 8 | + @JsonProperty("active") | |
| 9 | + public boolean getActive() { return active; } | |
| 10 | + @JsonProperty("active") | |
| 11 | + public void setActive(boolean value) { this.active = value; } | |
| 12 | +} |
Aschema-java-lombokdefault / src / main / java / io / quicktype / Status.java+24 −0
| @@ -0,0 +1,24 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import java.io.IOException; | |
| 4 | +import com.fasterxml.jackson.annotation.*; | |
| 5 | + | |
| 6 | +public enum Status { | |
| 7 | + READY, DONE; | |
| 8 | + | |
| 9 | + @JsonValue | |
| 10 | + public String toValue() { | |
| 11 | + switch (this) { | |
| 12 | + case READY: return "ready"; | |
| 13 | + case DONE: return "done"; | |
| 14 | + } | |
| 15 | + return null; | |
| 16 | + } | |
| 17 | + | |
| 18 | + @JsonCreator | |
| 19 | + public static Status forValue(String value) throws IOException { | |
| 20 | + if (value.equals("ready")) return READY; | |
| 21 | + if (value.equals("done")) return DONE; | |
| 22 | + throw new IOException("Cannot deserialize Status"); | |
| 23 | + } | |
| 24 | +} |
Aschema-java-lombokdefault / src / main / java / io / quicktype / TopLevel.java+49 −0
| @@ -0,0 +1,49 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | +import java.time.OffsetDateTime; | |
| 5 | + | |
| 6 | +public class TopLevel { | |
| 7 | + private String code; | |
| 8 | + private DateTime dateTime; | |
| 9 | + private EnumValues enumValues; | |
| 10 | + private FormatException formatException; | |
| 11 | + private RegExp regExp; | |
| 12 | + private Status status; | |
| 13 | + private OffsetDateTime timestamp; | |
| 14 | + | |
| 15 | + @JsonProperty("code") | |
| 16 | + public String getCode() { return code; } | |
| 17 | + @JsonProperty("code") | |
| 18 | + public void setCode(String value) { this.code = value; } | |
| 19 | + | |
| 20 | + @JsonProperty("dateTime") | |
| 21 | + public DateTime getDateTime() { return dateTime; } | |
| 22 | + @JsonProperty("dateTime") | |
| 23 | + public void setDateTime(DateTime value) { this.dateTime = value; } | |
| 24 | + | |
| 25 | + @JsonProperty("enumValues") | |
| 26 | + public EnumValues getEnumValues() { return enumValues; } | |
| 27 | + @JsonProperty("enumValues") | |
| 28 | + public void setEnumValues(EnumValues value) { this.enumValues = value; } | |
| 29 | + | |
| 30 | + @JsonProperty("formatException") | |
| 31 | + public FormatException getFormatException() { return formatException; } | |
| 32 | + @JsonProperty("formatException") | |
| 33 | + public void setFormatException(FormatException value) { this.formatException = value; } | |
| 34 | + | |
| 35 | + @JsonProperty("regExp") | |
| 36 | + public RegExp getRegExp() { return regExp; } | |
| 37 | + @JsonProperty("regExp") | |
| 38 | + public void setRegExp(RegExp value) { this.regExp = value; } | |
| 39 | + | |
| 40 | + @JsonProperty("status") | |
| 41 | + public Status getStatus() { return status; } | |
| 42 | + @JsonProperty("status") | |
| 43 | + public void setStatus(Status value) { this.status = value; } | |
| 44 | + | |
| 45 | + @JsonProperty("timestamp") | |
| 46 | + public OffsetDateTime getTimestamp() { return timestamp; } | |
| 47 | + @JsonProperty("timestamp") | |
| 48 | + public void setTimestamp(OffsetDateTime value) { this.timestamp = value; } | |
| 49 | +} |
Aschema-javadefault / src / main / java / io / quicktype / Converter.java+103 −0
| @@ -0,0 +1,103 @@ | ||
| 1 | +// To use this code, add the following Maven dependency to your project: | |
| 2 | +// | |
| 3 | +// | |
| 4 | +// com.fasterxml.jackson.core : jackson-databind : 2.9.0 | |
| 5 | +// com.fasterxml.jackson.datatype : jackson-datatype-jsr310 : 2.9.0 | |
| 6 | +// | |
| 7 | +// Import this package: | |
| 8 | +// | |
| 9 | +// import io.quicktype.Converter; | |
| 10 | +// | |
| 11 | +// Then you can deserialize a JSON string with | |
| 12 | +// | |
| 13 | +// TopLevel data = Converter.fromJsonString(jsonString); | |
| 14 | + | |
| 15 | +package io.quicktype; | |
| 16 | + | |
| 17 | +import java.io.IOException; | |
| 18 | +import com.fasterxml.jackson.databind.*; | |
| 19 | +import com.fasterxml.jackson.databind.module.SimpleModule; | |
| 20 | +import com.fasterxml.jackson.core.JsonParser; | |
| 21 | +import com.fasterxml.jackson.core.JsonProcessingException; | |
| 22 | +import com.fasterxml.jackson.core.type.TypeReference; | |
| 23 | +import java.util.*; | |
| 24 | +import java.time.LocalDate; | |
| 25 | +import java.time.OffsetDateTime; | |
| 26 | +import java.time.OffsetTime; | |
| 27 | +import java.time.ZoneOffset; | |
| 28 | +import java.time.ZonedDateTime; | |
| 29 | +import java.time.format.DateTimeFormatter; | |
| 30 | +import java.time.format.DateTimeFormatterBuilder; | |
| 31 | +import java.time.temporal.ChronoField; | |
| 32 | + | |
| 33 | +public class Converter { | |
| 34 | + // Date-time helpers | |
| 35 | + | |
| 36 | + private static final DateTimeFormatter DATE_TIME_FORMATTER = new DateTimeFormatterBuilder() | |
| 37 | + .appendOptional(DateTimeFormatter.ISO_DATE_TIME) | |
| 38 | + .appendOptional(DateTimeFormatter.ISO_OFFSET_DATE_TIME) | |
| 39 | + .appendOptional(DateTimeFormatter.ISO_INSTANT) | |
| 40 | + .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SX")) | |
| 41 | + .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssX")) | |
| 42 | + .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) | |
| 43 | + .toFormatter() | |
| 44 | + .withZone(ZoneOffset.UTC); | |
| 45 | + | |
| 46 | + public static OffsetDateTime parseDateTimeString(String str) { | |
| 47 | + return ZonedDateTime.from(Converter.DATE_TIME_FORMATTER.parse(str)).toOffsetDateTime(); | |
| 48 | + } | |
| 49 | + | |
| 50 | + private static final DateTimeFormatter TIME_FORMATTER = new DateTimeFormatterBuilder() | |
| 51 | + .appendOptional(DateTimeFormatter.ISO_TIME) | |
| 52 | + .appendOptional(DateTimeFormatter.ISO_OFFSET_TIME) | |
| 53 | + .parseDefaulting(ChronoField.YEAR, 2020) | |
| 54 | + .parseDefaulting(ChronoField.MONTH_OF_YEAR, 1) | |
| 55 | + .parseDefaulting(ChronoField.DAY_OF_MONTH, 1) | |
| 56 | + .toFormatter() | |
| 57 | + .withZone(ZoneOffset.UTC); | |
| 58 | + | |
| 59 | + public static OffsetTime parseTimeString(String str) { | |
| 60 | + return ZonedDateTime.from(Converter.TIME_FORMATTER.parse(str)).toOffsetDateTime().toOffsetTime(); | |
| 61 | + } | |
| 62 | + // Serialize/deserialize helpers | |
| 63 | + | |
| 64 | + public static TopLevel fromJsonString(String json) throws IOException { | |
| 65 | + return getObjectReader().readValue(json); | |
| 66 | + } | |
| 67 | + | |
| 68 | + public static String toJsonString(TopLevel obj) throws JsonProcessingException { | |
| 69 | + return getObjectWriter().writeValueAsString(obj); | |
| 70 | + } | |
| 71 | + | |
| 72 | + private static ObjectReader reader; | |
| 73 | + private static ObjectWriter writer; | |
| 74 | + | |
| 75 | + private static void instantiateMapper() { | |
| 76 | + ObjectMapper mapper = new ObjectMapper(); | |
| 77 | + mapper.findAndRegisterModules(); | |
| 78 | + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); | |
| 79 | + mapper.configure(DeserializationFeature.ACCEPT_FLOAT_AS_INT, false); | |
| 80 | + mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); | |
| 81 | + SimpleModule module = new SimpleModule(); | |
| 82 | + module.addDeserializer(OffsetDateTime.class, new JsonDeserializer<OffsetDateTime>() { | |
| 83 | + @Override | |
| 84 | + public OffsetDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { | |
| 85 | + String value = jsonParser.getText(); | |
| 86 | + return Converter.parseDateTimeString(value); | |
| 87 | + } | |
| 88 | + }); | |
| 89 | + mapper.registerModule(module); | |
| 90 | + reader = mapper.readerFor(TopLevel.class); | |
| 91 | + writer = mapper.writerFor(TopLevel.class); | |
| 92 | + } | |
| 93 | + | |
| 94 | + private static ObjectReader getObjectReader() { | |
| 95 | + if (reader == null) instantiateMapper(); | |
| 96 | + return reader; | |
| 97 | + } | |
| 98 | + | |
| 99 | + private static ObjectWriter getObjectWriter() { | |
| 100 | + if (writer == null) instantiateMapper(); | |
| 101 | + return writer; | |
| 102 | + } | |
| 103 | +} |
Aschema-javadefault / src / main / java / io / quicktype / DateTime.java+12 −0
| @@ -0,0 +1,12 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class DateTime { | |
| 6 | + private long value; | |
| 7 | + | |
| 8 | + @JsonProperty("value") | |
| 9 | + public long getValue() { return value; } | |
| 10 | + @JsonProperty("value") | |
| 11 | + public void setValue(long value) { this.value = value; } | |
| 12 | +} |
Aschema-javadefault / src / main / java / io / quicktype / EnumValues.java+12 −0
| @@ -0,0 +1,12 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class EnumValues { | |
| 6 | + private String label; | |
| 7 | + | |
| 8 | + @JsonProperty("label") | |
| 9 | + public String getLabel() { return label; } | |
| 10 | + @JsonProperty("label") | |
| 11 | + public void setLabel(String value) { this.label = value; } | |
| 12 | +} |
Aschema-javadefault / src / main / java / io / quicktype / FormatException.java+12 −0
| @@ -0,0 +1,12 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class FormatException { | |
| 6 | + private long count; | |
| 7 | + | |
| 8 | + @JsonProperty("count") | |
| 9 | + public long getCount() { return count; } | |
| 10 | + @JsonProperty("count") | |
| 11 | + public void setCount(long value) { this.count = value; } | |
| 12 | +} |
Aschema-javadefault / src / main / java / io / quicktype / RegExp.java+12 −0
| @@ -0,0 +1,12 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class RegExp { | |
| 6 | + private boolean active; | |
| 7 | + | |
| 8 | + @JsonProperty("active") | |
| 9 | + public boolean getActive() { return active; } | |
| 10 | + @JsonProperty("active") | |
| 11 | + public void setActive(boolean value) { this.active = value; } | |
| 12 | +} |
Aschema-javadefault / src / main / java / io / quicktype / Status.java+24 −0
| @@ -0,0 +1,24 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import java.io.IOException; | |
| 4 | +import com.fasterxml.jackson.annotation.*; | |
| 5 | + | |
| 6 | +public enum Status { | |
| 7 | + READY, DONE; | |
| 8 | + | |
| 9 | + @JsonValue | |
| 10 | + public String toValue() { | |
| 11 | + switch (this) { | |
| 12 | + case READY: return "ready"; | |
| 13 | + case DONE: return "done"; | |
| 14 | + } | |
| 15 | + return null; | |
| 16 | + } | |
| 17 | + | |
| 18 | + @JsonCreator | |
| 19 | + public static Status forValue(String value) throws IOException { | |
| 20 | + if (value.equals("ready")) return READY; | |
| 21 | + if (value.equals("done")) return DONE; | |
| 22 | + throw new IOException("Cannot deserialize Status"); | |
| 23 | + } | |
| 24 | +} |
Aschema-javadefault / src / main / java / io / quicktype / TopLevel.java+49 −0
| @@ -0,0 +1,49 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | +import java.time.OffsetDateTime; | |
| 5 | + | |
| 6 | +public class TopLevel { | |
| 7 | + private String code; | |
| 8 | + private DateTime dateTime; | |
| 9 | + private EnumValues enumValues; | |
| 10 | + private FormatException formatException; | |
| 11 | + private RegExp regExp; | |
| 12 | + private Status status; | |
| 13 | + private OffsetDateTime timestamp; | |
| 14 | + | |
| 15 | + @JsonProperty("code") | |
| 16 | + public String getCode() { return code; } | |
| 17 | + @JsonProperty("code") | |
| 18 | + public void setCode(String value) { this.code = value; } | |
| 19 | + | |
| 20 | + @JsonProperty("dateTime") | |
| 21 | + public DateTime getDateTime() { return dateTime; } | |
| 22 | + @JsonProperty("dateTime") | |
| 23 | + public void setDateTime(DateTime value) { this.dateTime = value; } | |
| 24 | + | |
| 25 | + @JsonProperty("enumValues") | |
| 26 | + public EnumValues getEnumValues() { return enumValues; } | |
| 27 | + @JsonProperty("enumValues") | |
| 28 | + public void setEnumValues(EnumValues value) { this.enumValues = value; } | |
| 29 | + | |
| 30 | + @JsonProperty("formatException") | |
| 31 | + public FormatException getFormatException() { return formatException; } | |
| 32 | + @JsonProperty("formatException") | |
| 33 | + public void setFormatException(FormatException value) { this.formatException = value; } | |
| 34 | + | |
| 35 | + @JsonProperty("regExp") | |
| 36 | + public RegExp getRegExp() { return regExp; } | |
| 37 | + @JsonProperty("regExp") | |
| 38 | + public void setRegExp(RegExp value) { this.regExp = value; } | |
| 39 | + | |
| 40 | + @JsonProperty("status") | |
| 41 | + public Status getStatus() { return status; } | |
| 42 | + @JsonProperty("status") | |
| 43 | + public void setStatus(Status value) { this.status = value; } | |
| 44 | + | |
| 45 | + @JsonProperty("timestamp") | |
| 46 | + public OffsetDateTime getTimestamp() { return timestamp; } | |
| 47 | + @JsonProperty("timestamp") | |
| 48 | + public void setTimestamp(OffsetDateTime value) { this.timestamp = value; } | |
| 49 | +} |
Aschema-javascript-prop-typesdefault / toplevel.js+44 −0
| @@ -0,0 +1,44 @@ | ||
| 1 | +// Example usage: | |
| 2 | +// | |
| 3 | +// import { MyShape } from ./myShape.js; | |
| 4 | +// | |
| 5 | +// class MyComponent extends React.Component { | |
| 6 | +// // | |
| 7 | +// } | |
| 8 | +// | |
| 9 | +// MyComponent.propTypes = { | |
| 10 | +// input: MyShape | |
| 11 | +// }; | |
| 12 | + | |
| 13 | +import PropTypes from "prop-types"; | |
| 14 | +const Integer = (props, name) => props[name] == null || Number.isInteger(props[name]) ? null : new Error("Expected integer"); | |
| 15 | + | |
| 16 | +let _TopLevel; | |
| 17 | +let _DateTime; | |
| 18 | +let _EnumValues; | |
| 19 | +let _FormatException; | |
| 20 | +let _RegExp; | |
| 21 | +const _Status = PropTypes.oneOf(['ready', 'done']); | |
| 22 | +_DateTime = PropTypes.shape({ | |
| 23 | + "value": PropTypes.oneOfType([Integer]).isRequired, | |
| 24 | +}); | |
| 25 | +_EnumValues = PropTypes.shape({ | |
| 26 | + "label": PropTypes.oneOfType([PropTypes.string]).isRequired, | |
| 27 | +}); | |
| 28 | +_FormatException = PropTypes.shape({ | |
| 29 | + "count": PropTypes.oneOfType([Integer]).isRequired, | |
| 30 | +}); | |
| 31 | +_RegExp = PropTypes.shape({ | |
| 32 | + "active": PropTypes.oneOfType([PropTypes.bool]).isRequired, | |
| 33 | +}); | |
| 34 | +_TopLevel = PropTypes.shape({ | |
| 35 | + "code": PropTypes.oneOfType([(props, name) => { const value = props[name]; return value == null || (typeof value === 'string' && value.length >= 1 && new RegExp("^[a-z]+$").test(value)) ? null : new Error("Expected bounded string"); }]).isRequired, | |
| 36 | + "dateTime": _DateTime, | |
| 37 | + "enumValues": _EnumValues, | |
| 38 | + "formatException": _FormatException, | |
| 39 | + "regExp": _RegExp, | |
| 40 | + "status": _Status, | |
| 41 | + "timestamp": PropTypes.oneOfType([(props, name) => props[name] == null || !Number.isNaN(Date.parse(props[name])) ? null : new Error("Expected date-time")]).isRequired, | |
| 42 | +}); | |
| 43 | + | |
| 44 | +export const TopLevel = _TopLevel; |
Aschema-javascriptdefault / TopLevel.js+225 −0
| @@ -0,0 +1,225 @@ | ||
| 1 | +// To parse this data: | |
| 2 | +// | |
| 3 | +// const Convert = require("./TopLevel"); | |
| 4 | +// | |
| 5 | +// const topLevel = Convert.toTopLevel(json); | |
| 6 | +// | |
| 7 | +// These functions will throw an error if the JSON doesn't | |
| 8 | +// match the expected interface, even if the JSON is valid. | |
| 9 | + | |
| 10 | +// Converts JSON strings to/from your types | |
| 11 | +// and asserts the results of JSON.parse at runtime | |
| 12 | +function toTopLevel(json) { | |
| 13 | + return cast(JSON.parse(json), r("TopLevel")); | |
| 14 | +} | |
| 15 | + | |
| 16 | +function topLevelToJson(value) { | |
| 17 | + return JSON.stringify(uncast(value, r("TopLevel")), null, 2); | |
| 18 | +} | |
| 19 | + | |
| 20 | +function invalidValue(typ, val, key, parent = '') { | |
| 21 | + const prettyTyp = prettyTypeName(typ); | |
| 22 | + const parentText = parent ? ` on ${parent}` : ''; | |
| 23 | + const keyText = key ? ` for key "${key}"` : ''; | |
| 24 | + throw Error(`Invalid value${keyText}${parentText}. Expected ${prettyTyp} but got ${JSON.stringify(val)}`); | |
| 25 | +} | |
| 26 | + | |
| 27 | +function prettyTypeName(typ) { | |
| 28 | + if (Array.isArray(typ)) { | |
| 29 | + if (typ.length === 2 && typ[0] === undefined) { | |
| 30 | + return `an optional ${prettyTypeName(typ[1])}`; | |
| 31 | + } else { | |
| 32 | + return `one of [${typ.map(a => { return prettyTypeName(a); }).join(", ")}]`; | |
| 33 | + } | |
| 34 | + } else if (typeof typ === "object" && typ.literal !== undefined) { | |
| 35 | + return typ.literal; | |
| 36 | + } else { | |
| 37 | + return typeof typ; | |
| 38 | + } | |
| 39 | +} | |
| 40 | + | |
| 41 | +function jsonToJSProps(typ) { | |
| 42 | + if (typ.jsonToJS === undefined) { | |
| 43 | + const map = {}; | |
| 44 | + typ.props.forEach((p) => map[p.json] = { key: p.js, typ: p.typ }); | |
| 45 | + typ.jsonToJS = map; | |
| 46 | + } | |
| 47 | + return typ.jsonToJS; | |
| 48 | +} | |
| 49 | + | |
| 50 | +function jsToJSONProps(typ) { | |
| 51 | + if (typ.jsToJSON === undefined) { | |
| 52 | + const map = {}; | |
| 53 | + typ.props.forEach((p) => map[p.js] = { key: p.json, typ: p.typ }); | |
| 54 | + typ.jsToJSON = map; | |
| 55 | + } | |
| 56 | + return typ.jsToJSON; | |
| 57 | +} | |
| 58 | + | |
| 59 | +function transform(val, typ, getProps, key = '', parent = '') { | |
| 60 | + function transformPrimitive(typ, val) { | |
| 61 | + if (typeof typ === typeof val) return val; | |
| 62 | + return invalidValue(typ, val, key, parent); | |
| 63 | + } | |
| 64 | + | |
| 65 | + function transformUnion(typs, val) { | |
| 66 | + // val must validate against one typ in typs | |
| 67 | + const l = typs.length; | |
| 68 | + for (let i = 0; i < l; i++) { | |
| 69 | + const typ = typs[i]; | |
| 70 | + try { | |
| 71 | + return transform(val, typ, getProps); | |
| 72 | + } catch (_) {} | |
| 73 | + } | |
| 74 | + return invalidValue(typs, val, key, parent); | |
| 75 | + } | |
| 76 | + | |
| 77 | + function transformEnum(cases, val) { | |
| 78 | + if (cases.indexOf(val) !== -1) return val; | |
| 79 | + return invalidValue(cases.map(a => { return l(a); }), val, key, parent); | |
| 80 | + } | |
| 81 | + | |
| 82 | + function transformArray(typ, val) { | |
| 83 | + // val must be an array with no invalid elements | |
| 84 | + if (!Array.isArray(val)) return invalidValue(l("array"), val, key, parent); | |
| 85 | + | |
| 86 | + return val.map(el => transform(el, typ, getProps)); | |
| 87 | + } | |
| 88 | + | |
| 89 | + function transformDate(val) { | |
| 90 | + if (val === null) { | |
| 91 | + return null; | |
| 92 | + } | |
| 93 | + const d = new Date(val); | |
| 94 | + if (isNaN(d.valueOf())) { | |
| 95 | + return invalidValue(l("Date"), val, key, parent); | |
| 96 | + } | |
| 97 | + return d; | |
| 98 | + } | |
| 99 | + | |
| 100 | + function transformObject(props, additional, val) { | |
| 101 | + if (val === null || typeof val !== "object" || Array.isArray(val)) { | |
| 102 | + return invalidValue(l(ref || "object"), val, key, parent); | |
| 103 | + } | |
| 104 | + const result = {}; | |
| 105 | + Object.getOwnPropertyNames(props).forEach(key => { | |
| 106 | + const prop = props[key]; | |
| 107 | + const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined; | |
| 108 | + result[prop.key] = transform(v, prop.typ, getProps, key, ref); | |
| 109 | + }); | |
| 110 | + Object.getOwnPropertyNames(val).forEach(key => { | |
| 111 | + if (!Object.prototype.hasOwnProperty.call(props, key)) { | |
| 112 | + result[key] = transform(val[key], additional, getProps, key, ref); | |
| 113 | + } | |
| 114 | + }); | |
| 115 | + return result; | |
| 116 | + } | |
| 117 | + | |
| 118 | + if (typ === "any") return val; | |
| 119 | + if (typ === null) { | |
| 120 | + if (val === null) return val; | |
| 121 | + return invalidValue(typ, val, key, parent); | |
| 122 | + } | |
| 123 | + if (typ === false) return invalidValue(typ, val, key, parent); | |
| 124 | + let ref = undefined; | |
| 125 | + while (typeof typ === "object" && typ.ref !== undefined) { | |
| 126 | + ref = typ.ref; | |
| 127 | + typ = typeMap[typ.ref]; | |
| 128 | + } | |
| 129 | + if (Array.isArray(typ)) return transformEnum(typ, val); | |
| 130 | + if (typeof typ === "object") { | |
| 131 | + return typ.hasOwnProperty("pattern") ? typeof val === "string" && new RegExp(typ.pattern).test(val) ? val : invalidValue(typ, val, key, parent) | |
| 132 | + : typ.hasOwnProperty("string") ? typeof val === "string" && (typ.min === undefined || val.length >= typ.min) && (typ.max === undefined || val.length <= typ.max) ? transform(val, typ.string, getProps, key, parent) : invalidValue(typ, val, key, parent) | |
| 133 | + : typ.hasOwnProperty("number") ? typeof val === "number" && (typ.min === undefined || val >= typ.min) && (typ.max === undefined || val <= typ.max) ? transform(val, typ.number, getProps, key, parent) : invalidValue(typ, val, key, parent) | |
| 134 | + : typ.hasOwnProperty("integer") ? typeof val === "number" && val % 1 === 0 ? val : invalidValue(l("integer"), val, key, parent) | |
| 135 | + : typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val) | |
| 136 | + : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) | |
| 137 | + : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) | |
| 138 | + : invalidValue(typ, val, key, parent); | |
| 139 | + } | |
| 140 | + // Numbers can be parsed by Date but shouldn't be. | |
| 141 | + if (typ === Date && typeof val !== "number") return transformDate(val); | |
| 142 | + return transformPrimitive(typ, val); | |
| 143 | +} | |
| 144 | + | |
| 145 | +function cast(val, typ) { | |
| 146 | + return transform(val, typ, jsonToJSProps); | |
| 147 | +} | |
| 148 | + | |
| 149 | +function uncast(val, typ) { | |
| 150 | + return transform(val, typ, jsToJSONProps); | |
| 151 | +} | |
| 152 | + | |
| 153 | +function l(typ) { | |
| 154 | + return { literal: typ }; | |
| 155 | +} | |
| 156 | + | |
| 157 | +function a(typ) { | |
| 158 | + return { arrayItems: typ }; | |
| 159 | +} | |
| 160 | + | |
| 161 | +function i(typ) { | |
| 162 | + return { integer: typ }; | |
| 163 | +} | |
| 164 | + | |
| 165 | +function p(pattern) { | |
| 166 | + return { pattern }; | |
| 167 | +} | |
| 168 | + | |
| 169 | +function s(typ, min, max) { | |
| 170 | + return { string: typ, min, max }; | |
| 171 | +} | |
| 172 | + | |
| 173 | +function n(typ, min, max) { | |
| 174 | + return { number: typ, min, max }; | |
| 175 | +} | |
| 176 | + | |
| 177 | +function u(...typs) { | |
| 178 | + return { unionMembers: typs }; | |
| 179 | +} | |
| 180 | + | |
| 181 | +function o(props, additional) { | |
| 182 | + return { props, additional }; | |
| 183 | +} | |
| 184 | + | |
| 185 | +function m(additional) { | |
| 186 | + const props = []; | |
| 187 | + return { props, additional }; | |
| 188 | +} | |
| 189 | + | |
| 190 | +function r(name) { | |
| 191 | + return { ref: name }; | |
| 192 | +} | |
| 193 | + | |
| 194 | +const typeMap = { | |
| 195 | + "TopLevel": o([ | |
| 196 | + { json: "code", js: "code", typ: s(p("^[a-z]+$"), 1, undefined) }, | |
| 197 | + { json: "dateTime", js: "dateTime", typ: r("DateTime") }, | |
| 198 | + { json: "enumValues", js: "enumValues", typ: r("EnumValues") }, | |
| 199 | + { json: "formatException", js: "formatException", typ: r("FormatException") }, | |
| 200 | + { json: "regExp", js: "regExp", typ: r("RegExp") }, | |
| 201 | + { json: "status", js: "status", typ: r("Status") }, | |
| 202 | + { json: "timestamp", js: "timestamp", typ: Date }, | |
| 203 | + ], false), | |
| 204 | + "DateTime": o([ | |
| 205 | + { json: "value", js: "value", typ: i(0) }, | |
| 206 | + ], "any"), | |
| 207 | + "EnumValues": o([ | |
| 208 | + { json: "label", js: "label", typ: "" }, | |
| 209 | + ], "any"), | |
| 210 | + "FormatException": o([ | |
| 211 | + { json: "count", js: "count", typ: i(0) }, | |
| 212 | + ], "any"), | |
| 213 | + "RegExp": o([ | |
| 214 | + { json: "active", js: "active", typ: true }, | |
| 215 | + ], "any"), | |
| 216 | + "Status": [ | |
| 217 | + "ready", | |
| 218 | + "done", | |
| 219 | + ], | |
| 220 | +}; | |
| 221 | + | |
| 222 | +module.exports = { | |
| 223 | + "topLevelToJson": topLevelToJson, | |
| 224 | + "toTopLevel": toTopLevel, | |
| 225 | +}; |
Aschema-kotlin-jacksondefault / TopLevel.kt+101 −0
| @@ -0,0 +1,101 @@ | ||
| 1 | +// To parse the JSON, install jackson-module-kotlin and do: | |
| 2 | +// | |
| 3 | +// val topLevel = TopLevel.fromJson(jsonString) | |
| 4 | + | |
| 5 | +package quicktype | |
| 6 | + | |
| 7 | +import java.time.OffsetDateTime | |
| 8 | + | |
| 9 | +import com.fasterxml.jackson.annotation.* | |
| 10 | +import com.fasterxml.jackson.core.* | |
| 11 | +import com.fasterxml.jackson.databind.* | |
| 12 | +import com.fasterxml.jackson.databind.deser.std.StdDeserializer | |
| 13 | +import com.fasterxml.jackson.databind.module.SimpleModule | |
| 14 | +import com.fasterxml.jackson.databind.node.* | |
| 15 | +import com.fasterxml.jackson.databind.ser.std.StdSerializer | |
| 16 | +import com.fasterxml.jackson.module.kotlin.* | |
| 17 | + | |
| 18 | + | |
| 19 | +@Suppress("UNCHECKED_CAST") | |
| 20 | +private fun <T> ObjectMapper.convert(k: kotlin.reflect.KClass<*>, fromJson: (JsonNode) -> T, toJson: (T) -> String, isUnion: Boolean = false) = registerModule(SimpleModule().apply { | |
| 21 | + addSerializer(k.java as Class<T>, object : StdSerializer<T>(k.java as Class<T>) { | |
| 22 | + override fun serialize(value: T, gen: JsonGenerator, provider: SerializerProvider) = gen.writeRawValue(toJson(value)) | |
| 23 | + }) | |
| 24 | + addDeserializer(k.java as Class<T>, object : StdDeserializer<T>(k.java as Class<T>) { | |
| 25 | + override fun deserialize(p: JsonParser, ctxt: DeserializationContext) = fromJson(p.readValueAsTree()) | |
| 26 | + }) | |
| 27 | +}) | |
| 28 | + | |
| 29 | +val mapper = jacksonObjectMapper().apply { | |
| 30 | + propertyNamingStrategy = object : PropertyNamingStrategy.PropertyNamingStrategyBase() { override fun translate(name: String) = if (name == "empty") "" else name } | |
| 31 | + setSerializationInclusion(JsonInclude.Include.NON_NULL) | |
| 32 | + disable(DeserializationFeature.ACCEPT_FLOAT_AS_INT) | |
| 33 | + convert(OffsetDateTime::class, { OffsetDateTime.parse(it.asText()) }, { "\"${java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(it)}\"" }) | |
| 34 | + convert(Status::class, { Status.fromValue(it.asText()) }, { "\"${it.value}\"" }) | |
| 35 | +} | |
| 36 | + | |
| 37 | +data class TopLevel ( | |
| 38 | + @get:JsonProperty(required=true)@field:JsonProperty(required=true) | |
| 39 | + val code: String, | |
| 40 | + | |
| 41 | + @get:JsonProperty(required=true)@field:JsonProperty(required=true) | |
| 42 | + val dateTime: DateTime, | |
| 43 | + | |
| 44 | + @get:JsonProperty(required=true)@field:JsonProperty(required=true) | |
| 45 | + val enumValues: EnumValues, | |
| 46 | + | |
| 47 | + @get:JsonProperty(required=true)@field:JsonProperty(required=true) | |
| 48 | + val formatException: FormatException, | |
| 49 | + | |
| 50 | + @get:JsonProperty(required=true)@field:JsonProperty(required=true) | |
| 51 | + val regExp: RegExp, | |
| 52 | + | |
| 53 | + @get:JsonProperty(required=true)@field:JsonProperty(required=true) | |
| 54 | + val status: Status, | |
| 55 | + | |
| 56 | + @get:JsonProperty(required=true)@field:JsonProperty(required=true) | |
| 57 | + val timestamp: OffsetDateTime | |
| 58 | +) { | |
| 59 | + init { | |
| 60 | + require(code.length >= 1) | |
| 61 | + require(Regex("^[a-z]+\$").containsMatchIn(code)) | |
| 62 | + } | |
| 63 | + fun toJson() = mapper.writeValueAsString(this) | |
| 64 | + | |
| 65 | + companion object { | |
| 66 | + fun fromJson(json: String) = mapper.readValue<TopLevel>(json) | |
| 67 | + } | |
| 68 | +} | |
| 69 | + | |
| 70 | +data class DateTime ( | |
| 71 | + @get:JsonProperty(required=true)@field:JsonProperty(required=true) | |
| 72 | + val value: Long | |
| 73 | +) | |
| 74 | + | |
| 75 | +data class EnumValues ( | |
| 76 | + @get:JsonProperty(required=true)@field:JsonProperty(required=true) | |
| 77 | + val label: String | |
| 78 | +) | |
| 79 | + | |
| 80 | +data class FormatException ( | |
| 81 | + @get:JsonProperty(required=true)@field:JsonProperty(required=true) | |
| 82 | + val count: Long | |
| 83 | +) | |
| 84 | + | |
| 85 | +data class RegExp ( | |
| 86 | + @get:JsonProperty(required=true)@field:JsonProperty(required=true) | |
| 87 | + val active: Boolean | |
| 88 | +) | |
| 89 | + | |
| 90 | +enum class Status(val value: String) { | |
| 91 | + Ready("ready"), | |
| 92 | + Done("done"); | |
| 93 | + | |
| 94 | + companion object { | |
| 95 | + fun fromValue(value: String): Status = when (value) { | |
| 96 | + "ready" -> Ready | |
| 97 | + "done" -> Done | |
| 98 | + else -> throw IllegalArgumentException() | |
| 99 | + } | |
| 100 | + } | |
| 101 | +} |
Aschema-kotlindefault / TopLevel.kt+72 −0
| @@ -0,0 +1,72 @@ | ||
| 1 | +// To parse the JSON, install Klaxon and do: | |
| 2 | +// | |
| 3 | +// val topLevel = TopLevel.fromJson(jsonString) | |
| 4 | + | |
| 5 | +package quicktype | |
| 6 | + | |
| 7 | +import java.time.OffsetDateTime | |
| 8 | + | |
| 9 | +import com.beust.klaxon.* | |
| 10 | + | |
| 11 | +private fun <T> Klaxon.convert(k: kotlin.reflect.KClass<*>, fromJson: (JsonValue) -> T, toJson: (T) -> String, isUnion: Boolean = false) = | |
| 12 | + this.converter(object: Converter { | |
| 13 | + @Suppress("UNCHECKED_CAST") | |
| 14 | + override fun toJson(value: Any) = toJson(value as T) | |
| 15 | + override fun fromJson(jv: JsonValue) = fromJson(jv) as Any | |
| 16 | + override fun canConvert(cls: Class<*>) = cls == k.java || (isUnion && cls.superclass == k.java) | |
| 17 | + }) | |
| 18 | + | |
| 19 | +private val klaxon = Klaxon() | |
| 20 | + .convert(OffsetDateTime::class, { OffsetDateTime.parse(it.string!!) }, { "\"${java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(it)}\"" }) | |
| 21 | + .convert(Status::class, { Status.fromValue(it.string!!) }, { "\"${it.value}\"" }) | |
| 22 | + | |
| 23 | +data class TopLevel ( | |
| 24 | + val code: String, | |
| 25 | + val dateTime: DateTime, | |
| 26 | + val enumValues: EnumValues, | |
| 27 | + val formatException: FormatException, | |
| 28 | + val regExp: RegExp, | |
| 29 | + val status: Status, | |
| 30 | + val timestamp: OffsetDateTime | |
| 31 | +) { | |
| 32 | + init { | |
| 33 | + require(code.length >= 1) | |
| 34 | + } | |
| 35 | + init { | |
| 36 | + require(Regex("^[a-z]+\$").containsMatchIn(code)) | |
| 37 | + } | |
| 38 | + public fun toJson() = klaxon.toJsonString(this) | |
| 39 | + | |
| 40 | + companion object { | |
| 41 | + public fun fromJson(json: String) = klaxon.parse<TopLevel>(json) | |
| 42 | + } | |
| 43 | +} | |
| 44 | + | |
| 45 | +data class DateTime ( | |
| 46 | + val value: Long | |
| 47 | +) | |
| 48 | + | |
| 49 | +data class EnumValues ( | |
| 50 | + val label: String | |
| 51 | +) | |
| 52 | + | |
| 53 | +data class FormatException ( | |
| 54 | + val count: Long | |
| 55 | +) | |
| 56 | + | |
| 57 | +data class RegExp ( | |
| 58 | + val active: Boolean | |
| 59 | +) | |
| 60 | + | |
| 61 | +enum class Status(val value: String) { | |
| 62 | + Ready("ready"), | |
| 63 | + Done("done"); | |
| 64 | + | |
| 65 | + companion object { | |
| 66 | + public fun fromValue(value: String): Status = when (value) { | |
| 67 | + "ready" -> Ready | |
| 68 | + "done" -> Done | |
| 69 | + else -> throw IllegalArgumentException() | |
| 70 | + } | |
| 71 | + } | |
| 72 | +} |
Aschema-kotlinxdefault / TopLevel.kt+60 −0
| @@ -0,0 +1,60 @@ | ||
| 1 | +// To parse the JSON, install kotlin's serialization plugin and do: | |
| 2 | +// | |
| 3 | +// val json = Json { allowStructuredMapKeys = true } | |
| 4 | +// val topLevel = json.parse(TopLevel.serializer(), jsonString) | |
| 5 | + | |
| 6 | +@file:UseSerializers(OffsetDateTimeSerializer::class) | |
| 7 | + | |
| 8 | +package quicktype | |
| 9 | + | |
| 10 | +import java.time.OffsetDateTime | |
| 11 | + | |
| 12 | +import kotlinx.serialization.* | |
| 13 | +import kotlinx.serialization.json.* | |
| 14 | +import kotlinx.serialization.descriptors.* | |
| 15 | +import kotlinx.serialization.encoding.* | |
| 16 | + | |
| 17 | +@Serializable | |
| 18 | +data class TopLevel ( | |
| 19 | + val code: String, | |
| 20 | + val dateTime: DateTime, | |
| 21 | + val enumValues: EnumValues, | |
| 22 | + val formatException: FormatException, | |
| 23 | + val regExp: RegExp, | |
| 24 | + val status: Status, | |
| 25 | + val timestamp: OffsetDateTime | |
| 26 | +) | |
| 27 | + | |
| 28 | +@Serializable | |
| 29 | +data class DateTime ( | |
| 30 | + val value: Long | |
| 31 | +) | |
| 32 | + | |
| 33 | +@Serializable | |
| 34 | +data class EnumValues ( | |
| 35 | + val label: String | |
| 36 | +) | |
| 37 | + | |
| 38 | +@Serializable | |
| 39 | +data class FormatException ( | |
| 40 | + val count: Long | |
| 41 | +) | |
| 42 | + | |
| 43 | +@Serializable | |
| 44 | +data class RegExp ( | |
| 45 | + val active: Boolean | |
| 46 | +) | |
| 47 | + | |
| 48 | +@Serializable | |
| 49 | +enum class Status(val value: String) { | |
| 50 | + @SerialName("ready") Ready("ready"), | |
| 51 | + @SerialName("done") Done("done"); | |
| 52 | +} | |
| 53 | + | |
| 54 | +object OffsetDateTimeSerializer : KSerializer<OffsetDateTime> { | |
| 55 | + override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("OffsetDateTime", PrimitiveKind.STRING) | |
| 56 | + override fun deserialize(decoder: Decoder): OffsetDateTime = OffsetDateTime.parse(decoder.decodeString()) | |
| 57 | + override fun serialize(encoder: Encoder, value: OffsetDateTime) { | |
| 58 | + encoder.encodeString(java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(value)) | |
| 59 | + } | |
| 60 | +} |
Aschema-objective-cdefault / QTTopLevel.h+66 −0
| @@ -0,0 +1,66 @@ | ||
| 1 | +// To parse this JSON: | |
| 2 | +// | |
| 3 | +// NSError *error; | |
| 4 | +// QTTopLevel *topLevel = [QTTopLevel fromJSON:json encoding:NSUTF8Encoding error:&error]; | |
| 5 | + | |
| 6 | +#import <Foundation/Foundation.h> | |
| 7 | + | |
| 8 | +@class QTTopLevel; | |
| 9 | +@class QTDateTime; | |
| 10 | +@class QTEnumValues; | |
| 11 | +@class QTFormatException; | |
| 12 | +@class QTRegExp; | |
| 13 | +@class QTStatus; | |
| 14 | + | |
| 15 | +NS_ASSUME_NONNULL_BEGIN | |
| 16 | + | |
| 17 | +#pragma mark - Boxed enums | |
| 18 | + | |
| 19 | +@interface QTStatus : NSObject | |
| 20 | +@property (nonatomic, readonly, copy) NSString *value; | |
| 21 | ++ (instancetype _Nullable)withValue:(NSString *)value; | |
| 22 | ++ (QTStatus *)ready; | |
| 23 | ++ (QTStatus *)done; | |
| 24 | +@end | |
| 25 | + | |
| 26 | +#pragma mark - Top-level marshaling functions | |
| 27 | + | |
| 28 | +QTTopLevel *_Nullable QTTopLevelFromData(NSData *data, NSError **error); | |
| 29 | +QTTopLevel *_Nullable QTTopLevelFromJSON(NSString *json, NSStringEncoding encoding, NSError **error); | |
| 30 | +NSData *_Nullable QTTopLevelToData(QTTopLevel *topLevel, NSError **error); | |
| 31 | +NSString *_Nullable QTTopLevelToJSON(QTTopLevel *topLevel, NSStringEncoding encoding, NSError **error); | |
| 32 | + | |
| 33 | +#pragma mark - Object interfaces | |
| 34 | + | |
| 35 | +@interface QTTopLevel : NSObject | |
| 36 | +@property (nonatomic, copy) NSString *code; | |
| 37 | +@property (nonatomic, strong) QTDateTime *dateTime; | |
| 38 | +@property (nonatomic, strong) QTEnumValues *enumValues; | |
| 39 | +@property (nonatomic, strong) QTFormatException *formatException; | |
| 40 | +@property (nonatomic, strong) QTRegExp *regExp; | |
| 41 | +@property (nonatomic, assign) QTStatus *status; | |
| 42 | +@property (nonatomic, copy) NSString *timestamp; | |
| 43 | + | |
| 44 | ++ (_Nullable instancetype)fromJSON:(NSString *)json encoding:(NSStringEncoding)encoding error:(NSError *_Nullable *)error; | |
| 45 | ++ (_Nullable instancetype)fromData:(NSData *)data error:(NSError *_Nullable *)error; | |
| 46 | +- (NSString *_Nullable)toJSON:(NSStringEncoding)encoding error:(NSError *_Nullable *)error; | |
| 47 | +- (NSData *_Nullable)toData:(NSError *_Nullable *)error; | |
| 48 | +@end | |
| 49 | + | |
| 50 | +@interface QTDateTime : NSObject | |
| 51 | +@property (nonatomic, assign) NSInteger value; | |
| 52 | +@end | |
| 53 | + | |
| 54 | +@interface QTEnumValues : NSObject | |
| 55 | +@property (nonatomic, copy) NSString *label; | |
| 56 | +@end | |
| 57 | + | |
| 58 | +@interface QTFormatException : NSObject | |
| 59 | +@property (nonatomic, assign) NSInteger count; | |
| 60 | +@end | |
| 61 | + | |
| 62 | +@interface QTRegExp : NSObject | |
| 63 | +@property (nonatomic, assign) BOOL isActive; | |
| 64 | +@end | |
| 65 | + | |
| 66 | +NS_ASSUME_NONNULL_END |
Aschema-objective-cdefault / QTTopLevel.m+374 −0
| @@ -0,0 +1,374 @@ | ||
| 1 | +#import "QTTopLevel.h" | |
| 2 | + | |
| 3 | +#define λ(decl, expr) (^(decl) { return (expr); }) | |
| 4 | + | |
| 5 | +static id NSNullify(id _Nullable x) { | |
| 6 | + return (x == nil || x == NSNull.null) ? NSNull.null : x; | |
| 7 | +} | |
| 8 | + | |
| 9 | +NS_ASSUME_NONNULL_BEGIN | |
| 10 | + | |
| 11 | +@interface QTTopLevel (JSONConversion) | |
| 12 | ++ (instancetype)fromJSONDictionary:(NSDictionary *)dict; | |
| 13 | +- (NSDictionary *)JSONDictionary; | |
| 14 | +@end | |
| 15 | + | |
| 16 | +@interface QTDateTime (JSONConversion) | |
| 17 | ++ (instancetype)fromJSONDictionary:(NSDictionary *)dict; | |
| 18 | +- (NSDictionary *)JSONDictionary; | |
| 19 | +@end | |
| 20 | + | |
| 21 | +@interface QTEnumValues (JSONConversion) | |
| 22 | ++ (instancetype)fromJSONDictionary:(NSDictionary *)dict; | |
| 23 | +- (NSDictionary *)JSONDictionary; | |
| 24 | +@end | |
| 25 | + | |
| 26 | +@interface QTFormatException (JSONConversion) | |
| 27 | ++ (instancetype)fromJSONDictionary:(NSDictionary *)dict; | |
| 28 | +- (NSDictionary *)JSONDictionary; | |
| 29 | +@end | |
| 30 | + | |
| 31 | +@interface QTRegExp (JSONConversion) | |
| 32 | ++ (instancetype)fromJSONDictionary:(NSDictionary *)dict; | |
| 33 | +- (NSDictionary *)JSONDictionary; | |
| 34 | +@end | |
| 35 | + | |
| 36 | +@implementation QTStatus | |
| 37 | ++ (NSDictionary<NSString *, QTStatus *> *)values | |
| 38 | +{ | |
| 39 | + static NSDictionary<NSString *, QTStatus *> *values; | |
| 40 | + return values = values ? values : @{ | |
| 41 | + @"ready": [[QTStatus alloc] initWithValue:@"ready"], | |
| 42 | + @"done": [[QTStatus alloc] initWithValue:@"done"], | |
| 43 | + }; | |
| 44 | +} | |
| 45 | + | |
| 46 | ++ (QTStatus *)ready { return QTStatus.values[@"ready"]; } | |
| 47 | ++ (QTStatus *)done { return QTStatus.values[@"done"]; } | |
| 48 | + | |
| 49 | ++ (instancetype _Nullable)withValue:(NSString *)value | |
| 50 | +{ | |
| 51 | + return QTStatus.values[value]; | |
| 52 | +} | |
| 53 | + | |
| 54 | +- (instancetype)initWithValue:(NSString *)value | |
| 55 | +{ | |
| 56 | + if (self = [super init]) _value = value; | |
| 57 | + return self; | |
| 58 | +} | |
| 59 | + | |
| 60 | +- (NSUInteger)hash { return _value.hash; } | |
| 61 | +@end | |
| 62 | + | |
| 63 | +#pragma mark - JSON serialization | |
| 64 | + | |
| 65 | +QTTopLevel *_Nullable QTTopLevelFromData(NSData *data, NSError **error) | |
| 66 | +{ | |
| 67 | + @try { | |
| 68 | + id json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:error]; | |
| 69 | + return *error ? nil : [QTTopLevel fromJSONDictionary:json]; | |
| 70 | + } @catch (NSException *exception) { | |
| 71 | + *error = [NSError errorWithDomain:@"JSONSerialization" code:-1 userInfo:@{ @"exception": exception }]; | |
| 72 | + return nil; | |
| 73 | + } | |
| 74 | +} | |
| 75 | + | |
| 76 | +QTTopLevel *_Nullable QTTopLevelFromJSON(NSString *json, NSStringEncoding encoding, NSError **error) | |
| 77 | +{ | |
| 78 | + return QTTopLevelFromData([json dataUsingEncoding:encoding], error); | |
| 79 | +} | |
| 80 | + | |
| 81 | +NSData *_Nullable QTTopLevelToData(QTTopLevel *topLevel, NSError **error) | |
| 82 | +{ | |
| 83 | + @try { | |
| 84 | + id json = [topLevel JSONDictionary]; | |
| 85 | + NSData *data = [NSJSONSerialization dataWithJSONObject:json options:NSJSONWritingFragmentsAllowed error:error]; | |
| 86 | + return *error ? nil : data; | |
| 87 | + } @catch (NSException *exception) { | |
| 88 | + *error = [NSError errorWithDomain:@"JSONSerialization" code:-1 userInfo:@{ @"exception": exception }]; | |
| 89 | + return nil; | |
| 90 | + } | |
| 91 | +} | |
| 92 | + | |
| 93 | +NSString *_Nullable QTTopLevelToJSON(QTTopLevel *topLevel, NSStringEncoding encoding, NSError **error) | |
| 94 | +{ | |
| 95 | + NSData *data = QTTopLevelToData(topLevel, error); | |
| 96 | + return data ? [[NSString alloc] initWithData:data encoding:encoding] : nil; | |
| 97 | +} | |
| 98 | + | |
| 99 | +@implementation QTTopLevel | |
| 100 | ++ (NSDictionary<NSString *, NSString *> *)properties | |
| 101 | +{ | |
| 102 | + static NSDictionary<NSString *, NSString *> *properties; | |
| 103 | + return properties = properties ? properties : @{ | |
| 104 | + @"code": @"code", | |
| 105 | + @"dateTime": @"dateTime", | |
| 106 | + @"enumValues": @"enumValues", | |
| 107 | + @"formatException": @"formatException", | |
| 108 | + @"regExp": @"regExp", | |
| 109 | + @"status": @"status", | |
| 110 | + @"timestamp": @"timestamp", | |
| 111 | + }; | |
| 112 | +} | |
| 113 | + | |
| 114 | ++ (_Nullable instancetype)fromData:(NSData *)data error:(NSError *_Nullable *)error | |
| 115 | +{ | |
| 116 | + return QTTopLevelFromData(data, error); | |
| 117 | +} | |
| 118 | + | |
| 119 | ++ (_Nullable instancetype)fromJSON:(NSString *)json encoding:(NSStringEncoding)encoding error:(NSError *_Nullable *)error | |
| 120 | +{ | |
| 121 | + return QTTopLevelFromJSON(json, encoding, error); | |
| 122 | +} | |
| 123 | + | |
| 124 | ++ (instancetype)fromJSONDictionary:(NSDictionary *)dict | |
| 125 | +{ | |
| 126 | + return [dict isKindOfClass:NSDictionary.class] ? [[QTTopLevel alloc] initWithJSONDictionary:dict] : nil; | |
| 127 | +} | |
| 128 | + | |
| 129 | +- (instancetype)initWithJSONDictionary:(NSDictionary *)dict | |
| 130 | +{ | |
| 131 | + if (self = [super init]) { | |
| 132 | + if (dict[@"code"] && [dict[@"code"] rangeOfString:@"^[a-z]+$" options:NSRegularExpressionSearch].location == NSNotFound) return nil; | |
| 133 | + if (dict[@"code"] && [dict[@"code"] length] < 1) return nil; | |
| 134 | + if (![dict[@"code"] isKindOfClass:NSString.class]) return nil; | |
| 135 | + if (![dict[@"dateTime"] isKindOfClass:NSDictionary.class]) return nil; | |
| 136 | + if (![dict[@"enumValues"] isKindOfClass:NSDictionary.class]) return nil; | |
| 137 | + if (![dict[@"formatException"] isKindOfClass:NSDictionary.class]) return nil; | |
| 138 | + if (![dict[@"regExp"] isKindOfClass:NSDictionary.class]) return nil; | |
| 139 | + if (![dict[@"status"] isKindOfClass:NSString.class]) return nil; | |
| 140 | + if (dict[@"timestamp"] && [dict[@"timestamp"] rangeOfString:@"^[0-9]{4}-[0-9]{2}-[0-9]{2}T" options:NSRegularExpressionSearch].location == NSNotFound) return nil; | |
| 141 | + if (![dict[@"timestamp"] isKindOfClass:NSString.class]) return nil; | |
| 142 | + [self setValuesForKeysWithDictionary:dict]; | |
| 143 | + _dateTime = [QTDateTime fromJSONDictionary:(id)_dateTime]; | |
| 144 | + if (!_dateTime && dict[@"dateTime"] && ![dict[@"dateTime"] isKindOfClass:NSNull.class]) return nil; | |
| 145 | + _enumValues = [QTEnumValues fromJSONDictionary:(id)_enumValues]; | |
| 146 | + if (!_enumValues && dict[@"enumValues"] && ![dict[@"enumValues"] isKindOfClass:NSNull.class]) return nil; | |
| 147 | + _formatException = [QTFormatException fromJSONDictionary:(id)_formatException]; | |
| 148 | + if (!_formatException && dict[@"formatException"] && ![dict[@"formatException"] isKindOfClass:NSNull.class]) return nil; | |
| 149 | + _regExp = [QTRegExp fromJSONDictionary:(id)_regExp]; | |
| 150 | + if (!_regExp && dict[@"regExp"] && ![dict[@"regExp"] isKindOfClass:NSNull.class]) return nil; | |
| 151 | + _status = [QTStatus withValue:(id)_status]; | |
| 152 | + } | |
| 153 | + return self; | |
| 154 | +} | |
| 155 | + | |
| 156 | +- (void)setValue:(nullable id)value forKey:(NSString *)key | |
| 157 | +{ | |
| 158 | + id resolved = QTTopLevel.properties[key]; | |
| 159 | + if (resolved) [super setValue:value forKey:resolved]; | |
| 160 | +} | |
| 161 | + | |
| 162 | +- (void)setNilValueForKey:(NSString *)key | |
| 163 | +{ | |
| 164 | + id resolved = QTTopLevel.properties[key]; | |
| 165 | + if (resolved) [super setValue:@(0) forKey:resolved]; | |
| 166 | +} | |
| 167 | + | |
| 168 | +- (NSDictionary *)JSONDictionary | |
| 169 | +{ | |
| 170 | + id dict = [[self dictionaryWithValuesForKeys:QTTopLevel.properties.allValues] mutableCopy]; | |
| 171 | + | |
| 172 | + [dict addEntriesFromDictionary:@{ | |
| 173 | + @"dateTime": [_dateTime JSONDictionary], | |
| 174 | + @"enumValues": [_enumValues JSONDictionary], | |
| 175 | + @"formatException": [_formatException JSONDictionary], | |
| 176 | + @"regExp": [_regExp JSONDictionary], | |
| 177 | + @"status": [_status value], | |
| 178 | + }]; | |
| 179 | + | |
| 180 | + return dict; | |
| 181 | +} | |
| 182 | + | |
| 183 | +- (NSData *_Nullable)toData:(NSError *_Nullable *)error | |
| 184 | +{ | |
| 185 | + return QTTopLevelToData(self, error); | |
| 186 | +} | |
| 187 | + | |
| 188 | +- (NSString *_Nullable)toJSON:(NSStringEncoding)encoding error:(NSError *_Nullable *)error | |
| 189 | +{ | |
| 190 | + return QTTopLevelToJSON(self, encoding, error); | |
| 191 | +} | |
| 192 | +@end | |
| 193 | + | |
| 194 | +@implementation QTDateTime | |
| 195 | ++ (NSDictionary<NSString *, NSString *> *)properties | |
| 196 | +{ | |
| 197 | + static NSDictionary<NSString *, NSString *> *properties; | |
| 198 | + return properties = properties ? properties : @{ | |
| 199 | + @"value": @"value", | |
| 200 | + }; | |
| 201 | +} | |
| 202 | + | |
| 203 | ++ (instancetype)fromJSONDictionary:(NSDictionary *)dict | |
| 204 | +{ | |
| 205 | + return [dict isKindOfClass:NSDictionary.class] ? [[QTDateTime alloc] initWithJSONDictionary:dict] : nil; | |
| 206 | +} | |
| 207 | + | |
| 208 | +- (instancetype)initWithJSONDictionary:(NSDictionary *)dict | |
| 209 | +{ | |
| 210 | + if (self = [super init]) { | |
| 211 | + if (![dict[@"value"] isKindOfClass:NSNumber.class]) return nil; | |
| 212 | + if ([dict[@"value"] doubleValue] != [dict[@"value"] longLongValue]) return nil; | |
| 213 | + [self setValuesForKeysWithDictionary:dict]; | |
| 214 | + } | |
| 215 | + return self; | |
| 216 | +} | |
| 217 | + | |
| 218 | +- (void)setValue:(nullable id)value forKey:(NSString *)key | |
| 219 | +{ | |
| 220 | + id resolved = QTDateTime.properties[key]; | |
| 221 | + if (resolved) [super setValue:value forKey:resolved]; | |
| 222 | +} | |
| 223 | + | |
| 224 | +- (void)setNilValueForKey:(NSString *)key | |
| 225 | +{ | |
| 226 | + id resolved = QTDateTime.properties[key]; | |
| 227 | + if (resolved) [super setValue:@(0) forKey:resolved]; | |
| 228 | +} | |
| 229 | + | |
| 230 | +- (NSDictionary *)JSONDictionary | |
| 231 | +{ | |
| 232 | + return [self dictionaryWithValuesForKeys:QTDateTime.properties.allValues]; | |
| 233 | +} | |
| 234 | +@end | |
| 235 | + | |
| 236 | +@implementation QTEnumValues | |
| 237 | ++ (NSDictionary<NSString *, NSString *> *)properties | |
| 238 | +{ | |
| 239 | + static NSDictionary<NSString *, NSString *> *properties; | |
| 240 | + return properties = properties ? properties : @{ | |
| 241 | + @"label": @"label", | |
| 242 | + }; | |
| 243 | +} | |
| 244 | + | |
| 245 | ++ (instancetype)fromJSONDictionary:(NSDictionary *)dict | |
| 246 | +{ | |
| 247 | + return [dict isKindOfClass:NSDictionary.class] ? [[QTEnumValues alloc] initWithJSONDictionary:dict] : nil; | |
| 248 | +} | |
| 249 | + | |
| 250 | +- (instancetype)initWithJSONDictionary:(NSDictionary *)dict | |
| 251 | +{ | |
| 252 | + if (self = [super init]) { | |
| 253 | + if (![dict[@"label"] isKindOfClass:NSString.class]) return nil; | |
| 254 | + [self setValuesForKeysWithDictionary:dict]; | |
| 255 | + } | |
| 256 | + return self; | |
| 257 | +} | |
| 258 | + | |
| 259 | +- (void)setValue:(nullable id)value forKey:(NSString *)key | |
| 260 | +{ | |
| 261 | + id resolved = QTEnumValues.properties[key]; | |
| 262 | + if (resolved) [super setValue:value forKey:resolved]; | |
| 263 | +} | |
| 264 | + | |
| 265 | +- (void)setNilValueForKey:(NSString *)key | |
| 266 | +{ | |
| 267 | + id resolved = QTEnumValues.properties[key]; | |
| 268 | + if (resolved) [super setValue:@(0) forKey:resolved]; | |
| 269 | +} | |
| 270 | + | |
| 271 | +- (NSDictionary *)JSONDictionary | |
| 272 | +{ | |
| 273 | + return [self dictionaryWithValuesForKeys:QTEnumValues.properties.allValues]; | |
| 274 | +} | |
| 275 | +@end | |
| 276 | + | |
| 277 | +@implementation QTFormatException | |
| 278 | ++ (NSDictionary<NSString *, NSString *> *)properties | |
| 279 | +{ | |
| 280 | + static NSDictionary<NSString *, NSString *> *properties; | |
| 281 | + return properties = properties ? properties : @{ | |
| 282 | + @"count": @"count", | |
| 283 | + }; | |
| 284 | +} | |
| 285 | + | |
| 286 | ++ (instancetype)fromJSONDictionary:(NSDictionary *)dict | |
| 287 | +{ | |
| 288 | + return [dict isKindOfClass:NSDictionary.class] ? [[QTFormatException alloc] initWithJSONDictionary:dict] : nil; | |
| 289 | +} | |
| 290 | + | |
| 291 | +- (instancetype)initWithJSONDictionary:(NSDictionary *)dict | |
| 292 | +{ | |
| 293 | + if (self = [super init]) { | |
| 294 | + if (![dict[@"count"] isKindOfClass:NSNumber.class]) return nil; | |
| 295 | + if ([dict[@"count"] doubleValue] != [dict[@"count"] longLongValue]) return nil; | |
| 296 | + [self setValuesForKeysWithDictionary:dict]; | |
| 297 | + } | |
| 298 | + return self; | |
| 299 | +} | |
| 300 | + | |
| 301 | +- (void)setValue:(nullable id)value forKey:(NSString *)key | |
| 302 | +{ | |
| 303 | + id resolved = QTFormatException.properties[key]; | |
| 304 | + if (resolved) [super setValue:value forKey:resolved]; | |
| 305 | +} | |
| 306 | + | |
| 307 | +- (void)setNilValueForKey:(NSString *)key | |
| 308 | +{ | |
| 309 | + id resolved = QTFormatException.properties[key]; | |
| 310 | + if (resolved) [super setValue:@(0) forKey:resolved]; | |
| 311 | +} | |
| 312 | + | |
| 313 | +- (NSDictionary *)JSONDictionary | |
| 314 | +{ | |
| 315 | + return [self dictionaryWithValuesForKeys:QTFormatException.properties.allValues]; | |
| 316 | +} | |
| 317 | +@end | |
| 318 | + | |
| 319 | +@implementation QTRegExp | |
| 320 | ++ (NSDictionary<NSString *, NSString *> *)properties | |
| 321 | +{ | |
| 322 | + static NSDictionary<NSString *, NSString *> *properties; | |
| 323 | + return properties = properties ? properties : @{ | |
| 324 | + @"active": @"isActive", | |
| 325 | + }; | |
| 326 | +} | |
| 327 | + | |
| 328 | ++ (instancetype)fromJSONDictionary:(NSDictionary *)dict | |
| 329 | +{ | |
| 330 | + return [dict isKindOfClass:NSDictionary.class] ? [[QTRegExp alloc] initWithJSONDictionary:dict] : nil; | |
| 331 | +} | |
| 332 | + | |
| 333 | +- (instancetype)initWithJSONDictionary:(NSDictionary *)dict | |
| 334 | +{ | |
| 335 | + if (self = [super init]) { | |
| 336 | + if (![dict[@"active"] isKindOfClass:NSNumber.class]) return nil; | |
| 337 | + [self setValuesForKeysWithDictionary:dict]; | |
| 338 | + } | |
| 339 | + return self; | |
| 340 | +} | |
| 341 | + | |
| 342 | +- (void)setValue:(nullable id)value forKey:(NSString *)key | |
| 343 | +{ | |
| 344 | + id resolved = QTRegExp.properties[key]; | |
| 345 | + if (resolved) [super setValue:value forKey:resolved]; | |
| 346 | +} | |
| 347 | + | |
| 348 | +- (void)setNilValueForKey:(NSString *)key | |
| 349 | +{ | |
| 350 | + id resolved = QTRegExp.properties[key]; | |
| 351 | + if (resolved) [super setValue:@(0) forKey:resolved]; | |
| 352 | +} | |
| 353 | + | |
| 354 | +- (NSDictionary *)JSONDictionary | |
| 355 | +{ | |
| 356 | + id dict = [[self dictionaryWithValuesForKeys:QTRegExp.properties.allValues] mutableCopy]; | |
| 357 | + | |
| 358 | + for (id jsonName in QTRegExp.properties) { | |
| 359 | + id propertyName = QTRegExp.properties[jsonName]; | |
| 360 | + if (![jsonName isEqualToString:propertyName]) { | |
| 361 | + dict[jsonName] = dict[propertyName]; | |
| 362 | + [dict removeObjectForKey:propertyName]; | |
| 363 | + } | |
| 364 | + } | |
| 365 | + | |
| 366 | + [dict addEntriesFromDictionary:@{ | |
| 367 | + @"active": _isActive ? @YES : @NO, | |
| 368 | + }]; | |
| 369 | + | |
| 370 | + return dict; | |
| 371 | +} | |
| 372 | +@end | |
| 373 | + | |
| 374 | +NS_ASSUME_NONNULL_END |
Aschema-phpdefault / TopLevel.php+916 −0
| @@ -0,0 +1,916 @@ | ||
| 1 | +<?php | |
| 2 | +declare(strict_types=1); | |
| 3 | + | |
| 4 | +// This is an autogenerated file:TopLevel | |
| 5 | + | |
| 6 | +class TopLevel { | |
| 7 | + private string $code; // json:code Required | |
| 8 | + private DateTimeClass $dateTime; // json:dateTime Required | |
| 9 | + private EnumValues $enumValues; // json:enumValues Required | |
| 10 | + private FormatException $formatException; // json:formatException Required | |
| 11 | + private RegExp $regExp; // json:regExp Required | |
| 12 | + private Status $status; // json:status Required | |
| 13 | + private DateTime $timestamp; // json:timestamp Required | |
| 14 | + | |
| 15 | + /** | |
| 16 | + * @param string $code | |
| 17 | + * @param DateTimeClass $dateTime | |
| 18 | + * @param EnumValues $enumValues | |
| 19 | + * @param FormatException $formatException | |
| 20 | + * @param RegExp $regExp | |
| 21 | + * @param Status $status | |
| 22 | + * @param DateTime $timestamp | |
| 23 | + */ | |
| 24 | + public function __construct(string $code, DateTimeClass $dateTime, EnumValues $enumValues, FormatException $formatException, RegExp $regExp, Status $status, DateTime $timestamp) { | |
| 25 | + $this->code = $code; | |
| 26 | + $this->dateTime = $dateTime; | |
| 27 | + $this->enumValues = $enumValues; | |
| 28 | + $this->formatException = $formatException; | |
| 29 | + $this->regExp = $regExp; | |
| 30 | + $this->status = $status; | |
| 31 | + $this->timestamp = $timestamp; | |
| 32 | + } | |
| 33 | + | |
| 34 | + /** | |
| 35 | + * @param string $value | |
| 36 | + * @throws Exception | |
| 37 | + * @return string | |
| 38 | + */ | |
| 39 | + public static function fromCode(string $value): string { | |
| 40 | + return $value; /*string*/ | |
| 41 | + } | |
| 42 | + | |
| 43 | + /** | |
| 44 | + * @throws Exception | |
| 45 | + * @return string | |
| 46 | + */ | |
| 47 | + public function toCode(): string { | |
| 48 | + if (TopLevel::validateCode($this->code)) { | |
| 49 | + return $this->code; /*string*/ | |
| 50 | + } | |
| 51 | + throw new Exception('never get to this TopLevel::code'); | |
| 52 | + } | |
| 53 | + | |
| 54 | + /** | |
| 55 | + * @param string | |
| 56 | + * @return bool | |
| 57 | + * @throws Exception | |
| 58 | + */ | |
| 59 | + public static function validateCode(string $value): bool { | |
| 60 | + if (preg_match_all('/./us', $value) < 1) { | |
| 61 | + throw new Exception("Attribute Error"); | |
| 62 | + } | |
| 63 | + if (preg_match('~^[a-z]+$~u', $value) !== 1) { | |
| 64 | + throw new Exception("Attribute Error"); | |
| 65 | + } | |
| 66 | + return true; | |
| 67 | + } | |
| 68 | + | |
| 69 | + /** | |
| 70 | + * @throws Exception | |
| 71 | + * @return string | |
| 72 | + */ | |
| 73 | + public function getCode(): string { | |
| 74 | + if (TopLevel::validateCode($this->code)) { | |
| 75 | + return $this->code; | |
| 76 | + } | |
| 77 | + throw new Exception('never get to getCode TopLevel::code'); | |
| 78 | + } | |
| 79 | + | |
| 80 | + /** | |
| 81 | + * @return string | |
| 82 | + */ | |
| 83 | + public static function sampleCode(): string { | |
| 84 | + return 'TopLevel::code::31'; /*31:code*/ | |
| 85 | + } | |
| 86 | + | |
| 87 | + /** | |
| 88 | + * @param stdClass $value | |
| 89 | + * @throws Exception | |
| 90 | + * @return DateTimeClass | |
| 91 | + */ | |
| 92 | + public static function fromDateTime(stdClass $value): DateTimeClass { | |
| 93 | + return DateTimeClass::from($value); /*class*/ | |
| 94 | + } | |
| 95 | + | |
| 96 | + /** | |
| 97 | + * @throws Exception | |
| 98 | + * @return stdClass | |
| 99 | + */ | |
| 100 | + public function toDateTime(): stdClass { | |
| 101 | + if (TopLevel::validateDateTime($this->dateTime)) { | |
| 102 | + return $this->dateTime->to(); /*class*/ | |
| 103 | + } | |
| 104 | + throw new Exception('never get to this TopLevel::dateTime'); | |
| 105 | + } | |
| 106 | + | |
| 107 | + /** | |
| 108 | + * @param DateTimeClass | |
| 109 | + * @return bool | |
| 110 | + * @throws Exception | |
| 111 | + */ | |
| 112 | + public static function validateDateTime(DateTimeClass $value): bool { | |
| 113 | + $value->validate(); | |
| 114 | + return true; | |
| 115 | + } | |
| 116 | + | |
| 117 | + /** | |
| 118 | + * @throws Exception | |
| 119 | + * @return DateTimeClass | |
| 120 | + */ | |
| 121 | + public function getDateTime(): DateTimeClass { | |
| 122 | + if (TopLevel::validateDateTime($this->dateTime)) { | |
| 123 | + return $this->dateTime; | |
| 124 | + } | |
| 125 | + throw new Exception('never get to getDateTime TopLevel::dateTime'); | |
| 126 | + } | |
| 127 | + | |
| 128 | + /** | |
| 129 | + * @return DateTimeClass | |
| 130 | + */ | |
| 131 | + public static function sampleDateTime(): DateTimeClass { | |
| 132 | + return DateTimeClass::sample(); /*32:dateTime*/ | |
| 133 | + } | |
| 134 | + | |
| 135 | + /** | |
| 136 | + * @param stdClass $value | |
| 137 | + * @throws Exception | |
| 138 | + * @return EnumValues | |
| 139 | + */ | |
| 140 | + public static function fromEnumValues(stdClass $value): EnumValues { | |
| 141 | + return EnumValues::from($value); /*class*/ | |
| 142 | + } | |
| 143 | + | |
| 144 | + /** | |
| 145 | + * @throws Exception | |
| 146 | + * @return stdClass | |
| 147 | + */ | |
| 148 | + public function toEnumValues(): stdClass { | |
| 149 | + if (TopLevel::validateEnumValues($this->enumValues)) { | |
| 150 | + return $this->enumValues->to(); /*class*/ | |
| 151 | + } | |
| 152 | + throw new Exception('never get to this TopLevel::enumValues'); | |
| 153 | + } | |
| 154 | + | |
| 155 | + /** | |
| 156 | + * @param EnumValues | |
| 157 | + * @return bool | |
| 158 | + * @throws Exception | |
| 159 | + */ | |
| 160 | + public static function validateEnumValues(EnumValues $value): bool { | |
| 161 | + $value->validate(); | |
| 162 | + return true; | |
| 163 | + } | |
| 164 | + | |
| 165 | + /** | |
| 166 | + * @throws Exception | |
| 167 | + * @return EnumValues | |
| 168 | + */ | |
| 169 | + public function getEnumValues(): EnumValues { | |
| 170 | + if (TopLevel::validateEnumValues($this->enumValues)) { | |
| 171 | + return $this->enumValues; | |
| 172 | + } | |
| 173 | + throw new Exception('never get to getEnumValues TopLevel::enumValues'); | |
| 174 | + } | |
| 175 | + | |
| 176 | + /** | |
| 177 | + * @return EnumValues | |
| 178 | + */ | |
| 179 | + public static function sampleEnumValues(): EnumValues { | |
| 180 | + return EnumValues::sample(); /*33:enumValues*/ | |
| 181 | + } | |
| 182 | + | |
| 183 | + /** | |
| 184 | + * @param stdClass $value | |
| 185 | + * @throws Exception | |
| 186 | + * @return FormatException | |
| 187 | + */ | |
| 188 | + public static function fromFormatException(stdClass $value): FormatException { | |
| 189 | + return FormatException::from($value); /*class*/ | |
| 190 | + } | |
| 191 | + | |
| 192 | + /** | |
| 193 | + * @throws Exception | |
| 194 | + * @return stdClass | |
| 195 | + */ | |
| 196 | + public function toFormatException(): stdClass { | |
| 197 | + if (TopLevel::validateFormatException($this->formatException)) { | |
| 198 | + return $this->formatException->to(); /*class*/ | |
| 199 | + } | |
| 200 | + throw new Exception('never get to this TopLevel::formatException'); | |
| 201 | + } | |
| 202 | + | |
| 203 | + /** | |
| 204 | + * @param FormatException | |
| 205 | + * @return bool | |
| 206 | + * @throws Exception | |
| 207 | + */ | |
| 208 | + public static function validateFormatException(FormatException $value): bool { | |
| 209 | + $value->validate(); | |
| 210 | + return true; | |
| 211 | + } | |
| 212 | + | |
| 213 | + /** | |
| 214 | + * @throws Exception | |
| 215 | + * @return FormatException | |
| 216 | + */ | |
| 217 | + public function getFormatException(): FormatException { | |
| 218 | + if (TopLevel::validateFormatException($this->formatException)) { | |
| 219 | + return $this->formatException; | |
| 220 | + } | |
| 221 | + throw new Exception('never get to getFormatException TopLevel::formatException'); | |
| 222 | + } | |
| 223 | + | |
| 224 | + /** | |
| 225 | + * @return FormatException | |
| 226 | + */ | |
| 227 | + public static function sampleFormatException(): FormatException { | |
| 228 | + return FormatException::sample(); /*34:formatException*/ | |
| 229 | + } | |
| 230 | + | |
| 231 | + /** | |
| 232 | + * @param stdClass $value | |
| 233 | + * @throws Exception | |
| 234 | + * @return RegExp | |
| 235 | + */ | |
| 236 | + public static function fromRegExp(stdClass $value): RegExp { | |
| 237 | + return RegExp::from($value); /*class*/ | |
| 238 | + } | |
| 239 | + | |
| 240 | + /** | |
| 241 | + * @throws Exception | |
| 242 | + * @return stdClass | |
| 243 | + */ | |
| 244 | + public function toRegExp(): stdClass { | |
| 245 | + if (TopLevel::validateRegExp($this->regExp)) { | |
| 246 | + return $this->regExp->to(); /*class*/ | |
| 247 | + } | |
| 248 | + throw new Exception('never get to this TopLevel::regExp'); | |
| 249 | + } | |
| 250 | + | |
| 251 | + /** | |
| 252 | + * @param RegExp | |
| 253 | + * @return bool | |
| 254 | + * @throws Exception | |
| 255 | + */ | |
| 256 | + public static function validateRegExp(RegExp $value): bool { | |
| 257 | + $value->validate(); | |
| 258 | + return true; | |
| 259 | + } | |
| 260 | + | |
| 261 | + /** | |
| 262 | + * @throws Exception | |
| 263 | + * @return RegExp | |
| 264 | + */ | |
| 265 | + public function getRegExp(): RegExp { | |
| 266 | + if (TopLevel::validateRegExp($this->regExp)) { | |
| 267 | + return $this->regExp; | |
| 268 | + } | |
| 269 | + throw new Exception('never get to getRegExp TopLevel::regExp'); | |
| 270 | + } | |
| 271 | + | |
| 272 | + /** | |
| 273 | + * @return RegExp | |
| 274 | + */ | |
| 275 | + public static function sampleRegExp(): RegExp { | |
| 276 | + return RegExp::sample(); /*35:regExp*/ | |
| 277 | + } | |
| 278 | + | |
| 279 | + /** | |
| 280 | + * @param string $value | |
| 281 | + * @throws Exception | |
| 282 | + * @return Status | |
| 283 | + */ | |
| 284 | + public static function fromStatus(string $value): Status { | |
| 285 | + return Status::from($value); /*enum*/ | |
| 286 | + } | |
| 287 | + | |
| 288 | + /** | |
| 289 | + * @throws Exception | |
| 290 | + * @return string | |
| 291 | + */ | |
| 292 | + public function toStatus(): string { | |
| 293 | + if (TopLevel::validateStatus($this->status)) { | |
| 294 | + return Status::to($this->status); /*enum*/ | |
| 295 | + } | |
| 296 | + throw new Exception('never get to this TopLevel::status'); | |
| 297 | + } | |
| 298 | + | |
| 299 | + /** | |
| 300 | + * @param Status | |
| 301 | + * @return bool | |
| 302 | + * @throws Exception | |
| 303 | + */ | |
| 304 | + public static function validateStatus(Status $value): bool { | |
| 305 | + Status::to($value); | |
| 306 | + return true; | |
| 307 | + } | |
| 308 | + | |
| 309 | + /** | |
| 310 | + * @throws Exception | |
| 311 | + * @return Status | |
| 312 | + */ | |
| 313 | + public function getStatus(): Status { | |
| 314 | + if (TopLevel::validateStatus($this->status)) { | |
| 315 | + return $this->status; | |
| 316 | + } | |
| 317 | + throw new Exception('never get to getStatus TopLevel::status'); | |
| 318 | + } | |
| 319 | + | |
| 320 | + /** | |
| 321 | + * @return Status | |
| 322 | + */ | |
| 323 | + public static function sampleStatus(): Status { | |
| 324 | + return Status::sample(); /*enum*/ | |
| 325 | + } | |
| 326 | + | |
| 327 | + /** | |
| 328 | + * @param string $value | |
| 329 | + * @throws Exception | |
| 330 | + * @return DateTime | |
| 331 | + */ | |
| 332 | + public static function fromTimestamp(string $value): DateTime { | |
| 333 | + $tmp = new DateTime($value); | |
| 334 | + if (!is_a($tmp, 'DateTime')) { | |
| 335 | + throw new Exception('Attribute Error:TopLevel::'); | |
| 336 | + } | |
| 337 | + return $tmp; | |
| 338 | + } | |
| 339 | + | |
| 340 | + /** | |
| 341 | + * @throws Exception | |
| 342 | + * @return string | |
| 343 | + */ | |
| 344 | + public function toTimestamp(): string { | |
| 345 | + if (TopLevel::validateTimestamp($this->timestamp)) { | |
| 346 | + return $this->timestamp->format("Y-m-d\\TH:i:s.uP"); | |
| 347 | + } | |
| 348 | + throw new Exception('never get to this TopLevel::timestamp'); | |
| 349 | + } | |
| 350 | + | |
| 351 | + /** | |
| 352 | + * @param DateTime | |
| 353 | + * @return bool | |
| 354 | + * @throws Exception | |
| 355 | + */ | |
| 356 | + public static function validateTimestamp(DateTime $value): bool { | |
| 357 | + if (!is_a($value, 'DateTime')) { | |
| 358 | + throw new Exception('Attribute Error:TopLevel::timestamp'); | |
| 359 | + } | |
| 360 | + return true; | |
| 361 | + } | |
| 362 | + | |
| 363 | + /** | |
| 364 | + * @throws Exception | |
| 365 | + * @return DateTime | |
| 366 | + */ | |
| 367 | + public function getTimestamp(): DateTime { | |
| 368 | + if (TopLevel::validateTimestamp($this->timestamp)) { | |
| 369 | + return $this->timestamp; | |
| 370 | + } | |
| 371 | + throw new Exception('never get to getTimestamp TopLevel::timestamp'); | |
| 372 | + } | |
| 373 | + | |
| 374 | + /** | |
| 375 | + * @return DateTime | |
| 376 | + */ | |
| 377 | + public static function sampleTimestamp(): DateTime { | |
| 378 | + return DateTime::createFromFormat(DateTimeInterface::ISO8601, '2020-12-70T12:70:70+00:00'); | |
| 379 | + } | |
| 380 | + | |
| 381 | + /** | |
| 382 | + * @throws Exception | |
| 383 | + * @return bool | |
| 384 | + */ | |
| 385 | + public function validate(): bool { | |
| 386 | + return TopLevel::validateCode($this->code) | |
| 387 | + || TopLevel::validateDateTime($this->dateTime) | |
| 388 | + || TopLevel::validateEnumValues($this->enumValues) | |
| 389 | + || TopLevel::validateFormatException($this->formatException) | |
| 390 | + || TopLevel::validateRegExp($this->regExp) | |
| 391 | + || TopLevel::validateStatus($this->status) | |
| 392 | + || TopLevel::validateTimestamp($this->timestamp); | |
| 393 | + } | |
| 394 | + | |
| 395 | + /** | |
| 396 | + * @return stdClass | |
| 397 | + * @throws Exception | |
| 398 | + */ | |
| 399 | + public function to(): stdClass { | |
| 400 | + $out = new stdClass(); | |
| 401 | + $out->{'code'} = $this->toCode(); | |
| 402 | + $out->{'dateTime'} = $this->toDateTime(); | |
| 403 | + $out->{'enumValues'} = $this->toEnumValues(); | |
| 404 | + $out->{'formatException'} = $this->toFormatException(); | |
| 405 | + $out->{'regExp'} = $this->toRegExp(); | |
| 406 | + $out->{'status'} = $this->toStatus(); | |
| 407 | + $out->{'timestamp'} = $this->toTimestamp(); | |
| 408 | + return $out; | |
| 409 | + } | |
| 410 | + | |
| 411 | + /** | |
| 412 | + * @param stdClass $obj | |
| 413 | + * @return TopLevel | |
| 414 | + * @throws Exception | |
| 415 | + */ | |
| 416 | + public static function from(stdClass $obj): TopLevel { | |
| 417 | + if (!property_exists($obj, 'code')) { | |
| 418 | + throw new Exception("Missing required property"); | |
| 419 | + } | |
| 420 | + if (!property_exists($obj, 'dateTime')) { | |
| 421 | + throw new Exception("Missing required property"); | |
| 422 | + } | |
| 423 | + if (!property_exists($obj, 'enumValues')) { | |
| 424 | + throw new Exception("Missing required property"); | |
| 425 | + } | |
| 426 | + if (!property_exists($obj, 'formatException')) { | |
| 427 | + throw new Exception("Missing required property"); | |
| 428 | + } | |
| 429 | + if (!property_exists($obj, 'regExp')) { | |
| 430 | + throw new Exception("Missing required property"); | |
| 431 | + } | |
| 432 | + if (!property_exists($obj, 'status')) { | |
| 433 | + throw new Exception("Missing required property"); | |
| 434 | + } | |
| 435 | + if (!property_exists($obj, 'timestamp')) { | |
| 436 | + throw new Exception("Missing required property"); | |
| 437 | + } | |
| 438 | + return new TopLevel( | |
| 439 | + TopLevel::fromCode($obj->{'code'}) | |
| 440 | + ,TopLevel::fromDateTime($obj->{'dateTime'}) | |
| 441 | + ,TopLevel::fromEnumValues($obj->{'enumValues'}) | |
| 442 | + ,TopLevel::fromFormatException($obj->{'formatException'}) | |
| 443 | + ,TopLevel::fromRegExp($obj->{'regExp'}) | |
| 444 | + ,TopLevel::fromStatus($obj->{'status'}) | |
| 445 | + ,TopLevel::fromTimestamp($obj->{'timestamp'}) | |
| 446 | + ); | |
| 447 | + } | |
| 448 | + | |
| 449 | + /** | |
| 450 | + * @return TopLevel | |
| 451 | + */ | |
| 452 | + public static function sample(): TopLevel { | |
| 453 | + return new TopLevel( | |
| 454 | + TopLevel::sampleCode() | |
| 455 | + ,TopLevel::sampleDateTime() | |
| 456 | + ,TopLevel::sampleEnumValues() | |
| 457 | + ,TopLevel::sampleFormatException() | |
| 458 | + ,TopLevel::sampleRegExp() | |
| 459 | + ,TopLevel::sampleStatus() | |
| 460 | + ,TopLevel::sampleTimestamp() | |
| 461 | + ); | |
| 462 | + } | |
| 463 | +} | |
| 464 | + | |
| 465 | +// This is an autogenerated file:DateTimeClass | |
| 466 | + | |
| 467 | +class DateTimeClass { | |
| 468 | + private int $value; // json:value Required | |
| 469 | + | |
| 470 | + /** | |
| 471 | + * @param int $value | |
| 472 | + */ | |
| 473 | + public function __construct(int $value) { | |
| 474 | + $this->value = $value; | |
| 475 | + } | |
| 476 | + | |
| 477 | + /** | |
| 478 | + * @param int $value | |
| 479 | + * @throws Exception | |
| 480 | + * @return int | |
| 481 | + */ | |
| 482 | + public static function fromValue(int $value): int { | |
| 483 | + return $value; /*int*/ | |
| 484 | + } | |
| 485 | + | |
| 486 | + /** | |
| 487 | + * @throws Exception | |
| 488 | + * @return int | |
| 489 | + */ | |
| 490 | + public function toValue(): int { | |
| 491 | + if (DateTimeClass::validateValue($this->value)) { | |
| 492 | + return $this->value; /*int*/ | |
| 493 | + } | |
| 494 | + throw new Exception('never get to this DateTimeClass::value'); | |
| 495 | + } | |
| 496 | + | |
| 497 | + /** | |
| 498 | + * @param int | |
| 499 | + * @return bool | |
| 500 | + * @throws Exception | |
| 501 | + */ | |
| 502 | + public static function validateValue(int $value): bool { | |
| 503 | + return true; | |
| 504 | + } | |
| 505 | + | |
| 506 | + /** | |
| 507 | + * @throws Exception | |
| 508 | + * @return int | |
| 509 | + */ | |
| 510 | + public function getValue(): int { | |
| 511 | + if (DateTimeClass::validateValue($this->value)) { | |
| 512 | + return $this->value; | |
| 513 | + } | |
| 514 | + throw new Exception('never get to getValue DateTimeClass::value'); | |
| 515 | + } | |
| 516 | + | |
| 517 | + /** | |
| 518 | + * @return int | |
| 519 | + */ | |
| 520 | + public static function sampleValue(): int { | |
| 521 | + return 31; /*31:value*/ | |
| 522 | + } | |
| 523 | + | |
| 524 | + /** | |
| 525 | + * @throws Exception | |
| 526 | + * @return bool | |
| 527 | + */ | |
| 528 | + public function validate(): bool { | |
| 529 | + return DateTimeClass::validateValue($this->value); | |
| 530 | + } | |
| 531 | + | |
| 532 | + /** | |
| 533 | + * @return stdClass | |
| 534 | + * @throws Exception | |
| 535 | + */ | |
| 536 | + public function to(): stdClass { | |
| 537 | + $out = new stdClass(); | |
| 538 | + $out->{'value'} = $this->toValue(); | |
| 539 | + return $out; | |
| 540 | + } | |
| 541 | + | |
| 542 | + /** | |
| 543 | + * @param stdClass $obj | |
| 544 | + * @return DateTimeClass | |
| 545 | + * @throws Exception | |
| 546 | + */ | |
| 547 | + public static function from(stdClass $obj): DateTimeClass { | |
| 548 | + if (!property_exists($obj, 'value')) { | |
| 549 | + throw new Exception("Missing required property"); | |
| 550 | + } | |
| 551 | + return new DateTimeClass( | |
| 552 | + DateTimeClass::fromValue($obj->{'value'}) | |
| 553 | + ); | |
| 554 | + } | |
| 555 | + | |
| 556 | + /** | |
| 557 | + * @return DateTimeClass | |
| 558 | + */ | |
| 559 | + public static function sample(): DateTimeClass { | |
| 560 | + return new DateTimeClass( | |
| 561 | + DateTimeClass::sampleValue() | |
| 562 | + ); | |
| 563 | + } | |
| 564 | +} | |
| 565 | + | |
| 566 | +// This is an autogenerated file:EnumValues | |
| 567 | + | |
| 568 | +class EnumValues { | |
| 569 | + private string $label; // json:label Required | |
| 570 | + | |
| 571 | + /** | |
| 572 | + * @param string $label | |
| 573 | + */ | |
| 574 | + public function __construct(string $label) { | |
| 575 | + $this->label = $label; | |
| 576 | + } | |
| 577 | + | |
| 578 | + /** | |
| 579 | + * @param string $value | |
| 580 | + * @throws Exception | |
| 581 | + * @return string | |
| 582 | + */ | |
| 583 | + public static function fromLabel(string $value): string { | |
| 584 | + return $value; /*string*/ | |
| 585 | + } | |
| 586 | + | |
| 587 | + /** | |
| 588 | + * @throws Exception | |
| 589 | + * @return string | |
| 590 | + */ | |
| 591 | + public function toLabel(): string { | |
| 592 | + if (EnumValues::validateLabel($this->label)) { | |
| 593 | + return $this->label; /*string*/ | |
| 594 | + } | |
| 595 | + throw new Exception('never get to this EnumValues::label'); | |
| 596 | + } | |
| 597 | + | |
| 598 | + /** | |
| 599 | + * @param string | |
| 600 | + * @return bool | |
| 601 | + * @throws Exception | |
| 602 | + */ | |
| 603 | + public static function validateLabel(string $value): bool { | |
| 604 | + return true; | |
| 605 | + } | |
| 606 | + | |
| 607 | + /** | |
| 608 | + * @throws Exception | |
| 609 | + * @return string | |
| 610 | + */ | |
| 611 | + public function getLabel(): string { | |
| 612 | + if (EnumValues::validateLabel($this->label)) { | |
| 613 | + return $this->label; | |
| 614 | + } | |
| 615 | + throw new Exception('never get to getLabel EnumValues::label'); | |
| 616 | + } | |
| 617 | + | |
| 618 | + /** | |
| 619 | + * @return string | |
| 620 | + */ | |
| 621 | + public static function sampleLabel(): string { | |
| 622 | + return 'EnumValues::label::31'; /*31:label*/ | |
| 623 | + } | |
| 624 | + | |
| 625 | + /** | |
| 626 | + * @throws Exception | |
| 627 | + * @return bool | |
| 628 | + */ | |
| 629 | + public function validate(): bool { | |
| 630 | + return EnumValues::validateLabel($this->label); | |
| 631 | + } | |
| 632 | + | |
| 633 | + /** | |
| 634 | + * @return stdClass | |
| 635 | + * @throws Exception | |
| 636 | + */ | |
| 637 | + public function to(): stdClass { | |
| 638 | + $out = new stdClass(); | |
| 639 | + $out->{'label'} = $this->toLabel(); | |
| 640 | + return $out; | |
| 641 | + } | |
| 642 | + | |
| 643 | + /** | |
| 644 | + * @param stdClass $obj | |
| 645 | + * @return EnumValues | |
| 646 | + * @throws Exception | |
| 647 | + */ | |
| 648 | + public static function from(stdClass $obj): EnumValues { | |
| 649 | + if (!property_exists($obj, 'label')) { | |
| 650 | + throw new Exception("Missing required property"); | |
| 651 | + } | |
| 652 | + return new EnumValues( | |
| 653 | + EnumValues::fromLabel($obj->{'label'}) | |
| 654 | + ); | |
| 655 | + } | |
| 656 | + | |
| 657 | + /** | |
| 658 | + * @return EnumValues | |
| 659 | + */ | |
| 660 | + public static function sample(): EnumValues { | |
| 661 | + return new EnumValues( | |
| 662 | + EnumValues::sampleLabel() | |
| 663 | + ); | |
| 664 | + } | |
| 665 | +} | |
| 666 | + | |
| 667 | +// This is an autogenerated file:FormatException | |
| 668 | + | |
| 669 | +class FormatException { | |
| 670 | + private int $count; // json:count Required | |
| 671 | + | |
| 672 | + /** | |
| 673 | + * @param int $count | |
| 674 | + */ | |
| 675 | + public function __construct(int $count) { | |
| 676 | + $this->count = $count; | |
| 677 | + } | |
| 678 | + | |
| 679 | + /** | |
| 680 | + * @param int $value | |
| 681 | + * @throws Exception | |
| 682 | + * @return int | |
| 683 | + */ | |
| 684 | + public static function fromCount(int $value): int { | |
| 685 | + return $value; /*int*/ | |
| 686 | + } | |
| 687 | + | |
| 688 | + /** | |
| 689 | + * @throws Exception | |
| 690 | + * @return int | |
| 691 | + */ | |
| 692 | + public function toCount(): int { | |
| 693 | + if (FormatException::validateCount($this->count)) { | |
| 694 | + return $this->count; /*int*/ | |
| 695 | + } | |
| 696 | + throw new Exception('never get to this FormatException::count'); | |
| 697 | + } | |
| 698 | + | |
| 699 | + /** | |
| 700 | + * @param int | |
| 701 | + * @return bool | |
| 702 | + * @throws Exception | |
| 703 | + */ | |
| 704 | + public static function validateCount(int $value): bool { | |
| 705 | + return true; | |
| 706 | + } | |
| 707 | + | |
| 708 | + /** | |
| 709 | + * @throws Exception | |
| 710 | + * @return int | |
| 711 | + */ | |
| 712 | + public function getCount(): int { | |
| 713 | + if (FormatException::validateCount($this->count)) { | |
| 714 | + return $this->count; | |
| 715 | + } | |
| 716 | + throw new Exception('never get to getCount FormatException::count'); | |
| 717 | + } | |
| 718 | + | |
| 719 | + /** | |
| 720 | + * @return int | |
| 721 | + */ | |
| 722 | + public static function sampleCount(): int { | |
| 723 | + return 31; /*31:count*/ | |
| 724 | + } | |
| 725 | + | |
| 726 | + /** | |
| 727 | + * @throws Exception | |
| 728 | + * @return bool | |
| 729 | + */ | |
| 730 | + public function validate(): bool { | |
| 731 | + return FormatException::validateCount($this->count); | |
| 732 | + } | |
| 733 | + | |
| 734 | + /** | |
| 735 | + * @return stdClass | |
| 736 | + * @throws Exception | |
| 737 | + */ | |
| 738 | + public function to(): stdClass { | |
| 739 | + $out = new stdClass(); | |
| 740 | + $out->{'count'} = $this->toCount(); | |
| 741 | + return $out; | |
| 742 | + } | |
| 743 | + | |
| 744 | + /** | |
| 745 | + * @param stdClass $obj | |
| 746 | + * @return FormatException | |
| 747 | + * @throws Exception | |
| 748 | + */ | |
| 749 | + public static function from(stdClass $obj): FormatException { | |
| 750 | + if (!property_exists($obj, 'count')) { | |
| 751 | + throw new Exception("Missing required property"); | |
| 752 | + } | |
| 753 | + return new FormatException( | |
| 754 | + FormatException::fromCount($obj->{'count'}) | |
| 755 | + ); | |
| 756 | + } | |
| 757 | + | |
| 758 | + /** | |
| 759 | + * @return FormatException | |
| 760 | + */ | |
| 761 | + public static function sample(): FormatException { | |
| 762 | + return new FormatException( | |
| 763 | + FormatException::sampleCount() | |
| 764 | + ); | |
| 765 | + } | |
| 766 | +} | |
| 767 | + | |
| 768 | +// This is an autogenerated file:RegExp | |
| 769 | + | |
| 770 | +class RegExp { | |
| 771 | + private bool $active; // json:active Required | |
| 772 | + | |
| 773 | + /** | |
| 774 | + * @param bool $active | |
| 775 | + */ | |
| 776 | + public function __construct(bool $active) { | |
| 777 | + $this->active = $active; | |
| 778 | + } | |
| 779 | + | |
| 780 | + /** | |
| 781 | + * @param bool $value | |
| 782 | + * @throws Exception | |
| 783 | + * @return bool | |
| 784 | + */ | |
| 785 | + public static function fromActive(bool $value): bool { | |
| 786 | + return $value; /*bool*/ | |
| 787 | + } | |
| 788 | + | |
| 789 | + /** | |
| 790 | + * @throws Exception | |
| 791 | + * @return bool | |
| 792 | + */ | |
| 793 | + public function toActive(): bool { | |
| 794 | + if (RegExp::validateActive($this->active)) { | |
| 795 | + return $this->active; /*bool*/ | |
| 796 | + } | |
| 797 | + throw new Exception('never get to this RegExp::active'); | |
| 798 | + } | |
| 799 | + | |
| 800 | + /** | |
| 801 | + * @param bool | |
| 802 | + * @return bool | |
| 803 | + * @throws Exception | |
| 804 | + */ | |
| 805 | + public static function validateActive(bool $value): bool { | |
| 806 | + return true; | |
| 807 | + } | |
| 808 | + | |
| 809 | + /** | |
| 810 | + * @throws Exception | |
| 811 | + * @return bool | |
| 812 | + */ | |
| 813 | + public function getActive(): bool { | |
| 814 | + if (RegExp::validateActive($this->active)) { | |
| 815 | + return $this->active; | |
| 816 | + } | |
| 817 | + throw new Exception('never get to getActive RegExp::active'); | |
| 818 | + } | |
| 819 | + | |
| 820 | + /** | |
| 821 | + * @return bool | |
| 822 | + */ | |
| 823 | + public static function sampleActive(): bool { | |
| 824 | + return true; /*31:active*/ | |
| 825 | + } | |
| 826 | + | |
| 827 | + /** | |
| 828 | + * @throws Exception | |
| 829 | + * @return bool | |
| 830 | + */ | |
| 831 | + public function validate(): bool { | |
| 832 | + return RegExp::validateActive($this->active); | |
| 833 | + } | |
| 834 | + | |
| 835 | + /** | |
| 836 | + * @return stdClass | |
| 837 | + * @throws Exception | |
| 838 | + */ | |
| 839 | + public function to(): stdClass { | |
| 840 | + $out = new stdClass(); | |
| 841 | + $out->{'active'} = $this->toActive(); | |
| 842 | + return $out; | |
| 843 | + } | |
| 844 | + | |
| 845 | + /** | |
| 846 | + * @param stdClass $obj | |
| 847 | + * @return RegExp | |
| 848 | + * @throws Exception | |
| 849 | + */ | |
| 850 | + public static function from(stdClass $obj): RegExp { | |
| 851 | + if (!property_exists($obj, 'active')) { | |
| 852 | + throw new Exception("Missing required property"); | |
| 853 | + } | |
| 854 | + return new RegExp( | |
| 855 | + RegExp::fromActive($obj->{'active'}) | |
| 856 | + ); | |
| 857 | + } | |
| 858 | + | |
| 859 | + /** | |
| 860 | + * @return RegExp | |
| 861 | + */ | |
| 862 | + public static function sample(): RegExp { | |
| 863 | + return new RegExp( | |
| 864 | + RegExp::sampleActive() | |
| 865 | + ); | |
| 866 | + } | |
| 867 | +} | |
| 868 | + | |
| 869 | +// This is an autogenerated file:Status | |
| 870 | + | |
| 871 | +class Status { | |
| 872 | + public static Status $READY; | |
| 873 | + public static Status $DONE; | |
| 874 | + public static function init() { | |
| 875 | + Status::$READY = new Status('ready'); | |
| 876 | + Status::$DONE = new Status('done'); | |
| 877 | + } | |
| 878 | + private string $enum; | |
| 879 | + public function __construct(string $enum) { | |
| 880 | + $this->enum = $enum; | |
| 881 | + } | |
| 882 | + | |
| 883 | + /** | |
| 884 | + * @param Status | |
| 885 | + * @return string | |
| 886 | + * @throws Exception | |
| 887 | + */ | |
| 888 | + public static function to(Status $obj): string { | |
| 889 | + switch ($obj->enum) { | |
| 890 | + case Status::$READY->enum: return 'ready'; | |
| 891 | + case Status::$DONE->enum: return 'done'; | |
| 892 | + } | |
| 893 | + throw new Exception('the give value is not an enum-value.'); | |
| 894 | + } | |
| 895 | + | |
| 896 | + /** | |
| 897 | + * @param mixed | |
| 898 | + * @return Status | |
| 899 | + * @throws Exception | |
| 900 | + */ | |
| 901 | + public static function from($obj): Status { | |
| 902 | + switch ($obj) { | |
| 903 | + case 'ready': return Status::$READY; | |
| 904 | + case 'done': return Status::$DONE; | |
| 905 | + } | |
| 906 | + throw new Exception("Cannot deserialize Status"); | |
| 907 | + } | |
| 908 | + | |
| 909 | + /** | |
| 910 | + * @return Status | |
| 911 | + */ | |
| 912 | + public static function sample(): Status { | |
| 913 | + return Status::$READY; | |
| 914 | + } | |
| 915 | +} | |
| 916 | +Status::init(); |
Aschema-pikedefault / TopLevel.pmod+145 −0
| @@ -0,0 +1,145 @@ | ||
| 1 | +// This source has been automatically generated by quicktype. | |
| 2 | +// ( https://github.com/quicktype/quicktype ) | |
| 3 | +// | |
| 4 | +// To use this code, simply import it into your project as a Pike module. | |
| 5 | +// To JSON-encode your object, you can pass it to `Standards.JSON.encode` | |
| 6 | +// or call `encode_json` on it. | |
| 7 | +// | |
| 8 | +// To decode a JSON string, first pass it to `Standards.JSON.decode`, | |
| 9 | +// and then pass the result to `<YourClass>_from_JSON`. | |
| 10 | +// It will return an instance of <YourClass>. | |
| 11 | +// Bear in mind that these functions have unexpected behavior, | |
| 12 | +// and will likely throw an error, if the JSON string does not | |
| 13 | +// match the expected interface, even if the JSON itself is valid. | |
| 14 | + | |
| 15 | +class TopLevel { | |
| 16 | + string code; // json: "code" | |
| 17 | + DateTime date_time; // json: "dateTime" | |
| 18 | + EnumValues enum_values; // json: "enumValues" | |
| 19 | + FormatException format_exception; // json: "formatException" | |
| 20 | + RegExp reg_exp; // json: "regExp" | |
| 21 | + Status status; // json: "status" | |
| 22 | + string timestamp; // json: "timestamp" | |
| 23 | + | |
| 24 | + string encode_json() { | |
| 25 | + mapping(string:mixed) json = ([ | |
| 26 | + "code" : code, | |
| 27 | + "dateTime" : date_time, | |
| 28 | + "enumValues" : enum_values, | |
| 29 | + "formatException" : format_exception, | |
| 30 | + "regExp" : reg_exp, | |
| 31 | + "status" : status, | |
| 32 | + "timestamp" : timestamp, | |
| 33 | + ]); | |
| 34 | + | |
| 35 | + return Standards.JSON.encode(json); | |
| 36 | + } | |
| 37 | +} | |
| 38 | + | |
| 39 | +TopLevel TopLevel_from_JSON(mixed json) { | |
| 40 | + TopLevel retval = TopLevel(); | |
| 41 | + | |
| 42 | + if (sizeof(json["code"]) < 1) error("String too short"); | |
| 43 | + if (!Regexp("^[a-z]+$")->match(json["code"])) error("String does not match pattern"); | |
| 44 | + retval.code = json["code"]; | |
| 45 | + retval.date_time = json["dateTime"]; | |
| 46 | + retval.enum_values = json["enumValues"]; | |
| 47 | + retval.format_exception = json["formatException"]; | |
| 48 | + retval.reg_exp = json["regExp"]; | |
| 49 | + retval.status = Status_from_JSON(json["status"]); | |
| 50 | + retval.timestamp = json["timestamp"]; | |
| 51 | + | |
| 52 | + return retval; | |
| 53 | +} | |
| 54 | + | |
| 55 | +class DateTime { | |
| 56 | + int value; // json: "value" | |
| 57 | + | |
| 58 | + string encode_json() { | |
| 59 | + mapping(string:mixed) json = ([ | |
| 60 | + "value" : value, | |
| 61 | + ]); | |
| 62 | + | |
| 63 | + return Standards.JSON.encode(json); | |
| 64 | + } | |
| 65 | +} | |
| 66 | + | |
| 67 | +DateTime DateTime_from_JSON(mixed json) { | |
| 68 | + DateTime retval = DateTime(); | |
| 69 | + | |
| 70 | + if (!intp(json["value"])) error("Expected integer"); | |
| 71 | + retval.value = json["value"]; | |
| 72 | + | |
| 73 | + return retval; | |
| 74 | +} | |
| 75 | + | |
| 76 | +class EnumValues { | |
| 77 | + string label; // json: "label" | |
| 78 | + | |
| 79 | + string encode_json() { | |
| 80 | + mapping(string:mixed) json = ([ | |
| 81 | + "label" : label, | |
| 82 | + ]); | |
| 83 | + | |
| 84 | + return Standards.JSON.encode(json); | |
| 85 | + } | |
| 86 | +} | |
| 87 | + | |
| 88 | +EnumValues EnumValues_from_JSON(mixed json) { | |
| 89 | + EnumValues retval = EnumValues(); | |
| 90 | + | |
| 91 | + retval.label = json["label"]; | |
| 92 | + | |
| 93 | + return retval; | |
| 94 | +} | |
| 95 | + | |
| 96 | +class FormatException { | |
| 97 | + int count; // json: "count" | |
| 98 | + | |
| 99 | + string encode_json() { | |
| 100 | + mapping(string:mixed) json = ([ | |
| 101 | + "count" : count, | |
| 102 | + ]); | |
| 103 | + | |
| 104 | + return Standards.JSON.encode(json); | |
| 105 | + } | |
| 106 | +} | |
| 107 | + | |
| 108 | +FormatException FormatException_from_JSON(mixed json) { | |
| 109 | + FormatException retval = FormatException(); | |
| 110 | + | |
| 111 | + if (!intp(json["count"])) error("Expected integer"); | |
| 112 | + retval.count = json["count"]; | |
| 113 | + | |
| 114 | + return retval; | |
| 115 | +} | |
| 116 | + | |
| 117 | +class RegExp { | |
| 118 | + bool active; // json: "active" | |
| 119 | + | |
| 120 | + string encode_json() { | |
| 121 | + mapping(string:mixed) json = ([ | |
| 122 | + "active" : active, | |
| 123 | + ]); | |
| 124 | + | |
| 125 | + return Standards.JSON.encode(json); | |
| 126 | + } | |
| 127 | +} | |
| 128 | + | |
| 129 | +RegExp RegExp_from_JSON(mixed json) { | |
| 130 | + RegExp retval = RegExp(); | |
| 131 | + | |
| 132 | + if (json["active"] != Standards.JSON.true && json["active"] != Standards.JSON.false) error("Expected bool"); | |
| 133 | + retval.active = json["active"]; | |
| 134 | + | |
| 135 | + return retval; | |
| 136 | +} | |
| 137 | + | |
| 138 | +enum Status { | |
| 139 | + READY = "ready", // json: "ready" | |
| 140 | + DONE = "done", // json: "done" | |
| 141 | +} | |
| 142 | + | |
| 143 | +Status Status_from_JSON(mixed json) { | |
| 144 | + if(json&&json != "ready"&&json != "done")error("enum");return json; | |
| 145 | +} |
Aschema-pythondefault / quicktype.py+149 −0
| @@ -0,0 +1,149 @@ | ||
| 1 | +import datetime | |
| 2 | +from dataclasses import dataclass | |
| 3 | +from typing import Any, TypeVar, Type, cast | |
| 4 | +from enum import Enum | |
| 5 | +import dateutil.parser | |
| 6 | + | |
| 7 | + | |
| 8 | +T = TypeVar("T") | |
| 9 | +EnumT = TypeVar("EnumT", bound=Enum) | |
| 10 | + | |
| 11 | + | |
| 12 | +def from_int(x: Any) -> int: | |
| 13 | + assert isinstance(x, int) and not isinstance(x, bool) | |
| 14 | + return x | |
| 15 | + | |
| 16 | + | |
| 17 | +def from_str(x: Any) -> str: | |
| 18 | + assert isinstance(x, str) | |
| 19 | + return x | |
| 20 | + | |
| 21 | + | |
| 22 | +def from_bool(x: Any) -> bool: | |
| 23 | + assert isinstance(x, bool) | |
| 24 | + return x | |
| 25 | + | |
| 26 | + | |
| 27 | +def from_datetime(x: Any) -> datetime.datetime: | |
| 28 | + return dateutil.parser.parse(x) | |
| 29 | + | |
| 30 | + | |
| 31 | +def to_class(c: Type[T], x: Any) -> dict: | |
| 32 | + assert isinstance(x, c) | |
| 33 | + return cast(Any, x).to_dict() | |
| 34 | + | |
| 35 | + | |
| 36 | +def to_enum(c: Type[EnumT], x: Any) -> EnumT: | |
| 37 | + assert isinstance(x, c) | |
| 38 | + return x.value | |
| 39 | + | |
| 40 | + | |
| 41 | +@dataclass | |
| 42 | +class DateTime: | |
| 43 | + value: int | |
| 44 | + | |
| 45 | + @staticmethod | |
| 46 | + def from_dict(obj: Any) -> 'DateTime': | |
| 47 | + assert isinstance(obj, dict) | |
| 48 | + value = from_int(obj.get("value")) | |
| 49 | + return DateTime(value) | |
| 50 | + | |
| 51 | + def to_dict(self) -> dict: | |
| 52 | + result: dict = {} | |
| 53 | + result["value"] = from_int(self.value) | |
| 54 | + return result | |
| 55 | + | |
| 56 | + | |
| 57 | +@dataclass | |
| 58 | +class EnumValues: | |
| 59 | + label: str | |
| 60 | + | |
| 61 | + @staticmethod | |
| 62 | + def from_dict(obj: Any) -> 'EnumValues': | |
| 63 | + assert isinstance(obj, dict) | |
| 64 | + label = from_str(obj.get("label")) | |
| 65 | + return EnumValues(label) | |
| 66 | + | |
| 67 | + def to_dict(self) -> dict: | |
| 68 | + result: dict = {} | |
| 69 | + result["label"] = from_str(self.label) | |
| 70 | + return result | |
| 71 | + | |
| 72 | + | |
| 73 | +@dataclass | |
| 74 | +class FormatException: | |
| 75 | + count: int | |
| 76 | + | |
| 77 | + @staticmethod | |
| 78 | + def from_dict(obj: Any) -> 'FormatException': | |
| 79 | + assert isinstance(obj, dict) | |
| 80 | + count = from_int(obj.get("count")) | |
| 81 | + return FormatException(count) | |
| 82 | + | |
| 83 | + def to_dict(self) -> dict: | |
| 84 | + result: dict = {} | |
| 85 | + result["count"] = from_int(self.count) | |
| 86 | + return result | |
| 87 | + | |
| 88 | + | |
| 89 | +@dataclass | |
| 90 | +class RegExp: | |
| 91 | + active: bool | |
| 92 | + | |
| 93 | + @staticmethod | |
| 94 | + def from_dict(obj: Any) -> 'RegExp': | |
| 95 | + assert isinstance(obj, dict) | |
| 96 | + active = from_bool(obj.get("active")) | |
| 97 | + return RegExp(active) | |
| 98 | + | |
| 99 | + def to_dict(self) -> dict: | |
| 100 | + result: dict = {} | |
| 101 | + result["active"] = from_bool(self.active) | |
| 102 | + return result | |
| 103 | + | |
| 104 | + | |
| 105 | +class Status(Enum): | |
| 106 | + READY = "ready" | |
| 107 | + DONE = "done" | |
| 108 | + | |
| 109 | + | |
| 110 | +@dataclass | |
| 111 | +class TopLevel: | |
| 112 | + code: str | |
| 113 | + date_time: DateTime | |
| 114 | + enum_values: EnumValues | |
| 115 | + format_exception: FormatException | |
| 116 | + reg_exp: RegExp | |
| 117 | + status: Status | |
| 118 | + timestamp: datetime.datetime | |
| 119 | + | |
| 120 | + @staticmethod | |
| 121 | + def from_dict(obj: Any) -> 'TopLevel': | |
| 122 | + assert isinstance(obj, dict) | |
| 123 | + code = from_str(obj.get("code")) | |
| 124 | + date_time = DateTime.from_dict(obj.get("dateTime")) | |
| 125 | + enum_values = EnumValues.from_dict(obj.get("enumValues")) | |
| 126 | + format_exception = FormatException.from_dict(obj.get("formatException")) | |
| 127 | + reg_exp = RegExp.from_dict(obj.get("regExp")) | |
| 128 | + status = Status(obj.get("status")) | |
| 129 | + timestamp = from_datetime(obj.get("timestamp")) | |
| 130 | + return TopLevel(code, date_time, enum_values, format_exception, reg_exp, status, timestamp) | |
| 131 | + | |
| 132 | + def to_dict(self) -> dict: | |
| 133 | + result: dict = {} | |
| 134 | + result["code"] = from_str(self.code) | |
| 135 | + result["dateTime"] = to_class(DateTime, self.date_time) | |
| 136 | + result["enumValues"] = to_class(EnumValues, self.enum_values) | |
| 137 | + result["formatException"] = to_class(FormatException, self.format_exception) | |
| 138 | + result["regExp"] = to_class(RegExp, self.reg_exp) | |
| 139 | + result["status"] = to_enum(Status, self.status) | |
| 140 | + result["timestamp"] = self.timestamp.isoformat() | |
| 141 | + return result | |
| 142 | + | |
| 143 | + | |
| 144 | +def top_level_from_dict(s: Any) -> TopLevel: | |
| 145 | + return TopLevel.from_dict(s) | |
| 146 | + | |
| 147 | + | |
| 148 | +def top_level_to_dict(x: TopLevel) -> Any: | |
| 149 | + return to_class(TopLevel, x) |
Aschema-rubydefault / TopLevel.rb+171 −0
| @@ -0,0 +1,171 @@ | ||
| 1 | +# This code may look unusually verbose for Ruby (and it is), but | |
| 2 | +# it performs some subtle and complex validation of JSON data. | |
| 3 | +# | |
| 4 | +# To parse this JSON, add 'dry-struct' and 'dry-types' gems, then do: | |
| 5 | +# | |
| 6 | +# top_level = TopLevel.from_json! "{…}" | |
| 7 | +# puts top_level.reg_exp.active | |
| 8 | +# | |
| 9 | +# If from_json! succeeds, the value returned matches the schema. | |
| 10 | + | |
| 11 | +require 'json' | |
| 12 | +require 'dry-types' | |
| 13 | +require 'dry-struct' | |
| 14 | + | |
| 15 | +module Types | |
| 16 | + include Dry.Types(default: :nominal) | |
| 17 | + | |
| 18 | + Integer = Strict::Integer | |
| 19 | + Bool = Strict::Bool | |
| 20 | + Hash = Strict::Hash | |
| 21 | + String = Strict::String | |
| 22 | + Status = Strict::String.enum("ready", "done") | |
| 23 | +end | |
| 24 | + | |
| 25 | +class DateTime < Dry::Struct | |
| 26 | + attribute :value, Types::Integer | |
| 27 | + | |
| 28 | + def self.from_dynamic!(d) | |
| 29 | + d = Types::Hash[d] | |
| 30 | + new( | |
| 31 | + value: d.fetch("value"), | |
| 32 | + ) | |
| 33 | + end | |
| 34 | + | |
| 35 | + def self.from_json!(json) | |
| 36 | + from_dynamic!(JSON.parse(json)) | |
| 37 | + end | |
| 38 | + | |
| 39 | + def to_dynamic | |
| 40 | + { | |
| 41 | + "value" => value, | |
| 42 | + } | |
| 43 | + end | |
| 44 | + | |
| 45 | + def to_json(options = nil) | |
| 46 | + JSON.generate(to_dynamic, options) | |
| 47 | + end | |
| 48 | +end | |
| 49 | + | |
| 50 | +class EnumValues < Dry::Struct | |
| 51 | + attribute :label, Types::String | |
| 52 | + | |
| 53 | + def self.from_dynamic!(d) | |
| 54 | + d = Types::Hash[d] | |
| 55 | + new( | |
| 56 | + label: d.fetch("label"), | |
| 57 | + ) | |
| 58 | + end | |
| 59 | + | |
| 60 | + def self.from_json!(json) | |
| 61 | + from_dynamic!(JSON.parse(json)) | |
| 62 | + end | |
| 63 | + | |
| 64 | + def to_dynamic | |
| 65 | + { | |
| 66 | + "label" => label, | |
| 67 | + } | |
| 68 | + end | |
| 69 | + | |
| 70 | + def to_json(options = nil) | |
| 71 | + JSON.generate(to_dynamic, options) | |
| 72 | + end | |
| 73 | +end | |
| 74 | + | |
| 75 | +class FormatException < Dry::Struct | |
| 76 | + attribute :count, Types::Integer | |
| 77 | + | |
| 78 | + def self.from_dynamic!(d) | |
| 79 | + d = Types::Hash[d] | |
| 80 | + new( | |
| 81 | + count: d.fetch("count"), | |
| 82 | + ) | |
| 83 | + end | |
| 84 | + | |
| 85 | + def self.from_json!(json) | |
| 86 | + from_dynamic!(JSON.parse(json)) | |
| 87 | + end | |
| 88 | + | |
| 89 | + def to_dynamic | |
| 90 | + { | |
| 91 | + "count" => count, | |
| 92 | + } | |
| 93 | + end | |
| 94 | + | |
| 95 | + def to_json(options = nil) | |
| 96 | + JSON.generate(to_dynamic, options) | |
| 97 | + end | |
| 98 | +end | |
| 99 | + | |
| 100 | +class RegExp < Dry::Struct | |
| 101 | + attribute :active, Types::Bool | |
| 102 | + | |
| 103 | + def self.from_dynamic!(d) | |
| 104 | + d = Types::Hash[d] | |
| 105 | + new( | |
| 106 | + active: d.fetch("active"), | |
| 107 | + ) | |
| 108 | + end | |
| 109 | + | |
| 110 | + def self.from_json!(json) | |
| 111 | + from_dynamic!(JSON.parse(json)) | |
| 112 | + end | |
| 113 | + | |
| 114 | + def to_dynamic | |
| 115 | + { | |
| 116 | + "active" => active, | |
| 117 | + } | |
| 118 | + end | |
| 119 | + | |
| 120 | + def to_json(options = nil) | |
| 121 | + JSON.generate(to_dynamic, options) | |
| 122 | + end | |
| 123 | +end | |
| 124 | + | |
| 125 | +module Status | |
| 126 | + Ready = "ready" | |
| 127 | + Done = "done" | |
| 128 | +end | |
| 129 | + | |
| 130 | +class TopLevel < Dry::Struct | |
| 131 | + attribute :code, Types::String.constrained(min_size: 1).constrained(format: Regexp.new("^[a-z]+$")) | |
| 132 | + attribute :date_time, DateTime | |
| 133 | + attribute :enum_values, EnumValues | |
| 134 | + attribute :format_exception, FormatException | |
| 135 | + attribute :reg_exp, RegExp | |
| 136 | + attribute :status, Types::Status | |
| 137 | + attribute :timestamp, Types::String.constrained(format: /\A\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(?:\.\d+)?(?:Z|[+-]\d\d:\d\d)\z/i) | |
| 138 | + | |
| 139 | + def self.from_dynamic!(d) | |
| 140 | + d = Types::Hash[d] | |
| 141 | + new( | |
| 142 | + code: d.fetch("code"), | |
| 143 | + date_time: DateTime.from_dynamic!(d.fetch("dateTime")), | |
| 144 | + enum_values: EnumValues.from_dynamic!(d.fetch("enumValues")), | |
| 145 | + format_exception: FormatException.from_dynamic!(d.fetch("formatException")), | |
| 146 | + reg_exp: RegExp.from_dynamic!(d.fetch("regExp")), | |
| 147 | + status: d.fetch("status"), | |
| 148 | + timestamp: d.fetch("timestamp"), | |
| 149 | + ) | |
| 150 | + end | |
| 151 | + | |
| 152 | + def self.from_json!(json) | |
| 153 | + from_dynamic!(JSON.parse(json)) | |
| 154 | + end | |
| 155 | + | |
| 156 | + def to_dynamic | |
| 157 | + { | |
| 158 | + "code" => code, | |
| 159 | + "dateTime" => date_time.to_dynamic, | |
| 160 | + "enumValues" => enum_values.to_dynamic, | |
| 161 | + "formatException" => format_exception.to_dynamic, | |
| 162 | + "regExp" => reg_exp.to_dynamic, | |
| 163 | + "status" => status, | |
| 164 | + "timestamp" => timestamp, | |
| 165 | + } | |
| 166 | + end | |
| 167 | + | |
| 168 | + def to_json(options = nil) | |
| 169 | + JSON.generate(to_dynamic, options) | |
| 170 | + end | |
| 171 | +end |
Aschema-rustdefault / module_under_test.rs+60 −0
| @@ -0,0 +1,60 @@ | ||
| 1 | +// Example code that deserializes and serializes the model. | |
| 2 | +// extern crate serde; | |
| 3 | +// #[macro_use] | |
| 4 | +// extern crate serde_derive; | |
| 5 | +// extern crate serde_json; | |
| 6 | +// | |
| 7 | +// use generated_module::TopLevel; | |
| 8 | +// | |
| 9 | +// fn main() { | |
| 10 | +// let json = r#"{"answer": 42}"#; | |
| 11 | +// let model: TopLevel = serde_json::from_str(&json).unwrap(); | |
| 12 | +// } | |
| 13 | + | |
| 14 | +use serde::{Serialize, Deserialize}; | |
| 15 | + | |
| 16 | +#[derive(Debug, Clone, Serialize, Deserialize)] | |
| 17 | +#[serde(rename_all = "camelCase")] | |
| 18 | +pub struct TopLevel { | |
| 19 | + pub code: String, | |
| 20 | + | |
| 21 | + pub date_time: DateTime, | |
| 22 | + | |
| 23 | + pub enum_values: EnumValues, | |
| 24 | + | |
| 25 | + pub format_exception: FormatException, | |
| 26 | + | |
| 27 | + pub reg_exp: RegExp, | |
| 28 | + | |
| 29 | + pub status: Status, | |
| 30 | + | |
| 31 | + pub timestamp: String, | |
| 32 | +} | |
| 33 | + | |
| 34 | +#[derive(Debug, Clone, Serialize, Deserialize)] | |
| 35 | +pub struct DateTime { | |
| 36 | + pub value: i64, | |
| 37 | +} | |
| 38 | + | |
| 39 | +#[derive(Debug, Clone, Serialize, Deserialize)] | |
| 40 | +pub struct EnumValues { | |
| 41 | + pub label: String, | |
| 42 | +} | |
| 43 | + | |
| 44 | +#[derive(Debug, Clone, Serialize, Deserialize)] | |
| 45 | +pub struct FormatException { | |
| 46 | + pub count: i64, | |
| 47 | +} | |
| 48 | + | |
| 49 | +#[derive(Debug, Clone, Serialize, Deserialize)] | |
| 50 | +pub struct RegExp { | |
| 51 | + pub active: bool, | |
| 52 | +} | |
| 53 | + | |
| 54 | +#[derive(Debug, Clone, Serialize, Deserialize)] | |
| 55 | +#[serde(rename_all = "snake_case")] | |
| 56 | +pub enum Status { | |
| 57 | + Ready, | |
| 58 | + | |
| 59 | + Done, | |
| 60 | +} |
Aschema-scala3-upickledefault / TopLevel.scala+110 −0
| @@ -0,0 +1,110 @@ | ||
| 1 | +package quicktype | |
| 2 | + | |
| 3 | +// Custom pickler so that missing keys and JSON nulls both read as None, | |
| 4 | +// and None is left out when writing (upickle's default for Option is a | |
| 5 | +// JSON array). | |
| 6 | +object OptionPickler extends upickle.AttributeTagged: | |
| 7 | + import upickle.default.Writer | |
| 8 | + import upickle.default.Reader | |
| 9 | + override implicit def OptionWriter[T: Writer]: Writer[Option[T]] = | |
| 10 | + implicitly[Writer[T]].comap[Option[T]] { | |
| 11 | + case None => null.asInstanceOf[T] | |
| 12 | + case Some(x) => x | |
| 13 | + } | |
| 14 | + | |
| 15 | + override implicit def OptionReader[T: Reader]: Reader[Option[T]] = { | |
| 16 | + new Reader.Delegate[Any, Option[T]](implicitly[Reader[T]].map(Some(_))){ | |
| 17 | + override def visitNull(index: Int) = None | |
| 18 | + } | |
| 19 | + } | |
| 20 | +end OptionPickler | |
| 21 | + | |
| 22 | +// If a union has a null in, then we'll need this too... | |
| 23 | +type NullValue = None.type | |
| 24 | +given OptionPickler.ReadWriter[NullValue] = OptionPickler.readwriter[ujson.Value].bimap[NullValue]( | |
| 25 | + _ => ujson.Null, | |
| 26 | + json => if json.isNull then None else throw new upickle.core.Abort("not null") | |
| 27 | +) | |
| 28 | +given OptionPickler.ReadWriter[java.time.Instant] = OptionPickler.readwriter[String].bimap(_.toString, java.time.Instant.parse) | |
| 29 | + | |
| 30 | +object JsonExt: | |
| 31 | + val valueReader = OptionPickler.readwriter[ujson.Value] | |
| 32 | + | |
| 33 | + // upickle's built-in primitive readers are lenient -- the numeric and | |
| 34 | + // boolean readers accept strings, and the string reader accepts | |
| 35 | + // numbers and booleans -- so untagged unions need strict readers to | |
| 36 | + // pick the right member. | |
| 37 | + val strictString: OptionPickler.Reader[String] = valueReader.map { | |
| 38 | + case ujson.Str(s) => s | |
| 39 | + case json => throw new upickle.core.Abort("expected string, got " + json) | |
| 40 | + } | |
| 41 | + val strictLong: OptionPickler.Reader[Long] = valueReader.map { | |
| 42 | + case ujson.Num(n) if n.isWhole => n.toLong | |
| 43 | + case json => throw new upickle.core.Abort("expected integer, got " + json) | |
| 44 | + } | |
| 45 | + val strictDouble: OptionPickler.Reader[Double] = valueReader.map { | |
| 46 | + case ujson.Num(n) => n | |
| 47 | + case json => throw new upickle.core.Abort("expected number, got " + json) | |
| 48 | + } | |
| 49 | + val strictBoolean: OptionPickler.Reader[Boolean] = valueReader.map { | |
| 50 | + case ujson.Bool(b) => b | |
| 51 | + case json => throw new upickle.core.Abort("expected boolean, got " + json) | |
| 52 | + } | |
| 53 | + | |
| 54 | + def badMerge[T](r1: => OptionPickler.Reader[?], rest: OptionPickler.Reader[?]*): OptionPickler.Reader[T] = valueReader.map { json => | |
| 55 | + var t: T | Null = null | |
| 56 | + val stack = Vector.newBuilder[Throwable] | |
| 57 | + (r1 +: rest).foreach { reader => | |
| 58 | + if t == null then | |
| 59 | + try | |
| 60 | + t = OptionPickler.read[T](json, trace = true)(using reader.asInstanceOf[OptionPickler.Reader[T]]) | |
| 61 | + catch | |
| 62 | + case exc => stack += exc | |
| 63 | + } | |
| 64 | + if t != null then t.nn else throw new Exception(json.toString(), stack.result().headOption.getOrElse(null)) | |
| 65 | + } | |
| 66 | +end JsonExt | |
| 67 | +given OptionPickler.Reader[Long] = JsonExt.strictLong | |
| 68 | + | |
| 69 | + | |
| 70 | +case class TopLevel ( | |
| 71 | + val code : String, | |
| 72 | + val dateTime : DateTime, | |
| 73 | + val enumValues : EnumValues, | |
| 74 | + val formatException : FormatException, | |
| 75 | + val regExp : RegExp, | |
| 76 | + val status : Status, | |
| 77 | + val timestamp : java.time.Instant | |
| 78 | +) derives OptionPickler.ReadWriter | |
| 79 | + | |
| 80 | +case class DateTime ( | |
| 81 | + val value : Long | |
| 82 | +) derives OptionPickler.ReadWriter | |
| 83 | + | |
| 84 | +case class EnumValues ( | |
| 85 | + val label : String | |
| 86 | +) derives OptionPickler.ReadWriter | |
| 87 | + | |
| 88 | +case class FormatException ( | |
| 89 | + val count : Long | |
| 90 | +) derives OptionPickler.ReadWriter | |
| 91 | + | |
| 92 | +case class RegExp ( | |
| 93 | + val active : Boolean | |
| 94 | +) derives OptionPickler.ReadWriter | |
| 95 | + | |
| 96 | +enum Status : | |
| 97 | + case Ready | |
| 98 | + case Done | |
| 99 | + | |
| 100 | +given OptionPickler.ReadWriter[Status] = OptionPickler.readwriter[String].bimap[Status]( | |
| 101 | + { | |
| 102 | + case Status.Ready => "ready" | |
| 103 | + case Status.Done => "done" | |
| 104 | + }, | |
| 105 | + { | |
| 106 | + case "ready" => Status.Ready | |
| 107 | + case "done" => Status.Done | |
| 108 | + case other => throw new upickle.core.Abort("invalid Status: " + other) | |
| 109 | + } | |
| 110 | +) |
Aschema-scala3default / TopLevel.scala+48 −0
| @@ -0,0 +1,48 @@ | ||
| 1 | +package quicktype | |
| 2 | + | |
| 3 | +import io.circe.syntax._ | |
| 4 | +import io.circe._ | |
| 5 | +import cats.syntax.functor._ | |
| 6 | + | |
| 7 | +// If a union has a null in, then we'll need this too... | |
| 8 | +type NullValue = None.type | |
| 9 | + | |
| 10 | +case class TopLevel ( | |
| 11 | + val code : String, | |
| 12 | + val dateTime : DateTime, | |
| 13 | + val enumValues : EnumValues, | |
| 14 | + val formatException : FormatException, | |
| 15 | + val regExp : RegExp, | |
| 16 | + val status : Status, | |
| 17 | + val timestamp : java.time.Instant | |
| 18 | +) derives Encoder.AsObject, Decoder | |
| 19 | + | |
| 20 | +case class DateTime ( | |
| 21 | + val value : Long | |
| 22 | +) derives Encoder.AsObject, Decoder | |
| 23 | + | |
| 24 | +case class EnumValues ( | |
| 25 | + val label : String | |
| 26 | +) derives Encoder.AsObject, Decoder | |
| 27 | + | |
| 28 | +case class FormatException ( | |
| 29 | + val count : Long | |
| 30 | +) derives Encoder.AsObject, Decoder | |
| 31 | + | |
| 32 | +case class RegExp ( | |
| 33 | + val active : Boolean | |
| 34 | +) derives Encoder.AsObject, Decoder | |
| 35 | + | |
| 36 | +enum Status : | |
| 37 | + case Ready | |
| 38 | + case Done | |
| 39 | + | |
| 40 | +given Decoder[Status] = Decoder.decodeString.emap { | |
| 41 | + case "ready" => scala.Right(Status.Ready) | |
| 42 | + case "done" => scala.Right(Status.Done) | |
| 43 | + case other => scala.Left("invalid Status: " + other) | |
| 44 | +} | |
| 45 | +given Encoder[Status] = Encoder.encodeString.contramap { | |
| 46 | + case Status.Ready => "ready" | |
| 47 | + case Status.Done => "done" | |
| 48 | +} |
Aschema-schemadefault / TopLevel.schema+106 −0
| @@ -0,0 +1,106 @@ | ||
| 1 | +{ | |
| 2 | + "$schema": "http://json-schema.org/draft-06/schema#", | |
| 3 | + "$ref": "#/definitions/TopLevel", | |
| 4 | + "definitions": { | |
| 5 | + "TopLevel": { | |
| 6 | + "type": "object", | |
| 7 | + "additionalProperties": false, | |
| 8 | + "properties": { | |
| 9 | + "code": { | |
| 10 | + "type": "string", | |
| 11 | + "minLength": 1, | |
| 12 | + "pattern": "^[a-z]+$" | |
| 13 | + }, | |
| 14 | + "dateTime": { | |
| 15 | + "$ref": "#/definitions/DateTime" | |
| 16 | + }, | |
| 17 | + "enumValues": { | |
| 18 | + "$ref": "#/definitions/EnumValues" | |
| 19 | + }, | |
| 20 | + "formatException": { | |
| 21 | + "$ref": "#/definitions/FormatException" | |
| 22 | + }, | |
| 23 | + "regExp": { | |
| 24 | + "$ref": "#/definitions/RegExp" | |
| 25 | + }, | |
| 26 | + "status": { | |
| 27 | + "$ref": "#/definitions/Status" | |
| 28 | + }, | |
| 29 | + "timestamp": { | |
| 30 | + "type": "string", | |
| 31 | + "format": "date-time" | |
| 32 | + } | |
| 33 | + }, | |
| 34 | + "required": [ | |
| 35 | + "code", | |
| 36 | + "dateTime", | |
| 37 | + "enumValues", | |
| 38 | + "formatException", | |
| 39 | + "regExp", | |
| 40 | + "status", | |
| 41 | + "timestamp" | |
| 42 | + ], | |
| 43 | + "title": "TopLevel" | |
| 44 | + }, | |
| 45 | + "DateTime": { | |
| 46 | + "type": "object", | |
| 47 | + "additionalProperties": {}, | |
| 48 | + "properties": { | |
| 49 | + "value": { | |
| 50 | + "type": "integer" | |
| 51 | + } | |
| 52 | + }, | |
| 53 | + "required": [ | |
| 54 | + "value" | |
| 55 | + ], | |
| 56 | + "title": "DateTime" | |
| 57 | + }, | |
| 58 | + "EnumValues": { | |
| 59 | + "type": "object", | |
| 60 | + "additionalProperties": {}, | |
| 61 | + "properties": { | |
| 62 | + "label": { | |
| 63 | + "type": "string" | |
| 64 | + } | |
| 65 | + }, | |
| 66 | + "required": [ | |
| 67 | + "label" | |
| 68 | + ], | |
| 69 | + "title": "EnumValues" | |
| 70 | + }, | |
| 71 | + "FormatException": { | |
| 72 | + "type": "object", | |
| 73 | + "additionalProperties": {}, | |
| 74 | + "properties": { | |
| 75 | + "count": { | |
| 76 | + "type": "integer" | |
| 77 | + } | |
| 78 | + }, | |
| 79 | + "required": [ | |
| 80 | + "count" | |
| 81 | + ], | |
| 82 | + "title": "FormatException" | |
| 83 | + }, | |
| 84 | + "RegExp": { | |
| 85 | + "type": "object", | |
| 86 | + "additionalProperties": {}, | |
| 87 | + "properties": { | |
| 88 | + "active": { | |
| 89 | + "type": "boolean" | |
| 90 | + } | |
| 91 | + }, | |
| 92 | + "required": [ | |
| 93 | + "active" | |
| 94 | + ], | |
| 95 | + "title": "RegExp" | |
| 96 | + }, | |
| 97 | + "Status": { | |
| 98 | + "type": "string", | |
| 99 | + "enum": [ | |
| 100 | + "ready", | |
| 101 | + "done" | |
| 102 | + ], | |
| 103 | + "title": "Status" | |
| 104 | + } | |
| 105 | + } | |
| 106 | +} |
Aschema-swiftdefault / quicktype.swift+291 −0
| @@ -0,0 +1,291 @@ | ||
| 1 | +// This file was generated from JSON Schema using quicktype, do not modify it directly. | |
| 2 | +// To parse the JSON, add this file to your project and do: | |
| 3 | +// | |
| 4 | +// let topLevel = try TopLevel(json) | |
| 5 | + | |
| 6 | +import Foundation | |
| 7 | + | |
| 8 | +// MARK: - TopLevel | |
| 9 | +struct TopLevel: Codable { | |
| 10 | + let code: String | |
| 11 | + let dateTime: DateTime | |
| 12 | + let enumValues: EnumValues | |
| 13 | + let formatException: FormatException | |
| 14 | + let regExp: RegExp | |
| 15 | + let status: Status | |
| 16 | + let timestamp: Date | |
| 17 | + | |
| 18 | + enum CodingKeys: String, CodingKey { | |
| 19 | + case code = "code" | |
| 20 | + case dateTime = "dateTime" | |
| 21 | + case enumValues = "enumValues" | |
| 22 | + case formatException = "formatException" | |
| 23 | + case regExp = "regExp" | |
| 24 | + case status = "status" | |
| 25 | + case timestamp = "timestamp" | |
| 26 | + } | |
| 27 | +} | |
| 28 | + | |
| 29 | +// MARK: TopLevel convenience initializers and mutators | |
| 30 | + | |
| 31 | +extension TopLevel { | |
| 32 | + init(data: Data) throws { | |
| 33 | + self = try newJSONDecoder().decode(TopLevel.self, from: data) | |
| 34 | + } | |
| 35 | + | |
| 36 | + init(_ json: String, using encoding: String.Encoding = .utf8) throws { | |
| 37 | + guard let data = json.data(using: encoding) else { | |
| 38 | + throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil) | |
| 39 | + } | |
| 40 | + try self.init(data: data) | |
| 41 | + } | |
| 42 | + | |
| 43 | + init(fromURL url: URL) throws { | |
| 44 | + try self.init(data: try Data(contentsOf: url)) | |
| 45 | + } | |
| 46 | + | |
| 47 | + func with( | |
| 48 | + code: String? = nil, | |
| 49 | + dateTime: DateTime? = nil, | |
| 50 | + enumValues: EnumValues? = nil, | |
| 51 | + formatException: FormatException? = nil, | |
| 52 | + regExp: RegExp? = nil, | |
| 53 | + status: Status? = nil, | |
| 54 | + timestamp: Date? = nil | |
| 55 | + ) -> TopLevel { | |
| 56 | + return TopLevel( | |
| 57 | + code: code ?? self.code, | |
| 58 | + dateTime: dateTime ?? self.dateTime, | |
| 59 | + enumValues: enumValues ?? self.enumValues, | |
| 60 | + formatException: formatException ?? self.formatException, | |
| 61 | + regExp: regExp ?? self.regExp, | |
| 62 | + status: status ?? self.status, | |
| 63 | + timestamp: timestamp ?? self.timestamp | |
| 64 | + ) | |
| 65 | + } | |
| 66 | + | |
| 67 | + func jsonData() throws -> Data { | |
| 68 | + return try newJSONEncoder().encode(self) | |
| 69 | + } | |
| 70 | + | |
| 71 | + func jsonString(encoding: String.Encoding = .utf8) throws -> String? { | |
| 72 | + return String(data: try self.jsonData(), encoding: encoding) | |
| 73 | + } | |
| 74 | +} | |
| 75 | + | |
| 76 | +// MARK: - DateTime | |
| 77 | +struct DateTime: Codable { | |
| 78 | + let value: Int | |
| 79 | + | |
| 80 | + enum CodingKeys: String, CodingKey { | |
| 81 | + case value = "value" | |
| 82 | + } | |
| 83 | +} | |
| 84 | + | |
| 85 | +// MARK: DateTime convenience initializers and mutators | |
| 86 | + | |
| 87 | +extension DateTime { | |
| 88 | + init(data: Data) throws { | |
| 89 | + self = try newJSONDecoder().decode(DateTime.self, from: data) | |
| 90 | + } | |
| 91 | + | |
| 92 | + init(_ json: String, using encoding: String.Encoding = .utf8) throws { | |
| 93 | + guard let data = json.data(using: encoding) else { | |
| 94 | + throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil) | |
| 95 | + } | |
| 96 | + try self.init(data: data) | |
| 97 | + } | |
| 98 | + | |
| 99 | + init(fromURL url: URL) throws { | |
| 100 | + try self.init(data: try Data(contentsOf: url)) | |
| 101 | + } | |
| 102 | + | |
| 103 | + func with( | |
| 104 | + value: Int? = nil | |
| 105 | + ) -> DateTime { | |
| 106 | + return DateTime( | |
| 107 | + value: value ?? self.value | |
| 108 | + ) | |
| 109 | + } | |
| 110 | + | |
| 111 | + func jsonData() throws -> Data { | |
| 112 | + return try newJSONEncoder().encode(self) | |
| 113 | + } | |
| 114 | + | |
| 115 | + func jsonString(encoding: String.Encoding = .utf8) throws -> String? { | |
| 116 | + return String(data: try self.jsonData(), encoding: encoding) | |
| 117 | + } | |
| 118 | +} | |
| 119 | + | |
| 120 | +// MARK: - EnumValues | |
| 121 | +struct EnumValues: Codable { | |
| 122 | + let label: String | |
| 123 | + | |
| 124 | + enum CodingKeys: String, CodingKey { | |
| 125 | + case label = "label" | |
| 126 | + } | |
| 127 | +} | |
| 128 | + | |
| 129 | +// MARK: EnumValues convenience initializers and mutators | |
| 130 | + | |
| 131 | +extension EnumValues { | |
| 132 | + init(data: Data) throws { | |
| 133 | + self = try newJSONDecoder().decode(EnumValues.self, from: data) | |
| 134 | + } | |
| 135 | + | |
| 136 | + init(_ json: String, using encoding: String.Encoding = .utf8) throws { | |
| 137 | + guard let data = json.data(using: encoding) else { | |
| 138 | + throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil) | |
| 139 | + } | |
| 140 | + try self.init(data: data) | |
| 141 | + } | |
| 142 | + | |
| 143 | + init(fromURL url: URL) throws { | |
| 144 | + try self.init(data: try Data(contentsOf: url)) | |
| 145 | + } | |
| 146 | + | |
| 147 | + func with( | |
| 148 | + label: String? = nil | |
| 149 | + ) -> EnumValues { | |
| 150 | + return EnumValues( | |
| 151 | + label: label ?? self.label | |
| 152 | + ) | |
| 153 | + } | |
| 154 | + | |
| 155 | + func jsonData() throws -> Data { | |
| 156 | + return try newJSONEncoder().encode(self) | |
| 157 | + } | |
| 158 | + | |
| 159 | + func jsonString(encoding: String.Encoding = .utf8) throws -> String? { | |
| 160 | + return String(data: try self.jsonData(), encoding: encoding) | |
| 161 | + } | |
| 162 | +} | |
| 163 | + | |
| 164 | +// MARK: - FormatException | |
| 165 | +struct FormatException: Codable { | |
| 166 | + let count: Int | |
| 167 | + | |
| 168 | + enum CodingKeys: String, CodingKey { | |
| 169 | + case count = "count" | |
| 170 | + } | |
| 171 | +} | |
| 172 | + | |
| 173 | +// MARK: FormatException convenience initializers and mutators | |
| 174 | + | |
| 175 | +extension FormatException { | |
| 176 | + init(data: Data) throws { | |
| 177 | + self = try newJSONDecoder().decode(FormatException.self, from: data) | |
| 178 | + } | |
| 179 | + | |
| 180 | + init(_ json: String, using encoding: String.Encoding = .utf8) throws { | |
| 181 | + guard let data = json.data(using: encoding) else { | |
| 182 | + throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil) | |
| 183 | + } | |
| 184 | + try self.init(data: data) | |
| 185 | + } | |
| 186 | + | |
| 187 | + init(fromURL url: URL) throws { | |
| 188 | + try self.init(data: try Data(contentsOf: url)) | |
| 189 | + } | |
| 190 | + | |
| 191 | + func with( | |
| 192 | + count: Int? = nil | |
| 193 | + ) -> FormatException { | |
| 194 | + return FormatException( | |
| 195 | + count: count ?? self.count | |
| 196 | + ) | |
| 197 | + } | |
| 198 | + | |
| 199 | + func jsonData() throws -> Data { | |
| 200 | + return try newJSONEncoder().encode(self) | |
| 201 | + } | |
| 202 | + | |
| 203 | + func jsonString(encoding: String.Encoding = .utf8) throws -> String? { | |
| 204 | + return String(data: try self.jsonData(), encoding: encoding) | |
| 205 | + } | |
| 206 | +} | |
| 207 | + | |
| 208 | +// MARK: - RegExp | |
| 209 | +struct RegExp: Codable { | |
| 210 | + let active: Bool | |
| 211 | + | |
| 212 | + enum CodingKeys: String, CodingKey { | |
| 213 | + case active = "active" | |
| 214 | + } | |
| 215 | +} | |
| 216 | + | |
| 217 | +// MARK: RegExp convenience initializers and mutators | |
| 218 | + | |
| 219 | +extension RegExp { | |
| 220 | + init(data: Data) throws { | |
| 221 | + self = try newJSONDecoder().decode(RegExp.self, from: data) | |
| 222 | + } | |
| 223 | + | |
| 224 | + init(_ json: String, using encoding: String.Encoding = .utf8) throws { | |
| 225 | + guard let data = json.data(using: encoding) else { | |
| 226 | + throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil) | |
| 227 | + } | |
| 228 | + try self.init(data: data) | |
| 229 | + } | |
| 230 | + | |
| 231 | + init(fromURL url: URL) throws { | |
| 232 | + try self.init(data: try Data(contentsOf: url)) | |
| 233 | + } | |
| 234 | + | |
| 235 | + func with( | |
| 236 | + active: Bool? = nil | |
| 237 | + ) -> RegExp { | |
| 238 | + return RegExp( | |
| 239 | + active: active ?? self.active | |
| 240 | + ) | |
| 241 | + } | |
| 242 | + | |
| 243 | + func jsonData() throws -> Data { | |
| 244 | + return try newJSONEncoder().encode(self) | |
| 245 | + } | |
| 246 | + | |
| 247 | + func jsonString(encoding: String.Encoding = .utf8) throws -> String? { | |
| 248 | + return String(data: try self.jsonData(), encoding: encoding) | |
| 249 | + } | |
| 250 | +} | |
| 251 | + | |
| 252 | +enum Status: String, Codable { | |
| 253 | + case ready = "ready" | |
| 254 | + case done = "done" | |
| 255 | +} | |
| 256 | + | |
| 257 | +// MARK: - Helper functions for creating encoders and decoders | |
| 258 | + | |
| 259 | +func newJSONDecoder() -> JSONDecoder { | |
| 260 | + let decoder = JSONDecoder() | |
| 261 | + decoder.dateDecodingStrategy = .custom({ (decoder) -> Date in | |
| 262 | + let container = try decoder.singleValueContainer() | |
| 263 | + let dateStr = try container.decode(String.self) | |
| 264 | + | |
| 265 | + let formatter = DateFormatter() | |
| 266 | + formatter.calendar = Calendar(identifier: .iso8601) | |
| 267 | + formatter.locale = Locale(identifier: "en_US_POSIX") | |
| 268 | + formatter.timeZone = TimeZone(secondsFromGMT: 0) | |
| 269 | + formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX" | |
| 270 | + if let date = formatter.date(from: dateStr) { | |
| 271 | + return date | |
| 272 | + } | |
| 273 | + formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssXXXXX" | |
| 274 | + if let date = formatter.date(from: dateStr) { | |
| 275 | + return date | |
| 276 | + } | |
| 277 | + throw DecodingError.typeMismatch(Date.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Could not decode date")) | |
| 278 | + }) | |
| 279 | + return decoder | |
| 280 | +} | |
| 281 | + | |
| 282 | +func newJSONEncoder() -> JSONEncoder { | |
| 283 | + let encoder = JSONEncoder() | |
| 284 | + let formatter = DateFormatter() | |
| 285 | + formatter.calendar = Calendar(identifier: .iso8601) | |
| 286 | + formatter.locale = Locale(identifier: "en_US_POSIX") | |
| 287 | + formatter.timeZone = TimeZone(secondsFromGMT: 0) | |
| 288 | + formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSXXXXX" | |
| 289 | + encoder.dateEncodingStrategy = .formatted(formatter) | |
| 290 | + return encoder | |
| 291 | +} |
Aschema-typescript-effect-schemadefault / TopLevel.ts+34 −0
| @@ -0,0 +1,34 @@ | ||
| 1 | +import * as S from "effect/Schema"; | |
| 2 | + | |
| 3 | + | |
| 4 | +export const Status = S.Literal( | |
| 5 | + "ready", | |
| 6 | + "done", | |
| 7 | +); | |
| 8 | +export type Status = S.Schema.Type<typeof Status>; | |
| 9 | + | |
| 10 | +export class RegExp extends S.Class<RegExp>("RegExp")({ | |
| 11 | + "active": S.Boolean, | |
| 12 | +}) {} | |
| 13 | + | |
| 14 | +export class FormatException extends S.Class<FormatException>("FormatException")({ | |
| 15 | + "count": S.Int, | |
| 16 | +}) {} | |
| 17 | + | |
| 18 | +export class EnumValues extends S.Class<EnumValues>("EnumValues")({ | |
| 19 | + "label": S.String, | |
| 20 | +}) {} | |
| 21 | + | |
| 22 | +export class DateTime extends S.Class<DateTime>("DateTime")({ | |
| 23 | + "value": S.Int, | |
| 24 | +}) {} | |
| 25 | + | |
| 26 | +export class TopLevel extends S.Class<TopLevel>("TopLevel")({ | |
| 27 | + "code": S.String.pipe(S.minLength(1)).pipe(S.pattern(new RegExp("^[a-z]+$"))), | |
| 28 | + "dateTime": DateTime, | |
| 29 | + "enumValues": EnumValues, | |
| 30 | + "formatException": FormatException, | |
| 31 | + "regExp": RegExp, | |
| 32 | + "status": Status, | |
| 33 | + "timestamp": S.String.pipe(S.pattern(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/)), | |
| 34 | +}) {} |
Aschema-typescript-zoddefault / TopLevel.ts+39 −0
| @@ -0,0 +1,39 @@ | ||
| 1 | +import * as z from "zod"; | |
| 2 | + | |
| 3 | + | |
| 4 | +export const StatusSchema = z.enum([ | |
| 5 | + "ready", | |
| 6 | + "done", | |
| 7 | +]); | |
| 8 | +export type Status = z.infer<typeof StatusSchema>; | |
| 9 | + | |
| 10 | +export const DateTimeSchema = z.object({ | |
| 11 | + "value": z.number().int(), | |
| 12 | +}); | |
| 13 | +export type DateTime = z.infer<typeof DateTimeSchema>; | |
| 14 | + | |
| 15 | +export const EnumValuesSchema = z.object({ | |
| 16 | + "label": z.string(), | |
| 17 | +}); | |
| 18 | +export type EnumValues = z.infer<typeof EnumValuesSchema>; | |
| 19 | + | |
| 20 | +export const FormatExceptionSchema = z.object({ | |
| 21 | + "count": z.number().int(), | |
| 22 | +}); | |
| 23 | +export type FormatException = z.infer<typeof FormatExceptionSchema>; | |
| 24 | + | |
| 25 | +export const RegExpSchema = z.object({ | |
| 26 | + "active": z.boolean(), | |
| 27 | +}); | |
| 28 | +export type RegExp = z.infer<typeof RegExpSchema>; | |
| 29 | + | |
| 30 | +export const TopLevelSchema = z.object({ | |
| 31 | + "code": z.string().min(1).regex(new RegExp("^[a-z]+$")), | |
| 32 | + "dateTime": DateTimeSchema, | |
| 33 | + "enumValues": EnumValuesSchema, | |
| 34 | + "formatException": FormatExceptionSchema, | |
| 35 | + "regExp": RegExpSchema, | |
| 36 | + "status": StatusSchema, | |
| 37 | + "timestamp": z.coerce.date(), | |
| 38 | +}); | |
| 39 | +export type TopLevel = z.infer<typeof TopLevelSchema>; |
Aschema-typescriptdefault / TopLevel.ts+254 −0
| @@ -0,0 +1,254 @@ | ||
| 1 | +// To parse this data: | |
| 2 | +// | |
| 3 | +// import { Convert, TopLevel } from "./TopLevel"; | |
| 4 | +// | |
| 5 | +// const topLevel = Convert.toTopLevel(json); | |
| 6 | +// | |
| 7 | +// These functions will throw an error if the JSON doesn't | |
| 8 | +// match the expected interface, even if the JSON is valid. | |
| 9 | + | |
| 10 | +export interface TopLevel { | |
| 11 | + code: string; | |
| 12 | + dateTime: DateTime; | |
| 13 | + enumValues: EnumValues; | |
| 14 | + formatException: FormatException; | |
| 15 | + regExp: RegExp; | |
| 16 | + status: Status; | |
| 17 | + timestamp: Date; | |
| 18 | +} | |
| 19 | + | |
| 20 | +export interface DateTime { | |
| 21 | + value: number; | |
| 22 | + [property: string]: unknown | number; | |
| 23 | +} | |
| 24 | + | |
| 25 | +export interface EnumValues { | |
| 26 | + label: string; | |
| 27 | + [property: string]: unknown | string; | |
| 28 | +} | |
| 29 | + | |
| 30 | +export interface FormatException { | |
| 31 | + count: number; | |
| 32 | + [property: string]: unknown | number; | |
| 33 | +} | |
| 34 | + | |
| 35 | +export interface RegExp { | |
| 36 | + active: boolean; | |
| 37 | + [property: string]: unknown | boolean; | |
| 38 | +} | |
| 39 | + | |
| 40 | +export type Status = "ready" | "done"; | |
| 41 | + | |
| 42 | +// Converts JSON strings to/from your types | |
| 43 | +// and asserts the results of JSON.parse at runtime | |
| 44 | +export class Convert { | |
| 45 | + public static toTopLevel(json: string): TopLevel { | |
| 46 | + return cast(JSON.parse(json), r("TopLevel")); | |
| 47 | + } | |
| 48 | + | |
| 49 | + public static topLevelToJson(value: TopLevel): string { | |
| 50 | + return JSON.stringify(uncast(value, r("TopLevel")), null, 2); | |
| 51 | + } | |
| 52 | +} | |
| 53 | + | |
| 54 | +function invalidValue(typ: any, val: any, key: any, parent: any = ''): never { | |
| 55 | + const prettyTyp = prettyTypeName(typ); | |
| 56 | + const parentText = parent ? ` on ${parent}` : ''; | |
| 57 | + const keyText = key ? ` for key "${key}"` : ''; | |
| 58 | + throw Error(`Invalid value${keyText}${parentText}. Expected ${prettyTyp} but got ${JSON.stringify(val)}`); | |
| 59 | +} | |
| 60 | + | |
| 61 | +function prettyTypeName(typ: any): string { | |
| 62 | + if (Array.isArray(typ)) { | |
| 63 | + if (typ.length === 2 && typ[0] === undefined) { | |
| 64 | + return `an optional ${prettyTypeName(typ[1])}`; | |
| 65 | + } else { | |
| 66 | + return `one of [${typ.map(a => { return prettyTypeName(a); }).join(", ")}]`; | |
| 67 | + } | |
| 68 | + } else if (typeof typ === "object" && typ.literal !== undefined) { | |
| 69 | + return typ.literal; | |
| 70 | + } else { | |
| 71 | + return typeof typ; | |
| 72 | + } | |
| 73 | +} | |
| 74 | + | |
| 75 | +function jsonToJSProps(typ: any): any { | |
| 76 | + if (typ.jsonToJS === undefined) { | |
| 77 | + const map: any = {}; | |
| 78 | + typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ }); | |
| 79 | + typ.jsonToJS = map; | |
| 80 | + } | |
| 81 | + return typ.jsonToJS; | |
| 82 | +} | |
| 83 | + | |
| 84 | +function jsToJSONProps(typ: any): any { | |
| 85 | + if (typ.jsToJSON === undefined) { | |
| 86 | + const map: any = {}; | |
| 87 | + typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ }); | |
| 88 | + typ.jsToJSON = map; | |
| 89 | + } | |
| 90 | + return typ.jsToJSON; | |
| 91 | +} | |
| 92 | + | |
| 93 | +function transform(val: any, typ: any, getProps: any, key: any = '', parent: any = ''): any { | |
| 94 | + function transformPrimitive(typ: string, val: any): any { | |
| 95 | + if (typeof typ === typeof val) return val; | |
| 96 | + return invalidValue(typ, val, key, parent); | |
| 97 | + } | |
| 98 | + | |
| 99 | + function transformUnion(typs: any[], val: any): any { | |
| 100 | + // val must validate against one typ in typs | |
| 101 | + const l = typs.length; | |
| 102 | + for (let i = 0; i < l; i++) { | |
| 103 | + const typ = typs[i]; | |
| 104 | + try { | |
| 105 | + return transform(val, typ, getProps); | |
| 106 | + } catch (_) {} | |
| 107 | + } | |
| 108 | + return invalidValue(typs, val, key, parent); | |
| 109 | + } | |
| 110 | + | |
| 111 | + function transformEnum(cases: string[], val: any): any { | |
| 112 | + if (cases.indexOf(val) !== -1) return val; | |
| 113 | + return invalidValue(cases.map(a => { return l(a); }), val, key, parent); | |
| 114 | + } | |
| 115 | + | |
| 116 | + function transformArray(typ: any, val: any): any { | |
| 117 | + // val must be an array with no invalid elements | |
| 118 | + if (!Array.isArray(val)) return invalidValue(l("array"), val, key, parent); | |
| 119 | + | |
| 120 | + return val.map(el => transform(el, typ, getProps)); | |
| 121 | + } | |
| 122 | + | |
| 123 | + function transformDate(val: any): any { | |
| 124 | + if (val === null) { | |
| 125 | + return null; | |
| 126 | + } | |
| 127 | + const d = new Date(val); | |
| 128 | + if (isNaN(d.valueOf())) { | |
| 129 | + return invalidValue(l("Date"), val, key, parent); | |
| 130 | + } | |
| 131 | + return d; | |
| 132 | + } | |
| 133 | + | |
| 134 | + function transformObject(props: { [k: string]: any }, additional: any, val: any): any { | |
| 135 | + if (val === null || typeof val !== "object" || Array.isArray(val)) { | |
| 136 | + return invalidValue(l(ref || "object"), val, key, parent); | |
| 137 | + } | |
| 138 | + const result: any = {}; | |
| 139 | + Object.getOwnPropertyNames(props).forEach(key => { | |
| 140 | + const prop = props[key]; | |
| 141 | + const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined; | |
| 142 | + result[prop.key] = transform(v, prop.typ, getProps, key, ref); | |
| 143 | + }); | |
| 144 | + Object.getOwnPropertyNames(val).forEach(key => { | |
| 145 | + if (!Object.prototype.hasOwnProperty.call(props, key)) { | |
| 146 | + result[key] = transform(val[key], additional, getProps, key, ref); | |
| 147 | + } | |
| 148 | + }); | |
| 149 | + return result; | |
| 150 | + } | |
| 151 | + | |
| 152 | + if (typ === "any") return val; | |
| 153 | + if (typ === null) { | |
| 154 | + if (val === null) return val; | |
| 155 | + return invalidValue(typ, val, key, parent); | |
| 156 | + } | |
| 157 | + if (typ === false) return invalidValue(typ, val, key, parent); | |
| 158 | + let ref: any = undefined; | |
| 159 | + while (typeof typ === "object" && typ.ref !== undefined) { | |
| 160 | + ref = typ.ref; | |
| 161 | + typ = typeMap[typ.ref]; | |
| 162 | + } | |
| 163 | + if (Array.isArray(typ)) return transformEnum(typ, val); | |
| 164 | + if (typeof typ === "object") { | |
| 165 | + return typ.hasOwnProperty("pattern") ? typeof val === "string" && new RegExp(typ.pattern).test(val) ? val : invalidValue(typ, val, key, parent) | |
| 166 | + : typ.hasOwnProperty("string") ? typeof val === "string" && (typ.min === undefined || val.length >= typ.min) && (typ.max === undefined || val.length <= typ.max) ? transform(val, typ.string, getProps, key, parent) : invalidValue(typ, val, key, parent) | |
| 167 | + : typ.hasOwnProperty("number") ? typeof val === "number" && (typ.min === undefined || val >= typ.min) && (typ.max === undefined || val <= typ.max) ? transform(val, typ.number, getProps, key, parent) : invalidValue(typ, val, key, parent) | |
| 168 | + : typ.hasOwnProperty("integer") ? typeof val === "number" && val % 1 === 0 ? val : invalidValue(l("integer"), val, key, parent) | |
| 169 | + : typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val) | |
| 170 | + : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) | |
| 171 | + : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) | |
| 172 | + : invalidValue(typ, val, key, parent); | |
| 173 | + } | |
| 174 | + // Numbers can be parsed by Date but shouldn't be. | |
| 175 | + if (typ === Date && typeof val !== "number") return transformDate(val); | |
| 176 | + return transformPrimitive(typ, val); | |
| 177 | +} | |
| 178 | + | |
| 179 | +function cast<T>(val: any, typ: any): T { | |
| 180 | + return transform(val, typ, jsonToJSProps); | |
| 181 | +} | |
| 182 | + | |
| 183 | +function uncast<T>(val: T, typ: any): any { | |
| 184 | + return transform(val, typ, jsToJSONProps); | |
| 185 | +} | |
| 186 | + | |
| 187 | +function l(typ: any) { | |
| 188 | + return { literal: typ }; | |
| 189 | +} | |
| 190 | + | |
| 191 | +function a(typ: any) { | |
| 192 | + return { arrayItems: typ }; | |
| 193 | +} | |
| 194 | + | |
| 195 | +function i(typ: any) { | |
| 196 | + return { integer: typ }; | |
| 197 | +} | |
| 198 | + | |
| 199 | +function p(pattern: any) { | |
| 200 | + return { pattern }; | |
| 201 | +} | |
| 202 | + | |
| 203 | +function s(typ: any, min: any, max: any) { | |
| 204 | + return { string: typ, min, max }; | |
| 205 | +} | |
| 206 | + | |
| 207 | +function n(typ: any, min: any, max: any) { | |
| 208 | + return { number: typ, min, max }; | |
| 209 | +} | |
| 210 | + | |
| 211 | +function u(...typs: any[]) { | |
| 212 | + return { unionMembers: typs }; | |
| 213 | +} | |
| 214 | + | |
| 215 | +function o(props: any[], additional: any) { | |
| 216 | + return { props, additional }; | |
| 217 | +} | |
| 218 | + | |
| 219 | +function m(additional: any) { | |
| 220 | + const props: any[] = []; | |
| 221 | + return { props, additional }; | |
| 222 | +} | |
| 223 | + | |
| 224 | +function r(name: string) { | |
| 225 | + return { ref: name }; | |
| 226 | +} | |
| 227 | + | |
| 228 | +const typeMap: any = { | |
| 229 | + "TopLevel": o([ | |
| 230 | + { json: "code", js: "code", typ: s(p("^[a-z]+$"), 1, undefined) }, | |
| 231 | + { json: "dateTime", js: "dateTime", typ: r("DateTime") }, | |
| 232 | + { json: "enumValues", js: "enumValues", typ: r("EnumValues") }, | |
| 233 | + { json: "formatException", js: "formatException", typ: r("FormatException") }, | |
| 234 | + { json: "regExp", js: "regExp", typ: r("RegExp") }, | |
| 235 | + { json: "status", js: "status", typ: r("Status") }, | |
| 236 | + { json: "timestamp", js: "timestamp", typ: Date }, | |
| 237 | + ], false), | |
| 238 | + "DateTime": o([ | |
| 239 | + { json: "value", js: "value", typ: i(0) }, | |
| 240 | + ], "any"), | |
| 241 | + "EnumValues": o([ | |
| 242 | + { json: "label", js: "label", typ: "" }, | |
| 243 | + ], "any"), | |
| 244 | + "FormatException": o([ | |
| 245 | + { json: "count", js: "count", typ: i(0) }, | |
| 246 | + ], "any"), | |
| 247 | + "RegExp": o([ | |
| 248 | + { json: "active", js: "active", typ: true }, | |
| 249 | + ], "any"), | |
| 250 | + "Status": [ | |
| 251 | + "ready", | |
| 252 | + "done", | |
| 253 | + ], | |
| 254 | +}; |
Test case
1 generated file · +3 −3test/inputs/schema/vega-lite.schema
Mschema-dartdefault / TopLevel.dart+3 −3
| @@ -4840,7 +4840,7 @@ class Predicate { | ||
| 4840 | 4840 | ///If both month and quarter are provided, month has higher precedence. |
| 4841 | 4841 | ///`day` cannot be combined with other date. |
| 4842 | 4842 | ///We accept string for month and day names. |
| 4843 | -class DateTime { | |
| 4843 | +class DateTimeClass { | |
| 4844 | 4844 | |
| 4845 | 4845 | ///Integer value representing the date from 1-31. |
| 4846 | 4846 | final double? date; |
| @@ -4879,7 +4879,7 @@ class DateTime { | ||
| 4879 | 4879 | ///Integer value representing the year. |
| 4880 | 4880 | final double? year; |
| 4881 | 4881 | |
| 4882 | - DateTime({ | |
| 4882 | + DateTimeClass({ | |
| 4883 | 4883 | this.date, |
| 4884 | 4884 | this.day, |
| 4885 | 4885 | this.hours, |
| @@ -4892,7 +4892,7 @@ class DateTime { | ||
| 4892 | 4892 | this.year, |
| 4893 | 4893 | }); |
| 4894 | 4894 | |
| 4895 | - factory DateTime.fromJson(Map<String, dynamic> json) => DateTime( | |
| 4895 | + factory DateTimeClass.fromJson(Map<String, dynamic> json) => DateTimeClass( | |
| 4896 | 4896 | date: json["date"]?.toDouble() == null ? null : ((x) => x >= 1 && x <= 31 ? x : throw FormatException("Expected bounded number"))(json["date"]?.toDouble()), |
| 4897 | 4897 | day: json["day"], |
| 4898 | 4898 | hours: json["hours"]?.toDouble() == null ? null : ((x) => x >= 0 && x <= 23 ? x : throw FormatException("Expected bounded number"))(json["hours"]?.toDouble()), |
No generated files match these filters.