Aschema-cjson/test/inputs/schema/anyof-object-union.schema/default/TopLevel.c+407 −0
| @@ -0,0 +1,407 @@ | ||
| 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 | +struct SecondProperty * cJSON_GetSecondPropertyValue(const cJSON * j) { | |
| 9 | + struct SecondProperty * x = cJSON_malloc(sizeof(struct SecondProperty)); | |
| 10 | + if (NULL != x) { | |
| 11 | + memset(x, 0, sizeof(struct SecondProperty)); | |
| 12 | + if (cJSON_IsArray(j)) { | |
| 13 | + x->type = cJSON_Array; | |
| 14 | + list_t * x1 = list_create(false, NULL); | |
| 15 | + if (NULL != x1) { | |
| 16 | + cJSON * e1 = NULL; | |
| 17 | + cJSON_ArrayForEach(e1, j) { | |
| 18 | + list_add_tail(x1, cJSON_GetMyObjectAValue(e1), sizeof(struct MyObjectA *)); | |
| 19 | + } | |
| 20 | + x->value.my_object_a_array = x1; | |
| 21 | + } | |
| 22 | + } | |
| 23 | + else if (cJSON_IsObject(j)) { | |
| 24 | + x->type = cJSON_Object; | |
| 25 | + x->value.my_object_b = cJSON_GetMyObjectBValue(j); | |
| 26 | + } | |
| 27 | + } | |
| 28 | + return x; | |
| 29 | +} | |
| 30 | + | |
| 31 | +cJSON * cJSON_CreateSecondProperty(const struct SecondProperty * x) { | |
| 32 | + cJSON * j = NULL; | |
| 33 | + if (NULL != x) { | |
| 34 | + if (cJSON_Array == x->type) { | |
| 35 | + cJSON * j1 = cJSON_CreateArray(); | |
| 36 | + if (NULL != j1) { | |
| 37 | + struct MyObjectA * x1 = list_get_head(x->value.my_object_a_array); | |
| 38 | + while (NULL != x1) { | |
| 39 | + cJSON_AddItemToArray(j1, cJSON_CreateMyObjectA(x1)); | |
| 40 | + x1 = list_get_next(x->value.my_object_a_array); | |
| 41 | + } | |
| 42 | + j = j1; | |
| 43 | + } | |
| 44 | + } | |
| 45 | + else if (cJSON_Object == x->type) { | |
| 46 | + j = cJSON_CreateMyObjectB(x->value.my_object_b); | |
| 47 | + } | |
| 48 | + } | |
| 49 | + return j; | |
| 50 | +} | |
| 51 | + | |
| 52 | +void cJSON_DeleteSecondProperty(struct SecondProperty * x) { | |
| 53 | + if (NULL != x) { | |
| 54 | + if (cJSON_Array == x->type) { | |
| 55 | + if (NULL != x->value.my_object_a_array) { | |
| 56 | + struct MyObjectA * x1 = list_get_head(x->value.my_object_a_array); | |
| 57 | + while (NULL != x1) { | |
| 58 | + cJSON_DeleteMyObjectA(x1); | |
| 59 | + x1 = list_get_next(x->value.my_object_a_array); | |
| 60 | + } | |
| 61 | + list_release(x->value.my_object_a_array); | |
| 62 | + } | |
| 63 | + } | |
| 64 | + else if (cJSON_Object == x->type) { | |
| 65 | + cJSON_DeleteMyObjectB(x->value.my_object_b); | |
| 66 | + } | |
| 67 | + cJSON_free(x); | |
| 68 | + } | |
| 69 | +} | |
| 70 | + | |
| 71 | +struct MyObject * cJSON_ParseMyObject(const char * s) { | |
| 72 | + struct MyObject * x = NULL; | |
| 73 | + if (NULL != s) { | |
| 74 | + cJSON * j = cJSON_Parse(s); | |
| 75 | + if (NULL != j) { | |
| 76 | + x = cJSON_GetMyObjectValue(j); | |
| 77 | + cJSON_Delete(j); | |
| 78 | + } | |
| 79 | + } | |
| 80 | + return x; | |
| 81 | +} | |
| 82 | + | |
| 83 | +struct MyObject * cJSON_GetMyObjectValue(const cJSON * j) { | |
| 84 | + struct MyObject * x = NULL; | |
| 85 | + if (NULL != j) { | |
| 86 | + if (NULL != (x = cJSON_malloc(sizeof(struct MyObject)))) { | |
| 87 | + memset(x, 0, sizeof(struct MyObject)); | |
| 88 | + if (cJSON_HasObjectItem(j, "a")) { | |
| 89 | + x->a = strdup(cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(j, "a"))); | |
| 90 | + } | |
| 91 | + if (cJSON_HasObjectItem(j, "b")) { | |
| 92 | + if (NULL != (x->b = cJSON_malloc(sizeof(double)))) { | |
| 93 | + *x->b = cJSON_GetNumberValue(cJSON_GetObjectItemCaseSensitive(j, "b")); | |
| 94 | + } | |
| 95 | + } | |
| 96 | + if (cJSON_HasObjectItem(j, "c")) { | |
| 97 | + if (NULL != (x->c = cJSON_malloc(sizeof(bool)))) { | |
| 98 | + *x->c = cJSON_IsTrue(cJSON_GetObjectItemCaseSensitive(j, "c")); | |
| 99 | + } | |
| 100 | + } | |
| 101 | + if (cJSON_HasObjectItem(j, "d")) { | |
| 102 | + x->d = strdup(cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(j, "d"))); | |
| 103 | + } | |
| 104 | + if (cJSON_HasObjectItem(j, "e")) { | |
| 105 | + if (NULL != (x->e = cJSON_malloc(sizeof(double)))) { | |
| 106 | + *x->e = cJSON_GetNumberValue(cJSON_GetObjectItemCaseSensitive(j, "e")); | |
| 107 | + } | |
| 108 | + } | |
| 109 | + if (cJSON_HasObjectItem(j, "f")) { | |
| 110 | + if (NULL != (x->f = cJSON_malloc(sizeof(bool)))) { | |
| 111 | + *x->f = cJSON_IsTrue(cJSON_GetObjectItemCaseSensitive(j, "f")); | |
| 112 | + } | |
| 113 | + } | |
| 114 | + } | |
| 115 | + } | |
| 116 | + return x; | |
| 117 | +} | |
| 118 | + | |
| 119 | +cJSON * cJSON_CreateMyObject(const struct MyObject * x) { | |
| 120 | + cJSON * j = NULL; | |
| 121 | + if (NULL != x) { | |
| 122 | + if (NULL != (j = cJSON_CreateObject())) { | |
| 123 | + if (NULL != x->a) { | |
| 124 | + cJSON_AddStringToObject(j, "a", x->a); | |
| 125 | + } | |
| 126 | + if (NULL != x->b) { | |
| 127 | + cJSON_AddNumberToObject(j, "b", *x->b); | |
| 128 | + } | |
| 129 | + if (NULL != x->c) { | |
| 130 | + cJSON_AddBoolToObject(j, "c", *x->c); | |
| 131 | + } | |
| 132 | + if (NULL != x->d) { | |
| 133 | + cJSON_AddStringToObject(j, "d", x->d); | |
| 134 | + } | |
| 135 | + if (NULL != x->e) { | |
| 136 | + cJSON_AddNumberToObject(j, "e", *x->e); | |
| 137 | + } | |
| 138 | + if (NULL != x->f) { | |
| 139 | + cJSON_AddBoolToObject(j, "f", *x->f); | |
| 140 | + } | |
| 141 | + } | |
| 142 | + } | |
| 143 | + return j; | |
| 144 | +} | |
| 145 | + | |
| 146 | +char * cJSON_PrintMyObject(const struct MyObject * x) { | |
| 147 | + char * s = NULL; | |
| 148 | + if (NULL != x) { | |
| 149 | + cJSON * j = cJSON_CreateMyObject(x); | |
| 150 | + if (NULL != j) { | |
| 151 | + s = cJSON_Print(j); | |
| 152 | + cJSON_Delete(j); | |
| 153 | + } | |
| 154 | + } | |
| 155 | + return s; | |
| 156 | +} | |
| 157 | + | |
| 158 | +void cJSON_DeleteMyObject(struct MyObject * x) { | |
| 159 | + if (NULL != x) { | |
| 160 | + if (NULL != x->a) { | |
| 161 | + cJSON_free(x->a); | |
| 162 | + } | |
| 163 | + if (NULL != x->b) { | |
| 164 | + cJSON_free(x->b); | |
| 165 | + } | |
| 166 | + if (NULL != x->c) { | |
| 167 | + cJSON_free(x->c); | |
| 168 | + } | |
| 169 | + if (NULL != x->d) { | |
| 170 | + cJSON_free(x->d); | |
| 171 | + } | |
| 172 | + if (NULL != x->e) { | |
| 173 | + cJSON_free(x->e); | |
| 174 | + } | |
| 175 | + if (NULL != x->f) { | |
| 176 | + cJSON_free(x->f); | |
| 177 | + } | |
| 178 | + cJSON_free(x); | |
| 179 | + } | |
| 180 | +} | |
| 181 | + | |
| 182 | +struct MyObjectA * cJSON_ParseMyObjectA(const char * s) { | |
| 183 | + struct MyObjectA * x = NULL; | |
| 184 | + if (NULL != s) { | |
| 185 | + cJSON * j = cJSON_Parse(s); | |
| 186 | + if (NULL != j) { | |
| 187 | + x = cJSON_GetMyObjectAValue(j); | |
| 188 | + cJSON_Delete(j); | |
| 189 | + } | |
| 190 | + } | |
| 191 | + return x; | |
| 192 | +} | |
| 193 | + | |
| 194 | +struct MyObjectA * cJSON_GetMyObjectAValue(const cJSON * j) { | |
| 195 | + struct MyObjectA * x = NULL; | |
| 196 | + if (NULL != j) { | |
| 197 | + if (NULL != (x = cJSON_malloc(sizeof(struct MyObjectA)))) { | |
| 198 | + memset(x, 0, sizeof(struct MyObjectA)); | |
| 199 | + if (cJSON_HasObjectItem(j, "a")) { | |
| 200 | + x->a = strdup(cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(j, "a"))); | |
| 201 | + } | |
| 202 | + if (cJSON_HasObjectItem(j, "b")) { | |
| 203 | + if (NULL != (x->b = cJSON_malloc(sizeof(double)))) { | |
| 204 | + *x->b = cJSON_GetNumberValue(cJSON_GetObjectItemCaseSensitive(j, "b")); | |
| 205 | + } | |
| 206 | + } | |
| 207 | + if (cJSON_HasObjectItem(j, "c")) { | |
| 208 | + if (NULL != (x->c = cJSON_malloc(sizeof(bool)))) { | |
| 209 | + *x->c = cJSON_IsTrue(cJSON_GetObjectItemCaseSensitive(j, "c")); | |
| 210 | + } | |
| 211 | + } | |
| 212 | + } | |
| 213 | + } | |
| 214 | + return x; | |
| 215 | +} | |
| 216 | + | |
| 217 | +cJSON * cJSON_CreateMyObjectA(const struct MyObjectA * x) { | |
| 218 | + cJSON * j = NULL; | |
| 219 | + if (NULL != x) { | |
| 220 | + if (NULL != (j = cJSON_CreateObject())) { | |
| 221 | + if (NULL != x->a) { | |
| 222 | + cJSON_AddStringToObject(j, "a", x->a); | |
| 223 | + } | |
| 224 | + if (NULL != x->b) { | |
| 225 | + cJSON_AddNumberToObject(j, "b", *x->b); | |
| 226 | + } | |
| 227 | + if (NULL != x->c) { | |
| 228 | + cJSON_AddBoolToObject(j, "c", *x->c); | |
| 229 | + } | |
| 230 | + } | |
| 231 | + } | |
| 232 | + return j; | |
| 233 | +} | |
| 234 | + | |
| 235 | +char * cJSON_PrintMyObjectA(const struct MyObjectA * x) { | |
| 236 | + char * s = NULL; | |
| 237 | + if (NULL != x) { | |
| 238 | + cJSON * j = cJSON_CreateMyObjectA(x); | |
| 239 | + if (NULL != j) { | |
| 240 | + s = cJSON_Print(j); | |
| 241 | + cJSON_Delete(j); | |
| 242 | + } | |
| 243 | + } | |
| 244 | + return s; | |
| 245 | +} | |
| 246 | + | |
| 247 | +void cJSON_DeleteMyObjectA(struct MyObjectA * x) { | |
| 248 | + if (NULL != x) { | |
| 249 | + if (NULL != x->a) { | |
| 250 | + cJSON_free(x->a); | |
| 251 | + } | |
| 252 | + if (NULL != x->b) { | |
| 253 | + cJSON_free(x->b); | |
| 254 | + } | |
| 255 | + if (NULL != x->c) { | |
| 256 | + cJSON_free(x->c); | |
| 257 | + } | |
| 258 | + cJSON_free(x); | |
| 259 | + } | |
| 260 | +} | |
| 261 | + | |
| 262 | +struct MyObjectB * cJSON_ParseMyObjectB(const char * s) { | |
| 263 | + struct MyObjectB * x = NULL; | |
| 264 | + if (NULL != s) { | |
| 265 | + cJSON * j = cJSON_Parse(s); | |
| 266 | + if (NULL != j) { | |
| 267 | + x = cJSON_GetMyObjectBValue(j); | |
| 268 | + cJSON_Delete(j); | |
| 269 | + } | |
| 270 | + } | |
| 271 | + return x; | |
| 272 | +} | |
| 273 | + | |
| 274 | +struct MyObjectB * cJSON_GetMyObjectBValue(const cJSON * j) { | |
| 275 | + struct MyObjectB * x = NULL; | |
| 276 | + if (NULL != j) { | |
| 277 | + if (NULL != (x = cJSON_malloc(sizeof(struct MyObjectB)))) { | |
| 278 | + memset(x, 0, sizeof(struct MyObjectB)); | |
| 279 | + if (cJSON_HasObjectItem(j, "d")) { | |
| 280 | + x->d = strdup(cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(j, "d"))); | |
| 281 | + } | |
| 282 | + if (cJSON_HasObjectItem(j, "e")) { | |
| 283 | + if (NULL != (x->e = cJSON_malloc(sizeof(double)))) { | |
| 284 | + *x->e = cJSON_GetNumberValue(cJSON_GetObjectItemCaseSensitive(j, "e")); | |
| 285 | + } | |
| 286 | + } | |
| 287 | + if (cJSON_HasObjectItem(j, "f")) { | |
| 288 | + if (NULL != (x->f = cJSON_malloc(sizeof(bool)))) { | |
| 289 | + *x->f = cJSON_IsTrue(cJSON_GetObjectItemCaseSensitive(j, "f")); | |
| 290 | + } | |
| 291 | + } | |
| 292 | + } | |
| 293 | + } | |
| 294 | + return x; | |
| 295 | +} | |
| 296 | + | |
| 297 | +cJSON * cJSON_CreateMyObjectB(const struct MyObjectB * x) { | |
| 298 | + cJSON * j = NULL; | |
| 299 | + if (NULL != x) { | |
| 300 | + if (NULL != (j = cJSON_CreateObject())) { | |
| 301 | + if (NULL != x->d) { | |
| 302 | + cJSON_AddStringToObject(j, "d", x->d); | |
| 303 | + } | |
| 304 | + if (NULL != x->e) { | |
| 305 | + cJSON_AddNumberToObject(j, "e", *x->e); | |
| 306 | + } | |
| 307 | + if (NULL != x->f) { | |
| 308 | + cJSON_AddBoolToObject(j, "f", *x->f); | |
| 309 | + } | |
| 310 | + } | |
| 311 | + } | |
| 312 | + return j; | |
| 313 | +} | |
| 314 | + | |
| 315 | +char * cJSON_PrintMyObjectB(const struct MyObjectB * x) { | |
| 316 | + char * s = NULL; | |
| 317 | + if (NULL != x) { | |
| 318 | + cJSON * j = cJSON_CreateMyObjectB(x); | |
| 319 | + if (NULL != j) { | |
| 320 | + s = cJSON_Print(j); | |
| 321 | + cJSON_Delete(j); | |
| 322 | + } | |
| 323 | + } | |
| 324 | + return s; | |
| 325 | +} | |
| 326 | + | |
| 327 | +void cJSON_DeleteMyObjectB(struct MyObjectB * x) { | |
| 328 | + if (NULL != x) { | |
| 329 | + if (NULL != x->d) { | |
| 330 | + cJSON_free(x->d); | |
| 331 | + } | |
| 332 | + if (NULL != x->e) { | |
| 333 | + cJSON_free(x->e); | |
| 334 | + } | |
| 335 | + if (NULL != x->f) { | |
| 336 | + cJSON_free(x->f); | |
| 337 | + } | |
| 338 | + cJSON_free(x); | |
| 339 | + } | |
| 340 | +} | |
| 341 | + | |
| 342 | +struct TopLevel * cJSON_ParseTopLevel(const char * s) { | |
| 343 | + struct TopLevel * x = NULL; | |
| 344 | + if (NULL != s) { | |
| 345 | + cJSON * j = cJSON_Parse(s); | |
| 346 | + if (NULL != j) { | |
| 347 | + x = cJSON_GetTopLevelValue(j); | |
| 348 | + cJSON_Delete(j); | |
| 349 | + } | |
| 350 | + } | |
| 351 | + return x; | |
| 352 | +} | |
| 353 | + | |
| 354 | +struct TopLevel * cJSON_GetTopLevelValue(const cJSON * j) { | |
| 355 | + struct TopLevel * x = NULL; | |
| 356 | + if (NULL != j) { | |
| 357 | + if (NULL != (x = cJSON_malloc(sizeof(struct TopLevel)))) { | |
| 358 | + memset(x, 0, sizeof(struct TopLevel)); | |
| 359 | + if (cJSON_HasObjectItem(j, "firstProperty")) { | |
| 360 | + x->first_property = cJSON_GetMyObjectValue(cJSON_GetObjectItemCaseSensitive(j, "firstProperty")); | |
| 361 | + } | |
| 362 | + if (cJSON_HasObjectItem(j, "secondProperty")) { | |
| 363 | + x->second_property = cJSON_GetSecondPropertyValue(cJSON_GetObjectItemCaseSensitive(j, "secondProperty")); | |
| 364 | + } | |
| 365 | + } | |
| 366 | + } | |
| 367 | + return x; | |
| 368 | +} | |
| 369 | + | |
| 370 | +cJSON * cJSON_CreateTopLevel(const struct TopLevel * x) { | |
| 371 | + cJSON * j = NULL; | |
| 372 | + if (NULL != x) { | |
| 373 | + if (NULL != (j = cJSON_CreateObject())) { | |
| 374 | + if (NULL != x->first_property) { | |
| 375 | + cJSON_AddItemToObject(j, "firstProperty", cJSON_CreateMyObject(x->first_property)); | |
| 376 | + } | |
| 377 | + if (NULL != x->second_property) { | |
| 378 | + cJSON_AddItemToObject(j, "secondProperty", cJSON_CreateSecondProperty(x->second_property)); | |
| 379 | + } | |
| 380 | + } | |
| 381 | + } | |
| 382 | + return j; | |
| 383 | +} | |
| 384 | + | |
| 385 | +char * cJSON_PrintTopLevel(const struct TopLevel * x) { | |
| 386 | + char * s = NULL; | |
| 387 | + if (NULL != x) { | |
| 388 | + cJSON * j = cJSON_CreateTopLevel(x); | |
| 389 | + if (NULL != j) { | |
| 390 | + s = cJSON_Print(j); | |
| 391 | + cJSON_Delete(j); | |
| 392 | + } | |
| 393 | + } | |
| 394 | + return s; | |
| 395 | +} | |
| 396 | + | |
| 397 | +void cJSON_DeleteTopLevel(struct TopLevel * x) { | |
| 398 | + if (NULL != x) { | |
| 399 | + if (NULL != x->first_property) { | |
| 400 | + cJSON_DeleteMyObject(x->first_property); | |
| 401 | + } | |
| 402 | + if (NULL != x->second_property) { | |
| 403 | + cJSON_DeleteSecondProperty(x->second_property); | |
| 404 | + } | |
| 405 | + cJSON_free(x); | |
| 406 | + } | |
| 407 | +} |
Aschema-cjson/test/inputs/schema/anyof-object-union.schema/default/TopLevel.h+103 −0
| @@ -0,0 +1,103 @@ | ||
| 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 <cJSON.h> | |
| 24 | +#include <hashtable.h> | |
| 25 | +#include <list.h> | |
| 26 | + | |
| 27 | +#ifndef cJSON_Bool | |
| 28 | +#define cJSON_Bool (cJSON_True | cJSON_False) | |
| 29 | +#endif | |
| 30 | +#ifndef cJSON_Map | |
| 31 | +#define cJSON_Map (1 << 16) | |
| 32 | +#endif | |
| 33 | +#ifndef cJSON_Enum | |
| 34 | +#define cJSON_Enum (1 << 17) | |
| 35 | +#endif | |
| 36 | + | |
| 37 | +struct MyObject { | |
| 38 | + char * a; | |
| 39 | + double * b; | |
| 40 | + bool * c; | |
| 41 | + char * d; | |
| 42 | + double * e; | |
| 43 | + bool * f; | |
| 44 | +}; | |
| 45 | + | |
| 46 | +struct MyObjectA { | |
| 47 | + char * a; | |
| 48 | + double * b; | |
| 49 | + bool * c; | |
| 50 | +}; | |
| 51 | + | |
| 52 | +struct MyObjectB { | |
| 53 | + char * d; | |
| 54 | + double * e; | |
| 55 | + bool * f; | |
| 56 | +}; | |
| 57 | + | |
| 58 | +struct SecondProperty { | |
| 59 | + int type; | |
| 60 | + union { | |
| 61 | + list_t * my_object_a_array; | |
| 62 | + struct MyObjectB * my_object_b; | |
| 63 | + } value; | |
| 64 | +}; | |
| 65 | + | |
| 66 | +struct TopLevel { | |
| 67 | + struct MyObject * first_property; | |
| 68 | + struct SecondProperty * second_property; | |
| 69 | +}; | |
| 70 | + | |
| 71 | +struct SecondProperty * cJSON_GetSecondPropertyValue(const cJSON * j); | |
| 72 | +cJSON * cJSON_CreateSecondProperty(const struct SecondProperty * x); | |
| 73 | +void cJSON_DeleteSecondProperty(struct SecondProperty * x); | |
| 74 | + | |
| 75 | +struct MyObject * cJSON_ParseMyObject(const char * s); | |
| 76 | +struct MyObject * cJSON_GetMyObjectValue(const cJSON * j); | |
| 77 | +cJSON * cJSON_CreateMyObject(const struct MyObject * x); | |
| 78 | +char * cJSON_PrintMyObject(const struct MyObject * x); | |
| 79 | +void cJSON_DeleteMyObject(struct MyObject * x); | |
| 80 | + | |
| 81 | +struct MyObjectA * cJSON_ParseMyObjectA(const char * s); | |
| 82 | +struct MyObjectA * cJSON_GetMyObjectAValue(const cJSON * j); | |
| 83 | +cJSON * cJSON_CreateMyObjectA(const struct MyObjectA * x); | |
| 84 | +char * cJSON_PrintMyObjectA(const struct MyObjectA * x); | |
| 85 | +void cJSON_DeleteMyObjectA(struct MyObjectA * x); | |
| 86 | + | |
| 87 | +struct MyObjectB * cJSON_ParseMyObjectB(const char * s); | |
| 88 | +struct MyObjectB * cJSON_GetMyObjectBValue(const cJSON * j); | |
| 89 | +cJSON * cJSON_CreateMyObjectB(const struct MyObjectB * x); | |
| 90 | +char * cJSON_PrintMyObjectB(const struct MyObjectB * x); | |
| 91 | +void cJSON_DeleteMyObjectB(struct MyObjectB * x); | |
| 92 | + | |
| 93 | +struct TopLevel * cJSON_ParseTopLevel(const char * s); | |
| 94 | +struct TopLevel * cJSON_GetTopLevelValue(const cJSON * j); | |
| 95 | +cJSON * cJSON_CreateTopLevel(const struct TopLevel * x); | |
| 96 | +char * cJSON_PrintTopLevel(const struct TopLevel * x); | |
| 97 | +void cJSON_DeleteTopLevel(struct TopLevel * x); | |
| 98 | + | |
| 99 | +#ifdef __cplusplus | |
| 100 | +} | |
| 101 | +#endif | |
| 102 | + | |
| 103 | +#endif /* __TOPLEVEL_H__ */ |
Aschema-cplusplus/test/inputs/schema/anyof-object-union.schema/default/quicktype.hpp+298 −0
| @@ -0,0 +1,298 @@ | ||
| 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 <optional> | |
| 12 | +#include <variant> | |
| 13 | +#include "json.hpp" | |
| 14 | + | |
| 15 | +#include <optional> | |
| 16 | +#include <stdexcept> | |
| 17 | +#include <regex> | |
| 18 | + | |
| 19 | +#ifndef NLOHMANN_OPT_HELPER | |
| 20 | +#define NLOHMANN_OPT_HELPER | |
| 21 | +namespace nlohmann { | |
| 22 | + template <typename T> | |
| 23 | + struct adl_serializer<std::shared_ptr<T>> { | |
| 24 | + static void to_json(json & j, const std::shared_ptr<T> & opt) { | |
| 25 | + if (!opt) j = nullptr; else j = *opt; | |
| 26 | + } | |
| 27 | + | |
| 28 | + static std::shared_ptr<T> from_json(const json & j) { | |
| 29 | + if (j.is_null()) return std::shared_ptr<T>(); else return std::make_shared<T>(j.get<T>()); | |
| 30 | + } | |
| 31 | + }; | |
| 32 | + template <typename T> | |
| 33 | + struct adl_serializer<std::optional<T>> { | |
| 34 | + static void to_json(json & j, const std::optional<T> & opt) { | |
| 35 | + if (!opt) j = nullptr; else j = *opt; | |
| 36 | + } | |
| 37 | + | |
| 38 | + static std::optional<T> from_json(const json & j) { | |
| 39 | + if (j.is_null()) return std::optional<T>(); else return std::make_optional<T>(j.get<T>()); | |
| 40 | + } | |
| 41 | + }; | |
| 42 | +} | |
| 43 | +#endif | |
| 44 | + | |
| 45 | +namespace quicktype { | |
| 46 | + using nlohmann::json; | |
| 47 | + | |
| 48 | + #ifndef NLOHMANN_UNTYPED_quicktype_HELPER | |
| 49 | + #define NLOHMANN_UNTYPED_quicktype_HELPER | |
| 50 | + inline json get_untyped(const json & j, const char * property) { | |
| 51 | + if (j.find(property) != j.end()) { | |
| 52 | + return j.at(property).get<json>(); | |
| 53 | + } | |
| 54 | + return json(); | |
| 55 | + } | |
| 56 | + | |
| 57 | + inline json get_untyped(const json & j, std::string property) { | |
| 58 | + return get_untyped(j, property.data()); | |
| 59 | + } | |
| 60 | + #endif | |
| 61 | + | |
| 62 | + #ifndef NLOHMANN_OPTIONAL_quicktype_HELPER | |
| 63 | + #define NLOHMANN_OPTIONAL_quicktype_HELPER | |
| 64 | + template <typename T> | |
| 65 | + inline std::shared_ptr<T> get_heap_optional(const json & j, const char * property) { | |
| 66 | + auto it = j.find(property); | |
| 67 | + if (it != j.end() && !it->is_null()) { | |
| 68 | + return j.at(property).get<std::shared_ptr<T>>(); | |
| 69 | + } | |
| 70 | + return std::shared_ptr<T>(); | |
| 71 | + } | |
| 72 | + | |
| 73 | + template <typename T> | |
| 74 | + inline std::shared_ptr<T> get_heap_optional(const json & j, std::string property) { | |
| 75 | + return get_heap_optional<T>(j, property.data()); | |
| 76 | + } | |
| 77 | + template <typename T> | |
| 78 | + inline std::optional<T> get_stack_optional(const json & j, const char * property) { | |
| 79 | + auto it = j.find(property); | |
| 80 | + if (it != j.end() && !it->is_null()) { | |
| 81 | + return j.at(property).get<std::optional<T>>(); | |
| 82 | + } | |
| 83 | + return std::optional<T>(); | |
| 84 | + } | |
| 85 | + | |
| 86 | + template <typename T> | |
| 87 | + inline std::optional<T> get_stack_optional(const json & j, std::string property) { | |
| 88 | + return get_stack_optional<T>(j, property.data()); | |
| 89 | + } | |
| 90 | + #endif | |
| 91 | + | |
| 92 | + class MyObject { | |
| 93 | + public: | |
| 94 | + MyObject() = default; | |
| 95 | + virtual ~MyObject() = default; | |
| 96 | + | |
| 97 | + private: | |
| 98 | + std::optional<std::string> a; | |
| 99 | + std::optional<double> b; | |
| 100 | + std::optional<bool> c; | |
| 101 | + std::optional<std::string> d; | |
| 102 | + std::optional<double> e; | |
| 103 | + std::optional<bool> f; | |
| 104 | + | |
| 105 | + public: | |
| 106 | + const std::optional<std::string> & get_a() const { return a; } | |
| 107 | + std::optional<std::string> & get_mutable_a() { return a; } | |
| 108 | + void set_a(const std::optional<std::string> & value) { this->a = value; } | |
| 109 | + | |
| 110 | + const std::optional<double> & get_b() const { return b; } | |
| 111 | + std::optional<double> & get_mutable_b() { return b; } | |
| 112 | + void set_b(const std::optional<double> & value) { this->b = value; } | |
| 113 | + | |
| 114 | + const std::optional<bool> & get_c() const { return c; } | |
| 115 | + std::optional<bool> & get_mutable_c() { return c; } | |
| 116 | + void set_c(const std::optional<bool> & value) { this->c = value; } | |
| 117 | + | |
| 118 | + const std::optional<std::string> & get_d() const { return d; } | |
| 119 | + std::optional<std::string> & get_mutable_d() { return d; } | |
| 120 | + void set_d(const std::optional<std::string> & value) { this->d = value; } | |
| 121 | + | |
| 122 | + const std::optional<double> & get_e() const { return e; } | |
| 123 | + std::optional<double> & get_mutable_e() { return e; } | |
| 124 | + void set_e(const std::optional<double> & value) { this->e = value; } | |
| 125 | + | |
| 126 | + const std::optional<bool> & get_f() const { return f; } | |
| 127 | + std::optional<bool> & get_mutable_f() { return f; } | |
| 128 | + void set_f(const std::optional<bool> & value) { this->f = value; } | |
| 129 | + }; | |
| 130 | + | |
| 131 | + class MyObjectA { | |
| 132 | + public: | |
| 133 | + MyObjectA() = default; | |
| 134 | + virtual ~MyObjectA() = default; | |
| 135 | + | |
| 136 | + private: | |
| 137 | + std::optional<std::string> a; | |
| 138 | + std::optional<double> b; | |
| 139 | + std::optional<bool> c; | |
| 140 | + | |
| 141 | + public: | |
| 142 | + const std::optional<std::string> & get_a() const { return a; } | |
| 143 | + std::optional<std::string> & get_mutable_a() { return a; } | |
| 144 | + void set_a(const std::optional<std::string> & value) { this->a = value; } | |
| 145 | + | |
| 146 | + const std::optional<double> & get_b() const { return b; } | |
| 147 | + std::optional<double> & get_mutable_b() { return b; } | |
| 148 | + void set_b(const std::optional<double> & value) { this->b = value; } | |
| 149 | + | |
| 150 | + const std::optional<bool> & get_c() const { return c; } | |
| 151 | + std::optional<bool> & get_mutable_c() { return c; } | |
| 152 | + void set_c(const std::optional<bool> & value) { this->c = value; } | |
| 153 | + }; | |
| 154 | + | |
| 155 | + class MyObjectB { | |
| 156 | + public: | |
| 157 | + MyObjectB() = default; | |
| 158 | + virtual ~MyObjectB() = default; | |
| 159 | + | |
| 160 | + private: | |
| 161 | + std::optional<std::string> d; | |
| 162 | + std::optional<double> e; | |
| 163 | + std::optional<bool> f; | |
| 164 | + | |
| 165 | + public: | |
| 166 | + const std::optional<std::string> & get_d() const { return d; } | |
| 167 | + std::optional<std::string> & get_mutable_d() { return d; } | |
| 168 | + void set_d(const std::optional<std::string> & value) { this->d = value; } | |
| 169 | + | |
| 170 | + const std::optional<double> & get_e() const { return e; } | |
| 171 | + std::optional<double> & get_mutable_e() { return e; } | |
| 172 | + void set_e(const std::optional<double> & value) { this->e = value; } | |
| 173 | + | |
| 174 | + const std::optional<bool> & get_f() const { return f; } | |
| 175 | + std::optional<bool> & get_mutable_f() { return f; } | |
| 176 | + void set_f(const std::optional<bool> & value) { this->f = value; } | |
| 177 | + }; | |
| 178 | + | |
| 179 | + using SecondProperty = std::variant<std::vector<MyObjectA>, MyObjectB>; | |
| 180 | + | |
| 181 | + class TopLevel { | |
| 182 | + public: | |
| 183 | + TopLevel() = default; | |
| 184 | + virtual ~TopLevel() = default; | |
| 185 | + | |
| 186 | + private: | |
| 187 | + std::optional<MyObject> first_property; | |
| 188 | + std::optional<SecondProperty> second_property; | |
| 189 | + | |
| 190 | + public: | |
| 191 | + const std::optional<MyObject> & get_first_property() const { return first_property; } | |
| 192 | + std::optional<MyObject> & get_mutable_first_property() { return first_property; } | |
| 193 | + void set_first_property(const std::optional<MyObject> & value) { this->first_property = value; } | |
| 194 | + | |
| 195 | + const std::optional<SecondProperty> & get_second_property() const { return second_property; } | |
| 196 | + std::optional<SecondProperty> & get_mutable_second_property() { return second_property; } | |
| 197 | + void set_second_property(const std::optional<SecondProperty> & value) { this->second_property = value; } | |
| 198 | + }; | |
| 199 | +} | |
| 200 | + | |
| 201 | +namespace quicktype { | |
| 202 | +void from_json(const json & j, MyObject & x); | |
| 203 | +void to_json(json & j, const MyObject & x); | |
| 204 | + | |
| 205 | +void from_json(const json & j, MyObjectA & x); | |
| 206 | +void to_json(json & j, const MyObjectA & x); | |
| 207 | + | |
| 208 | +void from_json(const json & j, MyObjectB & x); | |
| 209 | +void to_json(json & j, const MyObjectB & x); | |
| 210 | + | |
| 211 | +void from_json(const json & j, TopLevel & x); | |
| 212 | +void to_json(json & j, const TopLevel & x); | |
| 213 | +} | |
| 214 | +namespace nlohmann { | |
| 215 | +template <> | |
| 216 | +struct adl_serializer<std::variant<std::vector<quicktype::MyObjectA>, quicktype::MyObjectB>> { | |
| 217 | + static void from_json(const json & j, std::variant<std::vector<quicktype::MyObjectA>, quicktype::MyObjectB> & x); | |
| 218 | + static void to_json(json & j, const std::variant<std::vector<quicktype::MyObjectA>, quicktype::MyObjectB> & x); | |
| 219 | +}; | |
| 220 | +} | |
| 221 | +namespace quicktype { | |
| 222 | + inline void from_json(const json & j, MyObject& x) { | |
| 223 | + x.set_a(get_stack_optional<std::string>(j, "a")); | |
| 224 | + x.set_b(get_stack_optional<double>(j, "b")); | |
| 225 | + x.set_c(get_stack_optional<bool>(j, "c")); | |
| 226 | + x.set_d(get_stack_optional<std::string>(j, "d")); | |
| 227 | + x.set_e(get_stack_optional<double>(j, "e")); | |
| 228 | + x.set_f(get_stack_optional<bool>(j, "f")); | |
| 229 | + } | |
| 230 | + | |
| 231 | + inline void to_json(json & j, const MyObject & x) { | |
| 232 | + j = json::object(); | |
| 233 | + j["a"] = x.get_a(); | |
| 234 | + j["b"] = x.get_b(); | |
| 235 | + j["c"] = x.get_c(); | |
| 236 | + j["d"] = x.get_d(); | |
| 237 | + j["e"] = x.get_e(); | |
| 238 | + j["f"] = x.get_f(); | |
| 239 | + } | |
| 240 | + | |
| 241 | + inline void from_json(const json & j, MyObjectA& x) { | |
| 242 | + x.set_a(get_stack_optional<std::string>(j, "a")); | |
| 243 | + x.set_b(get_stack_optional<double>(j, "b")); | |
| 244 | + x.set_c(get_stack_optional<bool>(j, "c")); | |
| 245 | + } | |
| 246 | + | |
| 247 | + inline void to_json(json & j, const MyObjectA & x) { | |
| 248 | + j = json::object(); | |
| 249 | + j["a"] = x.get_a(); | |
| 250 | + j["b"] = x.get_b(); | |
| 251 | + j["c"] = x.get_c(); | |
| 252 | + } | |
| 253 | + | |
| 254 | + inline void from_json(const json & j, MyObjectB& x) { | |
| 255 | + x.set_d(get_stack_optional<std::string>(j, "d")); | |
| 256 | + x.set_e(get_stack_optional<double>(j, "e")); | |
| 257 | + x.set_f(get_stack_optional<bool>(j, "f")); | |
| 258 | + } | |
| 259 | + | |
| 260 | + inline void to_json(json & j, const MyObjectB & x) { | |
| 261 | + j = json::object(); | |
| 262 | + j["d"] = x.get_d(); | |
| 263 | + j["e"] = x.get_e(); | |
| 264 | + j["f"] = x.get_f(); | |
| 265 | + } | |
| 266 | + | |
| 267 | + inline void from_json(const json & j, TopLevel& x) { | |
| 268 | + x.set_first_property(get_stack_optional<MyObject>(j, "firstProperty")); | |
| 269 | + x.set_second_property(get_stack_optional<std::variant<std::vector<MyObjectA>, MyObjectB>>(j, "secondProperty")); | |
| 270 | + } | |
| 271 | + | |
| 272 | + inline void to_json(json & j, const TopLevel & x) { | |
| 273 | + j = json::object(); | |
| 274 | + j["firstProperty"] = x.get_first_property(); | |
| 275 | + j["secondProperty"] = x.get_second_property(); | |
| 276 | + } | |
| 277 | +} | |
| 278 | +namespace nlohmann { | |
| 279 | + inline void adl_serializer<std::variant<std::vector<quicktype::MyObjectA>, quicktype::MyObjectB>>::from_json(const json & j, std::variant<std::vector<quicktype::MyObjectA>, quicktype::MyObjectB> & x) { | |
| 280 | + if (j.is_object()) | |
| 281 | + x = j.get<quicktype::MyObjectB>(); | |
| 282 | + else if (j.is_array()) | |
| 283 | + x = j.get<std::vector<quicktype::MyObjectA>>(); | |
| 284 | + else throw std::runtime_error("Could not deserialise!"); | |
| 285 | + } | |
| 286 | + | |
| 287 | + inline void adl_serializer<std::variant<std::vector<quicktype::MyObjectA>, quicktype::MyObjectB>>::to_json(json & j, const std::variant<std::vector<quicktype::MyObjectA>, quicktype::MyObjectB> & x) { | |
| 288 | + switch (x.index()) { | |
| 289 | + case 0: | |
| 290 | + j = std::get<std::vector<quicktype::MyObjectA>>(x); | |
| 291 | + break; | |
| 292 | + case 1: | |
| 293 | + j = std::get<quicktype::MyObjectB>(x); | |
| 294 | + break; | |
| 295 | + default: throw std::runtime_error("Input JSON does not conform to schema!"); | |
| 296 | + } | |
| 297 | + } | |
| 298 | +} |
Aschema-csharp-SystemTextJson/test/inputs/schema/anyof-object-union.schema/default/QuickType.cs+156 −0
| @@ -0,0 +1,156 @@ | ||
| 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("firstProperty", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)] | |
| 29 | + public MyObject? FirstProperty { get; set; } | |
| 30 | + | |
| 31 | + [JsonProperty("secondProperty", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)] | |
| 32 | + public SecondProperty? SecondProperty { get; set; } | |
| 33 | + } | |
| 34 | + | |
| 35 | + public partial class MyObject | |
| 36 | + { | |
| 37 | + [JsonProperty("a", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)] | |
| 38 | + public string? A { get; set; } | |
| 39 | + | |
| 40 | + [JsonProperty("b", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)] | |
| 41 | + public double? B { get; set; } | |
| 42 | + | |
| 43 | + [JsonProperty("c", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)] | |
| 44 | + public bool? C { get; set; } | |
| 45 | + | |
| 46 | + [JsonProperty("d", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)] | |
| 47 | + public string? D { get; set; } | |
| 48 | + | |
| 49 | + [JsonProperty("e", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)] | |
| 50 | + public double? E { get; set; } | |
| 51 | + | |
| 52 | + [JsonProperty("f", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)] | |
| 53 | + public bool? F { get; set; } | |
| 54 | + } | |
| 55 | + | |
| 56 | + public partial class MyObjectA | |
| 57 | + { | |
| 58 | + [JsonProperty("a", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)] | |
| 59 | + public string? A { get; set; } | |
| 60 | + | |
| 61 | + [JsonProperty("b", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)] | |
| 62 | + public double? B { get; set; } | |
| 63 | + | |
| 64 | + [JsonProperty("c", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)] | |
| 65 | + public bool? C { get; set; } | |
| 66 | + } | |
| 67 | + | |
| 68 | + public partial class MyObjectB | |
| 69 | + { | |
| 70 | + [JsonProperty("d", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)] | |
| 71 | + public string? D { get; set; } | |
| 72 | + | |
| 73 | + [JsonProperty("e", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)] | |
| 74 | + public double? E { get; set; } | |
| 75 | + | |
| 76 | + [JsonProperty("f", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)] | |
| 77 | + public bool? F { get; set; } | |
| 78 | + } | |
| 79 | + | |
| 80 | + public partial struct SecondProperty | |
| 81 | + { | |
| 82 | + public MyObjectA[]? MyObjectAArray; | |
| 83 | + public MyObjectB? MyObjectB; | |
| 84 | + | |
| 85 | + public static implicit operator SecondProperty(MyObjectA[] MyObjectAArray) => new SecondProperty { MyObjectAArray = MyObjectAArray }; | |
| 86 | + public static implicit operator SecondProperty(MyObjectB MyObjectB) => new SecondProperty { MyObjectB = MyObjectB }; | |
| 87 | + } | |
| 88 | + | |
| 89 | + public partial class TopLevel | |
| 90 | + { | |
| 91 | + public static TopLevel FromJson(string json) => JsonConvert.DeserializeObject<TopLevel>(json, QuickType.Converter.Settings); | |
| 92 | + } | |
| 93 | + | |
| 94 | + public static partial class Serialize | |
| 95 | + { | |
| 96 | + public static string ToJson(this TopLevel self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings); | |
| 97 | + } | |
| 98 | + | |
| 99 | + internal static partial class Converter | |
| 100 | + { | |
| 101 | + public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings | |
| 102 | + { | |
| 103 | + MetadataPropertyHandling = MetadataPropertyHandling.Ignore, | |
| 104 | + DateParseHandling = DateParseHandling.None, | |
| 105 | + Converters = | |
| 106 | + { | |
| 107 | + SecondPropertyConverter.Singleton, | |
| 108 | + new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } | |
| 109 | + }, | |
| 110 | + }; | |
| 111 | + } | |
| 112 | + | |
| 113 | + internal class SecondPropertyConverter : JsonConverter | |
| 114 | + { | |
| 115 | + public override bool CanConvert(Type t) => t == typeof(SecondProperty) || t == typeof(SecondProperty?); | |
| 116 | + | |
| 117 | + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) | |
| 118 | + { | |
| 119 | + switch (reader.TokenType) | |
| 120 | + { | |
| 121 | + case JsonToken.StartObject: | |
| 122 | + var objectValue = serializer.Deserialize<MyObjectB>(reader); | |
| 123 | + return new SecondProperty { MyObjectB = objectValue }; | |
| 124 | + case JsonToken.StartArray: | |
| 125 | + var arrayValue = serializer.Deserialize<MyObjectA[]>(reader); | |
| 126 | + return new SecondProperty { MyObjectAArray = arrayValue }; | |
| 127 | + } | |
| 128 | + throw new Exception("Cannot unmarshal type SecondProperty"); | |
| 129 | + } | |
| 130 | + | |
| 131 | + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) | |
| 132 | + { | |
| 133 | + var value = (SecondProperty)untypedValue; | |
| 134 | + if (value.MyObjectAArray != null) | |
| 135 | + { | |
| 136 | + serializer.Serialize(writer, value.MyObjectAArray); | |
| 137 | + return; | |
| 138 | + } | |
| 139 | + if (value.MyObjectB != null) | |
| 140 | + { | |
| 141 | + serializer.Serialize(writer, value.MyObjectB); | |
| 142 | + return; | |
| 143 | + } | |
| 144 | + throw new Exception("Cannot marshal type SecondProperty"); | |
| 145 | + } | |
| 146 | + | |
| 147 | + public static readonly SecondPropertyConverter Singleton = new SecondPropertyConverter(); | |
| 148 | + } | |
| 149 | +} | |
| 150 | +#pragma warning restore CS8618 | |
| 151 | +#pragma warning restore CS8601 | |
| 152 | +#pragma warning restore CS8602 | |
| 153 | +#pragma warning restore CS8603 | |
| 154 | +#pragma warning restore CS8604 | |
| 155 | +#pragma warning restore CS8625 | |
| 156 | +#pragma warning restore CS8765 |
Aschema-csharp/test/inputs/schema/anyof-object-union.schema/default/QuickType.cs+273 −0
| @@ -0,0 +1,273 @@ | ||
| 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 | + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] | |
| 26 | + [JsonPropertyName("firstProperty")] | |
| 27 | + public MyObject? FirstProperty { get; set; } | |
| 28 | + | |
| 29 | + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] | |
| 30 | + [JsonPropertyName("secondProperty")] | |
| 31 | + public SecondProperty? SecondProperty { get; set; } | |
| 32 | + } | |
| 33 | + | |
| 34 | + public partial class MyObject | |
| 35 | + { | |
| 36 | + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] | |
| 37 | + [JsonPropertyName("a")] | |
| 38 | + public string? A { get; set; } | |
| 39 | + | |
| 40 | + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] | |
| 41 | + [JsonPropertyName("b")] | |
| 42 | + public double? B { get; set; } | |
| 43 | + | |
| 44 | + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] | |
| 45 | + [JsonPropertyName("c")] | |
| 46 | + public bool? C { get; set; } | |
| 47 | + | |
| 48 | + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] | |
| 49 | + [JsonPropertyName("d")] | |
| 50 | + public string? D { get; set; } | |
| 51 | + | |
| 52 | + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] | |
| 53 | + [JsonPropertyName("e")] | |
| 54 | + public double? E { get; set; } | |
| 55 | + | |
| 56 | + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] | |
| 57 | + [JsonPropertyName("f")] | |
| 58 | + public bool? F { get; set; } | |
| 59 | + } | |
| 60 | + | |
| 61 | + public partial class MyObjectA | |
| 62 | + { | |
| 63 | + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] | |
| 64 | + [JsonPropertyName("a")] | |
| 65 | + public string? A { get; set; } | |
| 66 | + | |
| 67 | + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] | |
| 68 | + [JsonPropertyName("b")] | |
| 69 | + public double? B { get; set; } | |
| 70 | + | |
| 71 | + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] | |
| 72 | + [JsonPropertyName("c")] | |
| 73 | + public bool? C { get; set; } | |
| 74 | + } | |
| 75 | + | |
| 76 | + public partial class MyObjectB | |
| 77 | + { | |
| 78 | + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] | |
| 79 | + [JsonPropertyName("d")] | |
| 80 | + public string? D { get; set; } | |
| 81 | + | |
| 82 | + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] | |
| 83 | + [JsonPropertyName("e")] | |
| 84 | + public double? E { get; set; } | |
| 85 | + | |
| 86 | + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] | |
| 87 | + [JsonPropertyName("f")] | |
| 88 | + public bool? F { get; set; } | |
| 89 | + } | |
| 90 | + | |
| 91 | + public partial struct SecondProperty | |
| 92 | + { | |
| 93 | + public MyObjectA[]? MyObjectAArray; | |
| 94 | + public MyObjectB? MyObjectB; | |
| 95 | + | |
| 96 | + public static implicit operator SecondProperty(MyObjectA[] MyObjectAArray) => new SecondProperty { MyObjectAArray = MyObjectAArray }; | |
| 97 | + public static implicit operator SecondProperty(MyObjectB MyObjectB) => new SecondProperty { MyObjectB = MyObjectB }; | |
| 98 | + } | |
| 99 | + | |
| 100 | + public partial class TopLevel | |
| 101 | + { | |
| 102 | + public static TopLevel FromJson(string json) => JsonSerializer.Deserialize<TopLevel>(json, QuickType.Converter.Settings); | |
| 103 | + } | |
| 104 | + | |
| 105 | + public static partial class Serialize | |
| 106 | + { | |
| 107 | + public static string ToJson(this TopLevel self) => JsonSerializer.Serialize(self, QuickType.Converter.Settings); | |
| 108 | + } | |
| 109 | + | |
| 110 | + internal static partial class Converter | |
| 111 | + { | |
| 112 | + public static readonly JsonSerializerOptions Settings = new(JsonSerializerDefaults.General) | |
| 113 | + { | |
| 114 | + Converters = | |
| 115 | + { | |
| 116 | + SecondPropertyConverter.Singleton, | |
| 117 | + new DateOnlyConverter(), | |
| 118 | + new TimeOnlyConverter(), | |
| 119 | + IsoDateTimeOffsetConverter.Singleton | |
| 120 | + }, | |
| 121 | + }; | |
| 122 | + } | |
| 123 | + | |
| 124 | + internal class SecondPropertyConverter : JsonConverter<SecondProperty> | |
| 125 | + { | |
| 126 | + public override bool CanConvert(Type t) => t == typeof(SecondProperty); | |
| 127 | + | |
| 128 | + public override SecondProperty Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | |
| 129 | + { | |
| 130 | + switch (reader.TokenType) | |
| 131 | + { | |
| 132 | + case JsonTokenType.StartObject: | |
| 133 | + var objectValue = JsonSerializer.Deserialize<MyObjectB>(ref reader, options); | |
| 134 | + return new SecondProperty { MyObjectB = objectValue }; | |
| 135 | + case JsonTokenType.StartArray: | |
| 136 | + var arrayValue = JsonSerializer.Deserialize<MyObjectA[]>(ref reader, options); | |
| 137 | + return new SecondProperty { MyObjectAArray = arrayValue }; | |
| 138 | + } | |
| 139 | + throw new JsonException("Cannot unmarshal type SecondProperty"); | |
| 140 | + } | |
| 141 | + | |
| 142 | + public override void Write(Utf8JsonWriter writer, SecondProperty value, JsonSerializerOptions options) | |
| 143 | + { | |
| 144 | + if (value.MyObjectAArray != null) | |
| 145 | + { | |
| 146 | + JsonSerializer.Serialize(writer, value.MyObjectAArray, options); | |
| 147 | + return; | |
| 148 | + } | |
| 149 | + if (value.MyObjectB != null) | |
| 150 | + { | |
| 151 | + JsonSerializer.Serialize(writer, value.MyObjectB, options); | |
| 152 | + return; | |
| 153 | + } | |
| 154 | + throw new NotSupportedException("Cannot marshal type SecondProperty"); | |
| 155 | + } | |
| 156 | + | |
| 157 | + public static readonly SecondPropertyConverter Singleton = new SecondPropertyConverter(); | |
| 158 | + } | |
| 159 | + | |
| 160 | + public class DateOnlyConverter : JsonConverter<DateOnly> | |
| 161 | + { | |
| 162 | + private readonly string serializationFormat; | |
| 163 | + public DateOnlyConverter() : this(null) { } | |
| 164 | + | |
| 165 | + public DateOnlyConverter(string? serializationFormat) | |
| 166 | + { | |
| 167 | + this.serializationFormat = serializationFormat ?? "yyyy-MM-dd"; | |
| 168 | + } | |
| 169 | + | |
| 170 | + public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | |
| 171 | + { | |
| 172 | + var value = reader.GetString(); | |
| 173 | + return DateOnly.Parse(value!); | |
| 174 | + } | |
| 175 | + | |
| 176 | + public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options) | |
| 177 | + => writer.WriteStringValue(value.ToString(serializationFormat)); | |
| 178 | + } | |
| 179 | + | |
| 180 | + public class TimeOnlyConverter : JsonConverter<TimeOnly> | |
| 181 | + { | |
| 182 | + private readonly string serializationFormat; | |
| 183 | + | |
| 184 | + public TimeOnlyConverter() : this(null) { } | |
| 185 | + | |
| 186 | + public TimeOnlyConverter(string? serializationFormat) | |
| 187 | + { | |
| 188 | + this.serializationFormat = serializationFormat ?? "HH:mm:ss.fff"; | |
| 189 | + } | |
| 190 | + | |
| 191 | + public override TimeOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | |
| 192 | + { | |
| 193 | + var value = reader.GetString(); | |
| 194 | + return TimeOnly.Parse(value!); | |
| 195 | + } | |
| 196 | + | |
| 197 | + public override void Write(Utf8JsonWriter writer, TimeOnly value, JsonSerializerOptions options) | |
| 198 | + => writer.WriteStringValue(value.ToString(serializationFormat)); | |
| 199 | + } | |
| 200 | + | |
| 201 | + internal class IsoDateTimeOffsetConverter : JsonConverter<DateTimeOffset> | |
| 202 | + { | |
| 203 | + public override bool CanConvert(Type t) => t == typeof(DateTimeOffset); | |
| 204 | + | |
| 205 | + private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"; | |
| 206 | + | |
| 207 | + private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind; | |
| 208 | + private string? _dateTimeFormat; | |
| 209 | + private CultureInfo? _culture; | |
| 210 | + | |
| 211 | + public DateTimeStyles DateTimeStyles | |
| 212 | + { | |
| 213 | + get => _dateTimeStyles; | |
| 214 | + set => _dateTimeStyles = value; | |
| 215 | + } | |
| 216 | + | |
| 217 | + public string? DateTimeFormat | |
| 218 | + { | |
| 219 | + get => _dateTimeFormat ?? string.Empty; | |
| 220 | + set => _dateTimeFormat = (string.IsNullOrEmpty(value)) ? null : value; | |
| 221 | + } | |
| 222 | + | |
| 223 | + public CultureInfo Culture | |
| 224 | + { | |
| 225 | + get => _culture ?? CultureInfo.CurrentCulture; | |
| 226 | + set => _culture = value; | |
| 227 | + } | |
| 228 | + | |
| 229 | + public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options) | |
| 230 | + { | |
| 231 | + string text; | |
| 232 | + | |
| 233 | + | |
| 234 | + if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal | |
| 235 | + || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal) | |
| 236 | + { | |
| 237 | + value = value.ToUniversalTime(); | |
| 238 | + } | |
| 239 | + | |
| 240 | + text = value.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture); | |
| 241 | + | |
| 242 | + writer.WriteStringValue(text); | |
| 243 | + } | |
| 244 | + | |
| 245 | + public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | |
| 246 | + { | |
| 247 | + string? dateText = reader.GetString(); | |
| 248 | + | |
| 249 | + if (string.IsNullOrEmpty(dateText) == false) | |
| 250 | + { | |
| 251 | + if (!string.IsNullOrEmpty(_dateTimeFormat)) | |
| 252 | + { | |
| 253 | + return DateTimeOffset.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles); | |
| 254 | + } | |
| 255 | + else | |
| 256 | + { | |
| 257 | + return DateTimeOffset.Parse(dateText, Culture, _dateTimeStyles); | |
| 258 | + } | |
| 259 | + } | |
| 260 | + else | |
| 261 | + { | |
| 262 | + return default(DateTimeOffset); | |
| 263 | + } | |
| 264 | + } | |
| 265 | + | |
| 266 | + | |
| 267 | + public static readonly IsoDateTimeOffsetConverter Singleton = new IsoDateTimeOffsetConverter(); | |
| 268 | + } | |
| 269 | +} | |
| 270 | +#pragma warning restore CS8618 | |
| 271 | +#pragma warning restore CS8601 | |
| 272 | +#pragma warning restore CS8602 | |
| 273 | +#pragma warning restore CS8603 |
Aschema-dart/test/inputs/schema/anyof-object-union.schema/default/TopLevel.dart+113 −0
| @@ -0,0 +1,113 @@ | ||
| 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 MyObject? firstProperty; | |
| 13 | + final dynamic secondProperty; | |
| 14 | + | |
| 15 | + TopLevel({ | |
| 16 | + this.firstProperty, | |
| 17 | + this.secondProperty, | |
| 18 | + }); | |
| 19 | + | |
| 20 | + factory TopLevel.fromJson(Map<String, dynamic> json) => TopLevel( | |
| 21 | + firstProperty: json["firstProperty"] == null ? null : MyObject.fromJson(json["firstProperty"]), | |
| 22 | + secondProperty: json["secondProperty"], | |
| 23 | + ); | |
| 24 | + | |
| 25 | + Map<String, dynamic> toJson() => { | |
| 26 | + "firstProperty": firstProperty?.toJson(), | |
| 27 | + "secondProperty": secondProperty, | |
| 28 | + }; | |
| 29 | +} | |
| 30 | + | |
| 31 | +class MyObject { | |
| 32 | + final String? a; | |
| 33 | + final double? b; | |
| 34 | + final bool? c; | |
| 35 | + final String? d; | |
| 36 | + final double? e; | |
| 37 | + final bool? f; | |
| 38 | + | |
| 39 | + MyObject({ | |
| 40 | + this.a, | |
| 41 | + this.b, | |
| 42 | + this.c, | |
| 43 | + this.d, | |
| 44 | + this.e, | |
| 45 | + this.f, | |
| 46 | + }); | |
| 47 | + | |
| 48 | + factory MyObject.fromJson(Map<String, dynamic> json) => MyObject( | |
| 49 | + a: json["a"], | |
| 50 | + b: json["b"]?.toDouble(), | |
| 51 | + c: json["c"], | |
| 52 | + d: json["d"], | |
| 53 | + e: json["e"]?.toDouble(), | |
| 54 | + f: json["f"], | |
| 55 | + ); | |
| 56 | + | |
| 57 | + Map<String, dynamic> toJson() => { | |
| 58 | + "a": a, | |
| 59 | + "b": b, | |
| 60 | + "c": c, | |
| 61 | + "d": d, | |
| 62 | + "e": e, | |
| 63 | + "f": f, | |
| 64 | + }; | |
| 65 | +} | |
| 66 | + | |
| 67 | +class MyObjectA { | |
| 68 | + final String? a; | |
| 69 | + final double? b; | |
| 70 | + final bool? c; | |
| 71 | + | |
| 72 | + MyObjectA({ | |
| 73 | + this.a, | |
| 74 | + this.b, | |
| 75 | + this.c, | |
| 76 | + }); | |
| 77 | + | |
| 78 | + factory MyObjectA.fromJson(Map<String, dynamic> json) => MyObjectA( | |
| 79 | + a: json["a"], | |
| 80 | + b: json["b"]?.toDouble(), | |
| 81 | + c: json["c"], | |
| 82 | + ); | |
| 83 | + | |
| 84 | + Map<String, dynamic> toJson() => { | |
| 85 | + "a": a, | |
| 86 | + "b": b, | |
| 87 | + "c": c, | |
| 88 | + }; | |
| 89 | +} | |
| 90 | + | |
| 91 | +class MyObjectB { | |
| 92 | + final String? d; | |
| 93 | + final double? e; | |
| 94 | + final bool? f; | |
| 95 | + | |
| 96 | + MyObjectB({ | |
| 97 | + this.d, | |
| 98 | + this.e, | |
| 99 | + this.f, | |
| 100 | + }); | |
| 101 | + | |
| 102 | + factory MyObjectB.fromJson(Map<String, dynamic> json) => MyObjectB( | |
| 103 | + d: json["d"], | |
| 104 | + e: json["e"]?.toDouble(), | |
| 105 | + f: json["f"], | |
| 106 | + ); | |
| 107 | + | |
| 108 | + Map<String, dynamic> toJson() => { | |
| 109 | + "d": d, | |
| 110 | + "e": e, | |
| 111 | + "f": f, | |
| 112 | + }; | |
| 113 | +} |
Aschema-elixir/test/inputs/schema/anyof-object-union.schema/default/QuickType.ex+174 −0
| @@ -0,0 +1,174 @@ | ||
| 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 MyObject do | |
| 9 | + defstruct [:a, :b, :c, :d, :e, :f] | |
| 10 | + | |
| 11 | + @type t :: %__MODULE__{ | |
| 12 | + a: String.t() | nil, | |
| 13 | + b: float() | nil, | |
| 14 | + c: boolean() | nil, | |
| 15 | + d: String.t() | nil, | |
| 16 | + e: float() | nil, | |
| 17 | + f: boolean() | nil | |
| 18 | + } | |
| 19 | + | |
| 20 | + def from_map(m) do | |
| 21 | + %MyObject{ | |
| 22 | + a: m["a"], | |
| 23 | + b: m["b"], | |
| 24 | + c: m["c"], | |
| 25 | + d: m["d"], | |
| 26 | + e: m["e"], | |
| 27 | + f: m["f"], | |
| 28 | + } | |
| 29 | + end | |
| 30 | + | |
| 31 | + def from_json(json) do | |
| 32 | + json | |
| 33 | + |> Jason.decode!() | |
| 34 | + |> from_map() | |
| 35 | + end | |
| 36 | + | |
| 37 | + def to_map(struct) do | |
| 38 | + %{ | |
| 39 | + "a" => struct.a, | |
| 40 | + "b" => struct.b, | |
| 41 | + "c" => struct.c, | |
| 42 | + "d" => struct.d, | |
| 43 | + "e" => struct.e, | |
| 44 | + "f" => struct.f, | |
| 45 | + } | |
| 46 | + end | |
| 47 | + | |
| 48 | + def to_json(struct) do | |
| 49 | + struct | |
| 50 | + |> to_map() | |
| 51 | + |> Jason.encode!() | |
| 52 | + end | |
| 53 | +end | |
| 54 | + | |
| 55 | +defmodule MyObjectA do | |
| 56 | + defstruct [:a, :b, :c] | |
| 57 | + | |
| 58 | + @type t :: %__MODULE__{ | |
| 59 | + a: String.t() | nil, | |
| 60 | + b: float() | nil, | |
| 61 | + c: boolean() | nil | |
| 62 | + } | |
| 63 | + | |
| 64 | + def from_map(m) do | |
| 65 | + %MyObjectA{ | |
| 66 | + a: m["a"], | |
| 67 | + b: m["b"], | |
| 68 | + c: m["c"], | |
| 69 | + } | |
| 70 | + end | |
| 71 | + | |
| 72 | + def from_json(json) do | |
| 73 | + json | |
| 74 | + |> Jason.decode!() | |
| 75 | + |> from_map() | |
| 76 | + end | |
| 77 | + | |
| 78 | + def to_map(struct) do | |
| 79 | + %{ | |
| 80 | + "a" => struct.a, | |
| 81 | + "b" => struct.b, | |
| 82 | + "c" => struct.c, | |
| 83 | + } | |
| 84 | + end | |
| 85 | + | |
| 86 | + def to_json(struct) do | |
| 87 | + struct | |
| 88 | + |> to_map() | |
| 89 | + |> Jason.encode!() | |
| 90 | + end | |
| 91 | +end | |
| 92 | + | |
| 93 | +defmodule MyObjectB do | |
| 94 | + defstruct [:d, :e, :f] | |
| 95 | + | |
| 96 | + @type t :: %__MODULE__{ | |
| 97 | + d: String.t() | nil, | |
| 98 | + e: float() | nil, | |
| 99 | + f: boolean() | nil | |
| 100 | + } | |
| 101 | + | |
| 102 | + def from_map(m) do | |
| 103 | + %MyObjectB{ | |
| 104 | + d: m["d"], | |
| 105 | + e: m["e"], | |
| 106 | + f: m["f"], | |
| 107 | + } | |
| 108 | + end | |
| 109 | + | |
| 110 | + def from_json(json) do | |
| 111 | + json | |
| 112 | + |> Jason.decode!() | |
| 113 | + |> from_map() | |
| 114 | + end | |
| 115 | + | |
| 116 | + def to_map(struct) do | |
| 117 | + %{ | |
| 118 | + "d" => struct.d, | |
| 119 | + "e" => struct.e, | |
| 120 | + "f" => struct.f, | |
| 121 | + } | |
| 122 | + end | |
| 123 | + | |
| 124 | + def to_json(struct) do | |
| 125 | + struct | |
| 126 | + |> to_map() | |
| 127 | + |> Jason.encode!() | |
| 128 | + end | |
| 129 | +end | |
| 130 | + | |
| 131 | +defmodule TopLevel do | |
| 132 | + defstruct [:first_property, :second_property] | |
| 133 | + | |
| 134 | + @type t :: %__MODULE__{ | |
| 135 | + first_property: MyObject.t() | nil, | |
| 136 | + second_property: [MyObjectA.t()] | MyObjectB.t() | nil | |
| 137 | + } | |
| 138 | + | |
| 139 | + def decode_second_property(%{} = value), do: MyObjectB.from_map(value) | |
| 140 | + def decode_second_property(value) when is_list(value), do: value | |
| 141 | + def decode_second_property(value) when is_nil(value), do: value | |
| 142 | + def decode_second_property(_), do: {:error, "Unexpected type when decoding TopLevel.second_property"} | |
| 143 | + | |
| 144 | + def encode_second_property(%MyObjectB{} = value), do: MyObjectB.to_map(value) | |
| 145 | + def encode_second_property(value) when is_list(value), do: value | |
| 146 | + def encode_second_property(value) when is_nil(value), do: value | |
| 147 | + def encode_second_property(_), do: {:error, "Unexpected type when encoding TopLevel.second_property"} | |
| 148 | + | |
| 149 | + def from_map(m) do | |
| 150 | + %TopLevel{ | |
| 151 | + first_property: m["firstProperty"] && MyObject.from_map(m["firstProperty"]), | |
| 152 | + second_property: decode_second_property(m["secondProperty"]), | |
| 153 | + } | |
| 154 | + end | |
| 155 | + | |
| 156 | + def from_json(json) do | |
| 157 | + json | |
| 158 | + |> Jason.decode!() | |
| 159 | + |> from_map() | |
| 160 | + end | |
| 161 | + | |
| 162 | + def to_map(struct) do | |
| 163 | + %{ | |
| 164 | + "firstProperty" => struct.first_property && MyObject.to_map(struct.first_property), | |
| 165 | + "secondProperty" => encode_second_property(struct.second_property), | |
| 166 | + } | |
| 167 | + end | |
| 168 | + | |
| 169 | + def to_json(struct) do | |
| 170 | + struct | |
| 171 | + |> to_map() | |
| 172 | + |> Jason.encode!() | |
| 173 | + end | |
| 174 | +end |
Aschema-elm/test/inputs/schema/anyof-object-union.schema/default/QuickType.elm+146 −0
| @@ -0,0 +1,146 @@ | ||
| 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 | + , MyObject | |
| 19 | + , MyObjectA | |
| 20 | + , MyObjectB | |
| 21 | + , SecondProperty(..) | |
| 22 | + ) | |
| 23 | + | |
| 24 | +import Json.Decode as Jdec | |
| 25 | +import Json.Decode.Pipeline as Jpipe | |
| 26 | +import Json.Encode as Jenc | |
| 27 | +import Dict exposing (Dict) | |
| 28 | + | |
| 29 | +type alias QuickType = | |
| 30 | + { firstProperty : Maybe MyObject | |
| 31 | + , secondProperty : Maybe SecondProperty | |
| 32 | + } | |
| 33 | + | |
| 34 | +type alias MyObject = | |
| 35 | + { a : Maybe String | |
| 36 | + , b : Maybe Float | |
| 37 | + , c : Maybe Bool | |
| 38 | + , d : Maybe String | |
| 39 | + , e : Maybe Float | |
| 40 | + , myObjectF : Maybe Bool | |
| 41 | + } | |
| 42 | + | |
| 43 | +type SecondProperty | |
| 44 | + = MyObjectAArrayInSecondProperty (List MyObjectA) | |
| 45 | + | MyObjectBInSecondProperty MyObjectB | |
| 46 | + | |
| 47 | +type alias MyObjectA = | |
| 48 | + { a : Maybe String | |
| 49 | + , b : Maybe Float | |
| 50 | + , c : Maybe Bool | |
| 51 | + } | |
| 52 | + | |
| 53 | +type alias MyObjectB = | |
| 54 | + { d : Maybe String | |
| 55 | + , e : Maybe Float | |
| 56 | + , myObjectBF : Maybe Bool | |
| 57 | + } | |
| 58 | + | |
| 59 | +-- decoders and encoders | |
| 60 | + | |
| 61 | +quickTypeToString : QuickType -> String | |
| 62 | +quickTypeToString r = Jenc.encode 0 (encodeQuickType r) | |
| 63 | + | |
| 64 | +quickType : Jdec.Decoder QuickType | |
| 65 | +quickType = | |
| 66 | + Jdec.succeed QuickType | |
| 67 | + |> Jpipe.optional "firstProperty" (Jdec.nullable myObject) Nothing | |
| 68 | + |> Jpipe.optional "secondProperty" (Jdec.nullable secondProperty) Nothing | |
| 69 | + | |
| 70 | +encodeQuickType : QuickType -> Jenc.Value | |
| 71 | +encodeQuickType x = | |
| 72 | + Jenc.object | |
| 73 | + [ ("firstProperty", makeNullableEncoder encodeMyObject x.firstProperty) | |
| 74 | + , ("secondProperty", makeNullableEncoder encodeSecondProperty x.secondProperty) | |
| 75 | + ] | |
| 76 | + | |
| 77 | +myObject : Jdec.Decoder MyObject | |
| 78 | +myObject = | |
| 79 | + Jdec.succeed MyObject | |
| 80 | + |> Jpipe.optional "a" (Jdec.nullable Jdec.string) Nothing | |
| 81 | + |> Jpipe.optional "b" (Jdec.nullable Jdec.float) Nothing | |
| 82 | + |> Jpipe.optional "c" (Jdec.nullable Jdec.bool) Nothing | |
| 83 | + |> Jpipe.optional "d" (Jdec.nullable Jdec.string) Nothing | |
| 84 | + |> Jpipe.optional "e" (Jdec.nullable Jdec.float) Nothing | |
| 85 | + |> Jpipe.optional "f" (Jdec.nullable Jdec.bool) Nothing | |
| 86 | + | |
| 87 | +encodeMyObject : MyObject -> Jenc.Value | |
| 88 | +encodeMyObject x = | |
| 89 | + Jenc.object | |
| 90 | + [ ("a", makeNullableEncoder Jenc.string x.a) | |
| 91 | + , ("b", makeNullableEncoder Jenc.float x.b) | |
| 92 | + , ("c", makeNullableEncoder Jenc.bool x.c) | |
| 93 | + , ("d", makeNullableEncoder Jenc.string x.d) | |
| 94 | + , ("e", makeNullableEncoder Jenc.float x.e) | |
| 95 | + , ("f", makeNullableEncoder Jenc.bool x.myObjectF) | |
| 96 | + ] | |
| 97 | + | |
| 98 | +secondProperty : Jdec.Decoder SecondProperty | |
| 99 | +secondProperty = | |
| 100 | + Jdec.oneOf | |
| 101 | + [ Jdec.map MyObjectAArrayInSecondProperty (Jdec.list myObjectA) | |
| 102 | + , Jdec.map MyObjectBInSecondProperty myObjectB | |
| 103 | + ] | |
| 104 | + | |
| 105 | +encodeSecondProperty : SecondProperty -> Jenc.Value | |
| 106 | +encodeSecondProperty x = case x of | |
| 107 | + MyObjectAArrayInSecondProperty y -> Jenc.list encodeMyObjectA y | |
| 108 | + MyObjectBInSecondProperty y -> encodeMyObjectB y | |
| 109 | + | |
| 110 | +myObjectA : Jdec.Decoder MyObjectA | |
| 111 | +myObjectA = | |
| 112 | + Jdec.succeed MyObjectA | |
| 113 | + |> Jpipe.optional "a" (Jdec.nullable Jdec.string) Nothing | |
| 114 | + |> Jpipe.optional "b" (Jdec.nullable Jdec.float) Nothing | |
| 115 | + |> Jpipe.optional "c" (Jdec.nullable Jdec.bool) Nothing | |
| 116 | + | |
| 117 | +encodeMyObjectA : MyObjectA -> Jenc.Value | |
| 118 | +encodeMyObjectA x = | |
| 119 | + Jenc.object | |
| 120 | + [ ("a", makeNullableEncoder Jenc.string x.a) | |
| 121 | + , ("b", makeNullableEncoder Jenc.float x.b) | |
| 122 | + , ("c", makeNullableEncoder Jenc.bool x.c) | |
| 123 | + ] | |
| 124 | + | |
| 125 | +myObjectB : Jdec.Decoder MyObjectB | |
| 126 | +myObjectB = | |
| 127 | + Jdec.succeed MyObjectB | |
| 128 | + |> Jpipe.optional "d" (Jdec.nullable Jdec.string) Nothing | |
| 129 | + |> Jpipe.optional "e" (Jdec.nullable Jdec.float) Nothing | |
| 130 | + |> Jpipe.optional "f" (Jdec.nullable Jdec.bool) Nothing | |
| 131 | + | |
| 132 | +encodeMyObjectB : MyObjectB -> Jenc.Value | |
| 133 | +encodeMyObjectB x = | |
| 134 | + Jenc.object | |
| 135 | + [ ("d", makeNullableEncoder Jenc.string x.d) | |
| 136 | + , ("e", makeNullableEncoder Jenc.float x.e) | |
| 137 | + , ("f", makeNullableEncoder Jenc.bool x.myObjectBF) | |
| 138 | + ] | |
| 139 | + | |
| 140 | +--- encoder helpers | |
| 141 | + | |
| 142 | +makeNullableEncoder : (a -> Jenc.Value) -> Maybe a -> Jenc.Value | |
| 143 | +makeNullableEncoder f m = | |
| 144 | + case m of | |
| 145 | + Just x -> f x | |
| 146 | + Nothing -> Jenc.null |
Aschema-flow/test/inputs/schema/anyof-object-union.schema/default/TopLevel.js+231 −0
| @@ -0,0 +1,231 @@ | ||
| 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 | + firstProperty?: MyObject; | |
| 14 | + secondProperty?: SecondProperty; | |
| 15 | +}; | |
| 16 | + | |
| 17 | +export type MyObject = { | |
| 18 | + a?: string; | |
| 19 | + b?: number; | |
| 20 | + c?: boolean; | |
| 21 | + d?: string; | |
| 22 | + e?: number; | |
| 23 | + f?: boolean; | |
| 24 | +}; | |
| 25 | + | |
| 26 | +export type SecondProperty = MyObjectA[] | MyObjectB; | |
| 27 | + | |
| 28 | +export type MyObjectA = { | |
| 29 | + a?: string; | |
| 30 | + b?: number; | |
| 31 | + c?: boolean; | |
| 32 | +}; | |
| 33 | + | |
| 34 | +export type MyObjectB = { | |
| 35 | + d?: string; | |
| 36 | + e?: number; | |
| 37 | + f?: boolean; | |
| 38 | +}; | |
| 39 | + | |
| 40 | +// Converts JSON strings to/from your types | |
| 41 | +// and asserts the results of JSON.parse at runtime | |
| 42 | +function toTopLevel(json: string): TopLevel { | |
| 43 | + return cast(JSON.parse(json), r("TopLevel")); | |
| 44 | +} | |
| 45 | + | |
| 46 | +function topLevelToJson(value: TopLevel): string { | |
| 47 | + return JSON.stringify(uncast(value, r("TopLevel")), null, 2); | |
| 48 | +} | |
| 49 | + | |
| 50 | +function invalidValue(typ: any, val: any, key: any, parent: any = '') { | |
| 51 | + const prettyTyp = prettyTypeName(typ); | |
| 52 | + const parentText = parent ? ` on ${parent}` : ''; | |
| 53 | + const keyText = key ? ` for key "${key}"` : ''; | |
| 54 | + throw Error(`Invalid value${keyText}${parentText}. Expected ${prettyTyp} but got ${JSON.stringify(val)}`); | |
| 55 | +} | |
| 56 | + | |
| 57 | +function prettyTypeName(typ: any): string { | |
| 58 | + if (Array.isArray(typ)) { | |
| 59 | + if (typ.length === 2 && typ[0] === undefined) { | |
| 60 | + return `an optional ${prettyTypeName(typ[1])}`; | |
| 61 | + } else { | |
| 62 | + return `one of [${typ.map(a => { return prettyTypeName(a); }).join(", ")}]`; | |
| 63 | + } | |
| 64 | + } else if (typeof typ === "object" && typ.literal !== undefined) { | |
| 65 | + return typ.literal; | |
| 66 | + } else { | |
| 67 | + return typeof typ; | |
| 68 | + } | |
| 69 | +} | |
| 70 | + | |
| 71 | +function jsonToJSProps(typ: any): any { | |
| 72 | + if (typ.jsonToJS === undefined) { | |
| 73 | + const map: any = {}; | |
| 74 | + typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ }); | |
| 75 | + typ.jsonToJS = map; | |
| 76 | + } | |
| 77 | + return typ.jsonToJS; | |
| 78 | +} | |
| 79 | + | |
| 80 | +function jsToJSONProps(typ: any): any { | |
| 81 | + if (typ.jsToJSON === undefined) { | |
| 82 | + const map: any = {}; | |
| 83 | + typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ }); | |
| 84 | + typ.jsToJSON = map; | |
| 85 | + } | |
| 86 | + return typ.jsToJSON; | |
| 87 | +} | |
| 88 | + | |
| 89 | +function transform(val: any, typ: any, getProps: any, key: any = '', parent: any = ''): any { | |
| 90 | + function transformPrimitive(typ: string, val: any): any { | |
| 91 | + if (typeof typ === typeof val) return val; | |
| 92 | + return invalidValue(typ, val, key, parent); | |
| 93 | + } | |
| 94 | + | |
| 95 | + function transformUnion(typs: any[], val: any): any { | |
| 96 | + // val must validate against one typ in typs | |
| 97 | + const l = typs.length; | |
| 98 | + for (let i = 0; i < l; i++) { | |
| 99 | + const typ = typs[i]; | |
| 100 | + try { | |
| 101 | + return transform(val, typ, getProps); | |
| 102 | + } catch (_) {} | |
| 103 | + } | |
| 104 | + return invalidValue(typs, val, key, parent); | |
| 105 | + } | |
| 106 | + | |
| 107 | + function transformEnum(cases: string[], val: any): any { | |
| 108 | + if (cases.indexOf(val) !== -1) return val; | |
| 109 | + return invalidValue(cases.map(a => { return l(a); }), val, key, parent); | |
| 110 | + } | |
| 111 | + | |
| 112 | + function transformArray(typ: any, val: any): any { | |
| 113 | + // val must be an array with no invalid elements | |
| 114 | + if (!Array.isArray(val)) return invalidValue(l("array"), val, key, parent); | |
| 115 | + return val.map(el => transform(el, typ, getProps)); | |
| 116 | + } | |
| 117 | + | |
| 118 | + function transformDate(val: any): any { | |
| 119 | + if (val === null) { | |
| 120 | + return null; | |
| 121 | + } | |
| 122 | + const d = new Date(val); | |
| 123 | + if (isNaN(d.valueOf())) { | |
| 124 | + return invalidValue(l("Date"), val, key, parent); | |
| 125 | + } | |
| 126 | + return d; | |
| 127 | + } | |
| 128 | + | |
| 129 | + function transformObject(props: { [k: string]: any }, additional: any, val: any): any { | |
| 130 | + if (val === null || typeof val !== "object" || Array.isArray(val)) { | |
| 131 | + return invalidValue(l(ref || "object"), val, key, parent); | |
| 132 | + } | |
| 133 | + const result: any = {}; | |
| 134 | + Object.getOwnPropertyNames(props).forEach(key => { | |
| 135 | + const prop = props[key]; | |
| 136 | + const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined; | |
| 137 | + result[prop.key] = transform(v, prop.typ, getProps, key, ref); | |
| 138 | + }); | |
| 139 | + Object.getOwnPropertyNames(val).forEach(key => { | |
| 140 | + if (!Object.prototype.hasOwnProperty.call(props, key)) { | |
| 141 | + result[key] = transform(val[key], additional, getProps, key, ref); | |
| 142 | + } | |
| 143 | + }); | |
| 144 | + return result; | |
| 145 | + } | |
| 146 | + | |
| 147 | + if (typ === "any") return val; | |
| 148 | + if (typ === null) { | |
| 149 | + if (val === null) return val; | |
| 150 | + return invalidValue(typ, val, key, parent); | |
| 151 | + } | |
| 152 | + if (typ === false) return invalidValue(typ, val, key, parent); | |
| 153 | + let ref: any = undefined; | |
| 154 | + while (typeof typ === "object" && typ.ref !== undefined) { | |
| 155 | + ref = typ.ref; | |
| 156 | + typ = typeMap[typ.ref]; | |
| 157 | + } | |
| 158 | + if (Array.isArray(typ)) return transformEnum(typ, val); | |
| 159 | + if (typeof typ === "object") { | |
| 160 | + return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val) | |
| 161 | + : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) | |
| 162 | + : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) | |
| 163 | + : invalidValue(typ, val, key, parent); | |
| 164 | + } | |
| 165 | + // Numbers can be parsed by Date but shouldn't be. | |
| 166 | + if (typ === Date && typeof val !== "number") return transformDate(val); | |
| 167 | + return transformPrimitive(typ, val); | |
| 168 | +} | |
| 169 | + | |
| 170 | +function cast<T>(val: any, typ: any): T { | |
| 171 | + return transform(val, typ, jsonToJSProps); | |
| 172 | +} | |
| 173 | + | |
| 174 | +function uncast<T>(val: T, typ: any): any { | |
| 175 | + return transform(val, typ, jsToJSONProps); | |
| 176 | +} | |
| 177 | + | |
| 178 | +function l(typ: any) { | |
| 179 | + return { literal: typ }; | |
| 180 | +} | |
| 181 | + | |
| 182 | +function a(typ: any) { | |
| 183 | + return { arrayItems: typ }; | |
| 184 | +} | |
| 185 | + | |
| 186 | +function u(...typs: any[]) { | |
| 187 | + return { unionMembers: typs }; | |
| 188 | +} | |
| 189 | + | |
| 190 | +function o(props: any[], additional: any) { | |
| 191 | + return { props, additional }; | |
| 192 | +} | |
| 193 | + | |
| 194 | +function m(additional: any) { | |
| 195 | + const props: any[] = []; | |
| 196 | + return { props, additional }; | |
| 197 | +} | |
| 198 | + | |
| 199 | +function r(name: string) { | |
| 200 | + return { ref: name }; | |
| 201 | +} | |
| 202 | + | |
| 203 | +const typeMap: any = { | |
| 204 | + "TopLevel": o([ | |
| 205 | + { json: "firstProperty", js: "firstProperty", typ: u(undefined, r("MyObject")) }, | |
| 206 | + { json: "secondProperty", js: "secondProperty", typ: u(undefined, u(a(r("MyObjectA")), r("MyObjectB"))) }, | |
| 207 | + ], false), | |
| 208 | + "MyObject": o([ | |
| 209 | + { json: "a", js: "a", typ: u(undefined, "") }, | |
| 210 | + { json: "b", js: "b", typ: u(undefined, 3.14) }, | |
| 211 | + { json: "c", js: "c", typ: u(undefined, true) }, | |
| 212 | + { json: "d", js: "d", typ: u(undefined, "") }, | |
| 213 | + { json: "e", js: "e", typ: u(undefined, 3.14) }, | |
| 214 | + { json: "f", js: "f", typ: u(undefined, true) }, | |
| 215 | + ], false), | |
| 216 | + "MyObjectA": o([ | |
| 217 | + { json: "a", js: "a", typ: u(undefined, "") }, | |
| 218 | + { json: "b", js: "b", typ: u(undefined, 3.14) }, | |
| 219 | + { json: "c", js: "c", typ: u(undefined, true) }, | |
| 220 | + ], false), | |
| 221 | + "MyObjectB": o([ | |
| 222 | + { json: "d", js: "d", typ: u(undefined, "") }, | |
| 223 | + { json: "e", js: "e", typ: u(undefined, 3.14) }, | |
| 224 | + { json: "f", js: "f", typ: u(undefined, true) }, | |
| 225 | + ], false), | |
| 226 | +}; | |
| 227 | + | |
| 228 | +module.exports = { | |
| 229 | + "topLevelToJson": topLevelToJson, | |
| 230 | + "toTopLevel": toTopLevel, | |
| 231 | +}; |
Aschema-golang/test/inputs/schema/anyof-object-union.schema/default/quicktype.go+184 −0
| @@ -0,0 +1,184 @@ | ||
| 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 "bytes" | |
| 10 | +import "errors" | |
| 11 | + | |
| 12 | +import "encoding/json" | |
| 13 | + | |
| 14 | +func UnmarshalTopLevel(data []byte) (TopLevel, error) { | |
| 15 | + var r TopLevel | |
| 16 | + err := json.Unmarshal(data, &r) | |
| 17 | + return r, err | |
| 18 | +} | |
| 19 | + | |
| 20 | +func (r *TopLevel) Marshal() ([]byte, error) { | |
| 21 | + return json.Marshal(r) | |
| 22 | +} | |
| 23 | + | |
| 24 | +type TopLevel struct { | |
| 25 | + FirstProperty *MyObject `json:"firstProperty,omitempty"` | |
| 26 | + SecondProperty *SecondProperty `json:"secondProperty"` | |
| 27 | +} | |
| 28 | + | |
| 29 | +type MyObject struct { | |
| 30 | + A *string `json:"a,omitempty"` | |
| 31 | + B *float64 `json:"b,omitempty"` | |
| 32 | + C *bool `json:"c,omitempty"` | |
| 33 | + D *string `json:"d,omitempty"` | |
| 34 | + E *float64 `json:"e,omitempty"` | |
| 35 | + F *bool `json:"f,omitempty"` | |
| 36 | +} | |
| 37 | + | |
| 38 | +type MyObjectA struct { | |
| 39 | + A *string `json:"a,omitempty"` | |
| 40 | + B *float64 `json:"b,omitempty"` | |
| 41 | + C *bool `json:"c,omitempty"` | |
| 42 | +} | |
| 43 | + | |
| 44 | +type MyObjectB struct { | |
| 45 | + D *string `json:"d,omitempty"` | |
| 46 | + E *float64 `json:"e,omitempty"` | |
| 47 | + F *bool `json:"f,omitempty"` | |
| 48 | +} | |
| 49 | + | |
| 50 | +type SecondProperty struct { | |
| 51 | + MyObjectAArray []MyObjectA | |
| 52 | + MyObjectB *MyObjectB | |
| 53 | +} | |
| 54 | + | |
| 55 | +func (x *SecondProperty) UnmarshalJSON(data []byte) error { | |
| 56 | + x.MyObjectAArray = nil | |
| 57 | + x.MyObjectB = nil | |
| 58 | + var c MyObjectB | |
| 59 | + object, err := unmarshalUnion(data, nil, nil, nil, nil, true, &x.MyObjectAArray, true, &c, false, nil, false, nil, false) | |
| 60 | + if err != nil { | |
| 61 | + return err | |
| 62 | + } | |
| 63 | + if object { | |
| 64 | + x.MyObjectB = &c | |
| 65 | + } | |
| 66 | + return nil | |
| 67 | +} | |
| 68 | + | |
| 69 | +func (x *SecondProperty) MarshalJSON() ([]byte, error) { | |
| 70 | + return marshalUnion(nil, nil, nil, nil, x.MyObjectAArray != nil, x.MyObjectAArray, x.MyObjectB != nil, x.MyObjectB, false, nil, false, nil, false) | |
| 71 | +} | |
| 72 | + | |
| 73 | +func unmarshalUnion(data []byte, pi **int64, pf **float64, pb **bool, ps **string, haveArray bool, pa interface{}, haveObject bool, pc interface{}, haveMap bool, pm interface{}, haveEnum bool, pe interface{}, nullable bool) (bool, error) { | |
| 74 | + if pi != nil { | |
| 75 | + *pi = nil | |
| 76 | + } | |
| 77 | + if pf != nil { | |
| 78 | + *pf = nil | |
| 79 | + } | |
| 80 | + if pb != nil { | |
| 81 | + *pb = nil | |
| 82 | + } | |
| 83 | + if ps != nil { | |
| 84 | + *ps = nil | |
| 85 | + } | |
| 86 | + | |
| 87 | + dec := json.NewDecoder(bytes.NewReader(data)) | |
| 88 | + dec.UseNumber() | |
| 89 | + tok, err := dec.Token() | |
| 90 | + if err != nil { | |
| 91 | + return false, err | |
| 92 | + } | |
| 93 | + | |
| 94 | + switch v := tok.(type) { | |
| 95 | + case json.Number: | |
| 96 | + if pi != nil { | |
| 97 | + i, err := v.Int64() | |
| 98 | + if err == nil { | |
| 99 | + *pi = &i | |
| 100 | + return false, nil | |
| 101 | + } | |
| 102 | + } | |
| 103 | + if pf != nil { | |
| 104 | + f, err := v.Float64() | |
| 105 | + if err == nil { | |
| 106 | + *pf = &f | |
| 107 | + return false, nil | |
| 108 | + } | |
| 109 | + return false, errors.New("Unparsable number") | |
| 110 | + } | |
| 111 | + return false, errors.New("Union does not contain number") | |
| 112 | + case float64: | |
| 113 | + return false, errors.New("Decoder should not return float64") | |
| 114 | + case bool: | |
| 115 | + if pb != nil { | |
| 116 | + *pb = &v | |
| 117 | + return false, nil | |
| 118 | + } | |
| 119 | + return false, errors.New("Union does not contain bool") | |
| 120 | + case string: | |
| 121 | + if haveEnum { | |
| 122 | + return false, json.Unmarshal(data, pe) | |
| 123 | + } | |
| 124 | + if ps != nil { | |
| 125 | + *ps = &v | |
| 126 | + return false, nil | |
| 127 | + } | |
| 128 | + return false, errors.New("Union does not contain string") | |
| 129 | + case nil: | |
| 130 | + if nullable { | |
| 131 | + return false, nil | |
| 132 | + } | |
| 133 | + return false, errors.New("Union does not contain null") | |
| 134 | + case json.Delim: | |
| 135 | + if v == '{' { | |
| 136 | + if haveObject { | |
| 137 | + return true, json.Unmarshal(data, pc) | |
| 138 | + } | |
| 139 | + if haveMap { | |
| 140 | + return false, json.Unmarshal(data, pm) | |
| 141 | + } | |
| 142 | + return false, errors.New("Union does not contain object") | |
| 143 | + } | |
| 144 | + if v == '[' { | |
| 145 | + if haveArray { | |
| 146 | + return false, json.Unmarshal(data, pa) | |
| 147 | + } | |
| 148 | + return false, errors.New("Union does not contain array") | |
| 149 | + } | |
| 150 | + return false, errors.New("Cannot handle delimiter") | |
| 151 | + } | |
| 152 | + return false, errors.New("Cannot unmarshal union") | |
| 153 | +} | |
| 154 | + | |
| 155 | +func marshalUnion(pi *int64, pf *float64, pb *bool, ps *string, haveArray bool, pa interface{}, haveObject bool, pc interface{}, haveMap bool, pm interface{}, haveEnum bool, pe interface{}, nullable bool) ([]byte, error) { | |
| 156 | + if pi != nil { | |
| 157 | + return json.Marshal(*pi) | |
| 158 | + } | |
| 159 | + if pf != nil { | |
| 160 | + return json.Marshal(*pf) | |
| 161 | + } | |
| 162 | + if pb != nil { | |
| 163 | + return json.Marshal(*pb) | |
| 164 | + } | |
| 165 | + if ps != nil { | |
| 166 | + return json.Marshal(*ps) | |
| 167 | + } | |
| 168 | + if haveArray { | |
| 169 | + return json.Marshal(pa) | |
| 170 | + } | |
| 171 | + if haveObject { | |
| 172 | + return json.Marshal(pc) | |
| 173 | + } | |
| 174 | + if haveMap { | |
| 175 | + return json.Marshal(pm) | |
| 176 | + } | |
| 177 | + if haveEnum { | |
| 178 | + return json.Marshal(pe) | |
| 179 | + } | |
| 180 | + if nullable { | |
| 181 | + return json.Marshal(nil) | |
| 182 | + } | |
| 183 | + return nil, errors.New("Union must not be null") | |
| 184 | +} |
Aschema-haskell/test/inputs/schema/anyof-object-union.schema/default/QuickType.hs+119 −0
| @@ -0,0 +1,119 @@ | ||
| 1 | +{-# LANGUAGE StrictData #-} | |
| 2 | +{-# LANGUAGE OverloadedStrings #-} | |
| 3 | + | |
| 4 | +module QuickType | |
| 5 | + ( QuickType (..) | |
| 6 | + , MyObject (..) | |
| 7 | + , MyObjectA (..) | |
| 8 | + , MyObjectB (..) | |
| 9 | + , SecondProperty (..) | |
| 10 | + , decodeTopLevel | |
| 11 | + ) where | |
| 12 | + | |
| 13 | +import Data.Aeson | |
| 14 | +import Data.Aeson.Types (emptyObject) | |
| 15 | +import Data.ByteString.Lazy (ByteString) | |
| 16 | +import Data.HashMap.Strict (HashMap) | |
| 17 | +import Data.Text (Text) | |
| 18 | + | |
| 19 | +data QuickType = QuickType | |
| 20 | + { firstPropertyQuickType :: Maybe MyObject | |
| 21 | + , secondPropertyQuickType :: Maybe SecondProperty | |
| 22 | + } deriving (Show) | |
| 23 | + | |
| 24 | +data MyObject = MyObject | |
| 25 | + { aMyObject :: Maybe Text | |
| 26 | + , bMyObject :: Maybe Float | |
| 27 | + , cMyObject :: Maybe Bool | |
| 28 | + , dMyObject :: Maybe Text | |
| 29 | + , eMyObject :: Maybe Float | |
| 30 | + , fMyObject :: Maybe Bool | |
| 31 | + } deriving (Show) | |
| 32 | + | |
| 33 | +data SecondProperty | |
| 34 | + = MyObjectAArrayInSecondProperty ([MyObjectA]) | |
| 35 | + | MyObjectBInSecondProperty MyObjectB | |
| 36 | + deriving (Show) | |
| 37 | + | |
| 38 | +data MyObjectA = MyObjectA | |
| 39 | + { aMyObjectA :: Maybe Text | |
| 40 | + , bMyObjectA :: Maybe Float | |
| 41 | + , cMyObjectA :: Maybe Bool | |
| 42 | + } deriving (Show) | |
| 43 | + | |
| 44 | +data MyObjectB = MyObjectB | |
| 45 | + { dMyObjectB :: Maybe Text | |
| 46 | + , eMyObjectB :: Maybe Float | |
| 47 | + , fMyObjectB :: Maybe Bool | |
| 48 | + } deriving (Show) | |
| 49 | + | |
| 50 | +decodeTopLevel :: ByteString -> Maybe QuickType | |
| 51 | +decodeTopLevel = decode | |
| 52 | + | |
| 53 | +instance ToJSON QuickType where | |
| 54 | + toJSON (QuickType firstPropertyQuickType secondPropertyQuickType) = | |
| 55 | + object | |
| 56 | + [ "firstProperty" .= firstPropertyQuickType | |
| 57 | + , "secondProperty" .= secondPropertyQuickType | |
| 58 | + ] | |
| 59 | + | |
| 60 | +instance FromJSON QuickType where | |
| 61 | + parseJSON (Object v) = QuickType | |
| 62 | + <$> v .:? "firstProperty" | |
| 63 | + <*> v .:? "secondProperty" | |
| 64 | + | |
| 65 | +instance ToJSON MyObject where | |
| 66 | + toJSON (MyObject aMyObject bMyObject cMyObject dMyObject eMyObject fMyObject) = | |
| 67 | + object | |
| 68 | + [ "a" .= aMyObject | |
| 69 | + , "b" .= bMyObject | |
| 70 | + , "c" .= cMyObject | |
| 71 | + , "d" .= dMyObject | |
| 72 | + , "e" .= eMyObject | |
| 73 | + , "f" .= fMyObject | |
| 74 | + ] | |
| 75 | + | |
| 76 | +instance FromJSON MyObject where | |
| 77 | + parseJSON (Object v) = MyObject | |
| 78 | + <$> v .:? "a" | |
| 79 | + <*> v .:? "b" | |
| 80 | + <*> v .:? "c" | |
| 81 | + <*> v .:? "d" | |
| 82 | + <*> v .:? "e" | |
| 83 | + <*> v .:? "f" | |
| 84 | + | |
| 85 | +instance ToJSON SecondProperty where | |
| 86 | + toJSON (MyObjectAArrayInSecondProperty x) = toJSON x | |
| 87 | + toJSON (MyObjectBInSecondProperty x) = toJSON x | |
| 88 | + | |
| 89 | +instance FromJSON SecondProperty where | |
| 90 | + parseJSON xs@(Array _) = (fmap MyObjectAArrayInSecondProperty . parseJSON) xs | |
| 91 | + parseJSON xs@(Object _) = (fmap MyObjectBInSecondProperty . parseJSON) xs | |
| 92 | + | |
| 93 | +instance ToJSON MyObjectA where | |
| 94 | + toJSON (MyObjectA aMyObjectA bMyObjectA cMyObjectA) = | |
| 95 | + object | |
| 96 | + [ "a" .= aMyObjectA | |
| 97 | + , "b" .= bMyObjectA | |
| 98 | + , "c" .= cMyObjectA | |
| 99 | + ] | |
| 100 | + | |
| 101 | +instance FromJSON MyObjectA where | |
| 102 | + parseJSON (Object v) = MyObjectA | |
| 103 | + <$> v .:? "a" | |
| 104 | + <*> v .:? "b" | |
| 105 | + <*> v .:? "c" | |
| 106 | + | |
| 107 | +instance ToJSON MyObjectB where | |
| 108 | + toJSON (MyObjectB dMyObjectB eMyObjectB fMyObjectB) = | |
| 109 | + object | |
| 110 | + [ "d" .= dMyObjectB | |
| 111 | + , "e" .= eMyObjectB | |
| 112 | + , "f" .= fMyObjectB | |
| 113 | + ] | |
| 114 | + | |
| 115 | +instance FromJSON MyObjectB where | |
| 116 | + parseJSON (Object v) = MyObjectB | |
| 117 | + <$> v .:? "d" | |
| 118 | + <*> v .:? "e" | |
| 119 | + <*> v .:? "f" |
Aschema-java-datetime-legacy/test/inputs/schema/anyof-object-union.schema/default/src/main/java/io/quicktype/Converter.java+101 −0
| @@ -0,0 +1,101 @@ | ||
| 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 java.util.*; | |
| 23 | +import java.time.LocalDate; | |
| 24 | +import java.time.OffsetDateTime; | |
| 25 | +import java.time.OffsetTime; | |
| 26 | +import java.time.ZoneOffset; | |
| 27 | +import java.time.ZonedDateTime; | |
| 28 | +import java.time.format.DateTimeFormatter; | |
| 29 | +import java.time.format.DateTimeFormatterBuilder; | |
| 30 | +import java.time.temporal.ChronoField; | |
| 31 | + | |
| 32 | +public class Converter { | |
| 33 | + // Date-time helpers | |
| 34 | + | |
| 35 | + private static final DateTimeFormatter DATE_TIME_FORMATTER = new DateTimeFormatterBuilder() | |
| 36 | + .appendOptional(DateTimeFormatter.ISO_DATE_TIME) | |
| 37 | + .appendOptional(DateTimeFormatter.ISO_OFFSET_DATE_TIME) | |
| 38 | + .appendOptional(DateTimeFormatter.ISO_INSTANT) | |
| 39 | + .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SX")) | |
| 40 | + .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssX")) | |
| 41 | + .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) | |
| 42 | + .toFormatter() | |
| 43 | + .withZone(ZoneOffset.UTC); | |
| 44 | + | |
| 45 | + public static OffsetDateTime parseDateTimeString(String str) { | |
| 46 | + return ZonedDateTime.from(Converter.DATE_TIME_FORMATTER.parse(str)).toOffsetDateTime(); | |
| 47 | + } | |
| 48 | + | |
| 49 | + private static final DateTimeFormatter TIME_FORMATTER = new DateTimeFormatterBuilder() | |
| 50 | + .appendOptional(DateTimeFormatter.ISO_TIME) | |
| 51 | + .appendOptional(DateTimeFormatter.ISO_OFFSET_TIME) | |
| 52 | + .parseDefaulting(ChronoField.YEAR, 2020) | |
| 53 | + .parseDefaulting(ChronoField.MONTH_OF_YEAR, 1) | |
| 54 | + .parseDefaulting(ChronoField.DAY_OF_MONTH, 1) | |
| 55 | + .toFormatter() | |
| 56 | + .withZone(ZoneOffset.UTC); | |
| 57 | + | |
| 58 | + public static OffsetTime parseTimeString(String str) { | |
| 59 | + return ZonedDateTime.from(Converter.TIME_FORMATTER.parse(str)).toOffsetDateTime().toOffsetTime(); | |
| 60 | + } | |
| 61 | + // Serialize/deserialize helpers | |
| 62 | + | |
| 63 | + public static TopLevel fromJsonString(String json) throws IOException { | |
| 64 | + return getObjectReader().readValue(json); | |
| 65 | + } | |
| 66 | + | |
| 67 | + public static String toJsonString(TopLevel obj) throws JsonProcessingException { | |
| 68 | + return getObjectWriter().writeValueAsString(obj); | |
| 69 | + } | |
| 70 | + | |
| 71 | + private static ObjectReader reader; | |
| 72 | + private static ObjectWriter writer; | |
| 73 | + | |
| 74 | + private static void instantiateMapper() { | |
| 75 | + ObjectMapper mapper = new ObjectMapper(); | |
| 76 | + mapper.findAndRegisterModules(); | |
| 77 | + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); | |
| 78 | + mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); | |
| 79 | + SimpleModule module = new SimpleModule(); | |
| 80 | + module.addDeserializer(OffsetDateTime.class, new JsonDeserializer<OffsetDateTime>() { | |
| 81 | + @Override | |
| 82 | + public OffsetDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { | |
| 83 | + String value = jsonParser.getText(); | |
| 84 | + return Converter.parseDateTimeString(value); | |
| 85 | + } | |
| 86 | + }); | |
| 87 | + mapper.registerModule(module); | |
| 88 | + reader = mapper.readerFor(TopLevel.class); | |
| 89 | + writer = mapper.writerFor(TopLevel.class); | |
| 90 | + } | |
| 91 | + | |
| 92 | + private static ObjectReader getObjectReader() { | |
| 93 | + if (reader == null) instantiateMapper(); | |
| 94 | + return reader; | |
| 95 | + } | |
| 96 | + | |
| 97 | + private static ObjectWriter getObjectWriter() { | |
| 98 | + if (writer == null) instantiateMapper(); | |
| 99 | + return writer; | |
| 100 | + } | |
| 101 | +} |
Aschema-java-datetime-legacy/test/inputs/schema/anyof-object-union.schema/default/src/main/java/io/quicktype/MyObject.java+42 −0
| @@ -0,0 +1,42 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class MyObject { | |
| 6 | + private String a; | |
| 7 | + private Double b; | |
| 8 | + private Boolean c; | |
| 9 | + private String d; | |
| 10 | + private Double e; | |
| 11 | + private Boolean f; | |
| 12 | + | |
| 13 | + @JsonProperty("a") | |
| 14 | + public String getA() { return a; } | |
| 15 | + @JsonProperty("a") | |
| 16 | + public void setA(String value) { this.a = value; } | |
| 17 | + | |
| 18 | + @JsonProperty("b") | |
| 19 | + public Double getB() { return b; } | |
| 20 | + @JsonProperty("b") | |
| 21 | + public void setB(Double value) { this.b = value; } | |
| 22 | + | |
| 23 | + @JsonProperty("c") | |
| 24 | + public Boolean getC() { return c; } | |
| 25 | + @JsonProperty("c") | |
| 26 | + public void setC(Boolean value) { this.c = value; } | |
| 27 | + | |
| 28 | + @JsonProperty("d") | |
| 29 | + public String getD() { return d; } | |
| 30 | + @JsonProperty("d") | |
| 31 | + public void setD(String value) { this.d = value; } | |
| 32 | + | |
| 33 | + @JsonProperty("e") | |
| 34 | + public Double getE() { return e; } | |
| 35 | + @JsonProperty("e") | |
| 36 | + public void setE(Double value) { this.e = value; } | |
| 37 | + | |
| 38 | + @JsonProperty("f") | |
| 39 | + public Boolean getF() { return f; } | |
| 40 | + @JsonProperty("f") | |
| 41 | + public void setF(Boolean value) { this.f = value; } | |
| 42 | +} |
Aschema-java-datetime-legacy/test/inputs/schema/anyof-object-union.schema/default/src/main/java/io/quicktype/MyObjectA.java+24 −0
| @@ -0,0 +1,24 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class MyObjectA { | |
| 6 | + private String a; | |
| 7 | + private Double b; | |
| 8 | + private Boolean c; | |
| 9 | + | |
| 10 | + @JsonProperty("a") | |
| 11 | + public String getA() { return a; } | |
| 12 | + @JsonProperty("a") | |
| 13 | + public void setA(String value) { this.a = value; } | |
| 14 | + | |
| 15 | + @JsonProperty("b") | |
| 16 | + public Double getB() { return b; } | |
| 17 | + @JsonProperty("b") | |
| 18 | + public void setB(Double value) { this.b = value; } | |
| 19 | + | |
| 20 | + @JsonProperty("c") | |
| 21 | + public Boolean getC() { return c; } | |
| 22 | + @JsonProperty("c") | |
| 23 | + public void setC(Boolean value) { this.c = value; } | |
| 24 | +} |
Aschema-java-datetime-legacy/test/inputs/schema/anyof-object-union.schema/default/src/main/java/io/quicktype/MyObjectB.java+24 −0
| @@ -0,0 +1,24 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class MyObjectB { | |
| 6 | + private String d; | |
| 7 | + private Double e; | |
| 8 | + private Boolean f; | |
| 9 | + | |
| 10 | + @JsonProperty("d") | |
| 11 | + public String getD() { return d; } | |
| 12 | + @JsonProperty("d") | |
| 13 | + public void setD(String value) { this.d = value; } | |
| 14 | + | |
| 15 | + @JsonProperty("e") | |
| 16 | + public Double getE() { return e; } | |
| 17 | + @JsonProperty("e") | |
| 18 | + public void setE(Double value) { this.e = value; } | |
| 19 | + | |
| 20 | + @JsonProperty("f") | |
| 21 | + public Boolean getF() { return f; } | |
| 22 | + @JsonProperty("f") | |
| 23 | + public void setF(Boolean value) { this.f = value; } | |
| 24 | +} |
Aschema-java-datetime-legacy/test/inputs/schema/anyof-object-union.schema/default/src/main/java/io/quicktype/SecondProperty.java+50 −0
| @@ -0,0 +1,50 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import java.io.IOException; | |
| 4 | +import java.io.IOException; | |
| 5 | +import com.fasterxml.jackson.core.*; | |
| 6 | +import com.fasterxml.jackson.databind.*; | |
| 7 | +import com.fasterxml.jackson.databind.annotation.*; | |
| 8 | +import com.fasterxml.jackson.core.type.*; | |
| 9 | +import java.util.List; | |
| 10 | + | |
| 11 | +@JsonDeserialize(using = SecondProperty.Deserializer.class) | |
| 12 | +@JsonSerialize(using = SecondProperty.Serializer.class) | |
| 13 | +public class SecondProperty { | |
| 14 | + public List<MyObjectA> myObjectAArrayValue; | |
| 15 | + public MyObjectB myObjectBValue; | |
| 16 | + | |
| 17 | + static class Deserializer extends JsonDeserializer<SecondProperty> { | |
| 18 | + @Override | |
| 19 | + public SecondProperty deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { | |
| 20 | + SecondProperty value = new SecondProperty(); | |
| 21 | + switch (jsonParser.currentToken()) { | |
| 22 | + case VALUE_NULL: | |
| 23 | + break; | |
| 24 | + case START_ARRAY: | |
| 25 | + value.myObjectAArrayValue = jsonParser.readValueAs(new TypeReference<List<MyObjectA>>() {}); | |
| 26 | + break; | |
| 27 | + case START_OBJECT: | |
| 28 | + value.myObjectBValue = jsonParser.readValueAs(MyObjectB.class); | |
| 29 | + break; | |
| 30 | + default: throw new IOException("Cannot deserialize SecondProperty"); | |
| 31 | + } | |
| 32 | + return value; | |
| 33 | + } | |
| 34 | + } | |
| 35 | + | |
| 36 | + static class Serializer extends JsonSerializer<SecondProperty> { | |
| 37 | + @Override | |
| 38 | + public void serialize(SecondProperty obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { | |
| 39 | + if (obj.myObjectAArrayValue != null) { | |
| 40 | + jsonGenerator.writeObject(obj.myObjectAArrayValue); | |
| 41 | + return; | |
| 42 | + } | |
| 43 | + if (obj.myObjectBValue != null) { | |
| 44 | + jsonGenerator.writeObject(obj.myObjectBValue); | |
| 45 | + return; | |
| 46 | + } | |
| 47 | + jsonGenerator.writeNull(); | |
| 48 | + } | |
| 49 | + } | |
| 50 | +} |
Aschema-java-datetime-legacy/test/inputs/schema/anyof-object-union.schema/default/src/main/java/io/quicktype/TopLevel.java+19 −0
| @@ -0,0 +1,19 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | +import java.util.List; | |
| 5 | + | |
| 6 | +public class TopLevel { | |
| 7 | + private MyObject firstProperty; | |
| 8 | + private SecondProperty secondProperty; | |
| 9 | + | |
| 10 | + @JsonProperty("firstProperty") | |
| 11 | + public MyObject getFirstProperty() { return firstProperty; } | |
| 12 | + @JsonProperty("firstProperty") | |
| 13 | + public void setFirstProperty(MyObject value) { this.firstProperty = value; } | |
| 14 | + | |
| 15 | + @JsonProperty("secondProperty") | |
| 16 | + public SecondProperty getSecondProperty() { return secondProperty; } | |
| 17 | + @JsonProperty("secondProperty") | |
| 18 | + public void setSecondProperty(SecondProperty value) { this.secondProperty = value; } | |
| 19 | +} |
Aschema-java-lombok/test/inputs/schema/anyof-object-union.schema/default/src/main/java/io/quicktype/Converter.java+121 −0
| @@ -0,0 +1,121 @@ | ||
| 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 java.util.*; | |
| 23 | +import java.util.Date; | |
| 24 | +import java.text.SimpleDateFormat; | |
| 25 | + | |
| 26 | +public class Converter { | |
| 27 | + // Date-time helpers | |
| 28 | + | |
| 29 | + private static final String[] DATE_TIME_FORMATS = { | |
| 30 | + "yyyy-MM-dd'T'HH:mm:ss.SX", | |
| 31 | + "yyyy-MM-dd'T'HH:mm:ss.S", | |
| 32 | + "yyyy-MM-dd'T'HH:mm:ssX", | |
| 33 | + "yyyy-MM-dd'T'HH:mm:ss", | |
| 34 | + "yyyy-MM-dd HH:mm:ss.SX", | |
| 35 | + "yyyy-MM-dd HH:mm:ss.S", | |
| 36 | + "yyyy-MM-dd HH:mm:ssX", | |
| 37 | + "yyyy-MM-dd HH:mm:ss", | |
| 38 | + "HH:mm:ss.SZ", | |
| 39 | + "HH:mm:ss.S", | |
| 40 | + "HH:mm:ssZ", | |
| 41 | + "HH:mm:ss", | |
| 42 | + "yyyy-MM-dd", | |
| 43 | + }; | |
| 44 | + | |
| 45 | + public static Date parseAllDateTimeString(String str) { | |
| 46 | + for (String format : DATE_TIME_FORMATS) { | |
| 47 | + try { | |
| 48 | + return new SimpleDateFormat(format).parse(str); | |
| 49 | + } catch (Exception ex) { | |
| 50 | + // Ignored | |
| 51 | + } | |
| 52 | + } | |
| 53 | + return null; | |
| 54 | + } | |
| 55 | + | |
| 56 | + public static String serializeDateTime(Date datetime) { | |
| 57 | + return new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZ").format(datetime); | |
| 58 | + } | |
| 59 | + | |
| 60 | + public static String serializeDate(Date datetime) { | |
| 61 | + return new SimpleDateFormat("yyyy-MM-dd").format(datetime); | |
| 62 | + } | |
| 63 | + | |
| 64 | + public static String serializeTime(Date datetime) { | |
| 65 | + return new SimpleDateFormat("hh:mm:ssZ").format(datetime); | |
| 66 | + } | |
| 67 | + // Serialize/deserialize helpers | |
| 68 | + | |
| 69 | + public static TopLevel fromJsonString(String json) throws IOException { | |
| 70 | + return getObjectReader().readValue(json); | |
| 71 | + } | |
| 72 | + | |
| 73 | + public static String toJsonString(TopLevel obj) throws JsonProcessingException { | |
| 74 | + return getObjectWriter().writeValueAsString(obj); | |
| 75 | + } | |
| 76 | + | |
| 77 | + private static ObjectReader reader; | |
| 78 | + private static ObjectWriter writer; | |
| 79 | + | |
| 80 | + private static void instantiateMapper() { | |
| 81 | + ObjectMapper mapper = new ObjectMapper(); | |
| 82 | + mapper.findAndRegisterModules(); | |
| 83 | + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); | |
| 84 | + mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); | |
| 85 | + SimpleModule module = new SimpleModule(); | |
| 86 | + module.addDeserializer(Date.class, new JsonDeserializer<Date>() { | |
| 87 | + @Override | |
| 88 | + public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { | |
| 89 | + String value = jsonParser.getText(); | |
| 90 | + return Converter.parseAllDateTimeString(value); | |
| 91 | + } | |
| 92 | + }); | |
| 93 | + module.addDeserializer(Date.class, new JsonDeserializer<Date>() { | |
| 94 | + @Override | |
| 95 | + public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { | |
| 96 | + String value = jsonParser.getText(); | |
| 97 | + return Converter.parseAllDateTimeString(value); | |
| 98 | + } | |
| 99 | + }); | |
| 100 | + module.addDeserializer(Date.class, new JsonDeserializer<Date>() { | |
| 101 | + @Override | |
| 102 | + public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { | |
| 103 | + String value = jsonParser.getText(); | |
| 104 | + return Converter.parseAllDateTimeString(value); | |
| 105 | + } | |
| 106 | + }); | |
| 107 | + mapper.registerModule(module); | |
| 108 | + reader = mapper.readerFor(TopLevel.class); | |
| 109 | + writer = mapper.writerFor(TopLevel.class); | |
| 110 | + } | |
| 111 | + | |
| 112 | + private static ObjectReader getObjectReader() { | |
| 113 | + if (reader == null) instantiateMapper(); | |
| 114 | + return reader; | |
| 115 | + } | |
| 116 | + | |
| 117 | + private static ObjectWriter getObjectWriter() { | |
| 118 | + if (writer == null) instantiateMapper(); | |
| 119 | + return writer; | |
| 120 | + } | |
| 121 | +} |
Aschema-java-lombok/test/inputs/schema/anyof-object-union.schema/default/src/main/java/io/quicktype/MyObject.java+42 −0
| @@ -0,0 +1,42 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class MyObject { | |
| 6 | + private String a; | |
| 7 | + private Double b; | |
| 8 | + private Boolean c; | |
| 9 | + private String d; | |
| 10 | + private Double e; | |
| 11 | + private Boolean f; | |
| 12 | + | |
| 13 | + @JsonProperty("a") | |
| 14 | + public String getA() { return a; } | |
| 15 | + @JsonProperty("a") | |
| 16 | + public void setA(String value) { this.a = value; } | |
| 17 | + | |
| 18 | + @JsonProperty("b") | |
| 19 | + public Double getB() { return b; } | |
| 20 | + @JsonProperty("b") | |
| 21 | + public void setB(Double value) { this.b = value; } | |
| 22 | + | |
| 23 | + @JsonProperty("c") | |
| 24 | + public Boolean getC() { return c; } | |
| 25 | + @JsonProperty("c") | |
| 26 | + public void setC(Boolean value) { this.c = value; } | |
| 27 | + | |
| 28 | + @JsonProperty("d") | |
| 29 | + public String getD() { return d; } | |
| 30 | + @JsonProperty("d") | |
| 31 | + public void setD(String value) { this.d = value; } | |
| 32 | + | |
| 33 | + @JsonProperty("e") | |
| 34 | + public Double getE() { return e; } | |
| 35 | + @JsonProperty("e") | |
| 36 | + public void setE(Double value) { this.e = value; } | |
| 37 | + | |
| 38 | + @JsonProperty("f") | |
| 39 | + public Boolean getF() { return f; } | |
| 40 | + @JsonProperty("f") | |
| 41 | + public void setF(Boolean value) { this.f = value; } | |
| 42 | +} |
Aschema-java-lombok/test/inputs/schema/anyof-object-union.schema/default/src/main/java/io/quicktype/MyObjectA.java+24 −0
| @@ -0,0 +1,24 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class MyObjectA { | |
| 6 | + private String a; | |
| 7 | + private Double b; | |
| 8 | + private Boolean c; | |
| 9 | + | |
| 10 | + @JsonProperty("a") | |
| 11 | + public String getA() { return a; } | |
| 12 | + @JsonProperty("a") | |
| 13 | + public void setA(String value) { this.a = value; } | |
| 14 | + | |
| 15 | + @JsonProperty("b") | |
| 16 | + public Double getB() { return b; } | |
| 17 | + @JsonProperty("b") | |
| 18 | + public void setB(Double value) { this.b = value; } | |
| 19 | + | |
| 20 | + @JsonProperty("c") | |
| 21 | + public Boolean getC() { return c; } | |
| 22 | + @JsonProperty("c") | |
| 23 | + public void setC(Boolean value) { this.c = value; } | |
| 24 | +} |
Aschema-java-lombok/test/inputs/schema/anyof-object-union.schema/default/src/main/java/io/quicktype/MyObjectB.java+24 −0
| @@ -0,0 +1,24 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class MyObjectB { | |
| 6 | + private String d; | |
| 7 | + private Double e; | |
| 8 | + private Boolean f; | |
| 9 | + | |
| 10 | + @JsonProperty("d") | |
| 11 | + public String getD() { return d; } | |
| 12 | + @JsonProperty("d") | |
| 13 | + public void setD(String value) { this.d = value; } | |
| 14 | + | |
| 15 | + @JsonProperty("e") | |
| 16 | + public Double getE() { return e; } | |
| 17 | + @JsonProperty("e") | |
| 18 | + public void setE(Double value) { this.e = value; } | |
| 19 | + | |
| 20 | + @JsonProperty("f") | |
| 21 | + public Boolean getF() { return f; } | |
| 22 | + @JsonProperty("f") | |
| 23 | + public void setF(Boolean value) { this.f = value; } | |
| 24 | +} |
Aschema-java-lombok/test/inputs/schema/anyof-object-union.schema/default/src/main/java/io/quicktype/SecondProperty.java+50 −0
| @@ -0,0 +1,50 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import java.io.IOException; | |
| 4 | +import java.io.IOException; | |
| 5 | +import com.fasterxml.jackson.core.*; | |
| 6 | +import com.fasterxml.jackson.databind.*; | |
| 7 | +import com.fasterxml.jackson.databind.annotation.*; | |
| 8 | +import com.fasterxml.jackson.core.type.*; | |
| 9 | +import java.util.List; | |
| 10 | + | |
| 11 | +@JsonDeserialize(using = SecondProperty.Deserializer.class) | |
| 12 | +@JsonSerialize(using = SecondProperty.Serializer.class) | |
| 13 | +public class SecondProperty { | |
| 14 | + public List<MyObjectA> myObjectAArrayValue; | |
| 15 | + public MyObjectB myObjectBValue; | |
| 16 | + | |
| 17 | + static class Deserializer extends JsonDeserializer<SecondProperty> { | |
| 18 | + @Override | |
| 19 | + public SecondProperty deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { | |
| 20 | + SecondProperty value = new SecondProperty(); | |
| 21 | + switch (jsonParser.currentToken()) { | |
| 22 | + case VALUE_NULL: | |
| 23 | + break; | |
| 24 | + case START_ARRAY: | |
| 25 | + value.myObjectAArrayValue = jsonParser.readValueAs(new TypeReference<List<MyObjectA>>() {}); | |
| 26 | + break; | |
| 27 | + case START_OBJECT: | |
| 28 | + value.myObjectBValue = jsonParser.readValueAs(MyObjectB.class); | |
| 29 | + break; | |
| 30 | + default: throw new IOException("Cannot deserialize SecondProperty"); | |
| 31 | + } | |
| 32 | + return value; | |
| 33 | + } | |
| 34 | + } | |
| 35 | + | |
| 36 | + static class Serializer extends JsonSerializer<SecondProperty> { | |
| 37 | + @Override | |
| 38 | + public void serialize(SecondProperty obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { | |
| 39 | + if (obj.myObjectAArrayValue != null) { | |
| 40 | + jsonGenerator.writeObject(obj.myObjectAArrayValue); | |
| 41 | + return; | |
| 42 | + } | |
| 43 | + if (obj.myObjectBValue != null) { | |
| 44 | + jsonGenerator.writeObject(obj.myObjectBValue); | |
| 45 | + return; | |
| 46 | + } | |
| 47 | + jsonGenerator.writeNull(); | |
| 48 | + } | |
| 49 | + } | |
| 50 | +} |
Aschema-java-lombok/test/inputs/schema/anyof-object-union.schema/default/src/main/java/io/quicktype/TopLevel.java+19 −0
| @@ -0,0 +1,19 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | +import java.util.List; | |
| 5 | + | |
| 6 | +public class TopLevel { | |
| 7 | + private MyObject firstProperty; | |
| 8 | + private SecondProperty secondProperty; | |
| 9 | + | |
| 10 | + @JsonProperty("firstProperty") | |
| 11 | + public MyObject getFirstProperty() { return firstProperty; } | |
| 12 | + @JsonProperty("firstProperty") | |
| 13 | + public void setFirstProperty(MyObject value) { this.firstProperty = value; } | |
| 14 | + | |
| 15 | + @JsonProperty("secondProperty") | |
| 16 | + public SecondProperty getSecondProperty() { return secondProperty; } | |
| 17 | + @JsonProperty("secondProperty") | |
| 18 | + public void setSecondProperty(SecondProperty value) { this.secondProperty = value; } | |
| 19 | +} |
Aschema-java/test/inputs/schema/anyof-object-union.schema/default/src/main/java/io/quicktype/Converter.java+101 −0
| @@ -0,0 +1,101 @@ | ||
| 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 java.util.*; | |
| 23 | +import java.time.LocalDate; | |
| 24 | +import java.time.OffsetDateTime; | |
| 25 | +import java.time.OffsetTime; | |
| 26 | +import java.time.ZoneOffset; | |
| 27 | +import java.time.ZonedDateTime; | |
| 28 | +import java.time.format.DateTimeFormatter; | |
| 29 | +import java.time.format.DateTimeFormatterBuilder; | |
| 30 | +import java.time.temporal.ChronoField; | |
| 31 | + | |
| 32 | +public class Converter { | |
| 33 | + // Date-time helpers | |
| 34 | + | |
| 35 | + private static final DateTimeFormatter DATE_TIME_FORMATTER = new DateTimeFormatterBuilder() | |
| 36 | + .appendOptional(DateTimeFormatter.ISO_DATE_TIME) | |
| 37 | + .appendOptional(DateTimeFormatter.ISO_OFFSET_DATE_TIME) | |
| 38 | + .appendOptional(DateTimeFormatter.ISO_INSTANT) | |
| 39 | + .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SX")) | |
| 40 | + .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssX")) | |
| 41 | + .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) | |
| 42 | + .toFormatter() | |
| 43 | + .withZone(ZoneOffset.UTC); | |
| 44 | + | |
| 45 | + public static OffsetDateTime parseDateTimeString(String str) { | |
| 46 | + return ZonedDateTime.from(Converter.DATE_TIME_FORMATTER.parse(str)).toOffsetDateTime(); | |
| 47 | + } | |
| 48 | + | |
| 49 | + private static final DateTimeFormatter TIME_FORMATTER = new DateTimeFormatterBuilder() | |
| 50 | + .appendOptional(DateTimeFormatter.ISO_TIME) | |
| 51 | + .appendOptional(DateTimeFormatter.ISO_OFFSET_TIME) | |
| 52 | + .parseDefaulting(ChronoField.YEAR, 2020) | |
| 53 | + .parseDefaulting(ChronoField.MONTH_OF_YEAR, 1) | |
| 54 | + .parseDefaulting(ChronoField.DAY_OF_MONTH, 1) | |
| 55 | + .toFormatter() | |
| 56 | + .withZone(ZoneOffset.UTC); | |
| 57 | + | |
| 58 | + public static OffsetTime parseTimeString(String str) { | |
| 59 | + return ZonedDateTime.from(Converter.TIME_FORMATTER.parse(str)).toOffsetDateTime().toOffsetTime(); | |
| 60 | + } | |
| 61 | + // Serialize/deserialize helpers | |
| 62 | + | |
| 63 | + public static TopLevel fromJsonString(String json) throws IOException { | |
| 64 | + return getObjectReader().readValue(json); | |
| 65 | + } | |
| 66 | + | |
| 67 | + public static String toJsonString(TopLevel obj) throws JsonProcessingException { | |
| 68 | + return getObjectWriter().writeValueAsString(obj); | |
| 69 | + } | |
| 70 | + | |
| 71 | + private static ObjectReader reader; | |
| 72 | + private static ObjectWriter writer; | |
| 73 | + | |
| 74 | + private static void instantiateMapper() { | |
| 75 | + ObjectMapper mapper = new ObjectMapper(); | |
| 76 | + mapper.findAndRegisterModules(); | |
| 77 | + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); | |
| 78 | + mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); | |
| 79 | + SimpleModule module = new SimpleModule(); | |
| 80 | + module.addDeserializer(OffsetDateTime.class, new JsonDeserializer<OffsetDateTime>() { | |
| 81 | + @Override | |
| 82 | + public OffsetDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { | |
| 83 | + String value = jsonParser.getText(); | |
| 84 | + return Converter.parseDateTimeString(value); | |
| 85 | + } | |
| 86 | + }); | |
| 87 | + mapper.registerModule(module); | |
| 88 | + reader = mapper.readerFor(TopLevel.class); | |
| 89 | + writer = mapper.writerFor(TopLevel.class); | |
| 90 | + } | |
| 91 | + | |
| 92 | + private static ObjectReader getObjectReader() { | |
| 93 | + if (reader == null) instantiateMapper(); | |
| 94 | + return reader; | |
| 95 | + } | |
| 96 | + | |
| 97 | + private static ObjectWriter getObjectWriter() { | |
| 98 | + if (writer == null) instantiateMapper(); | |
| 99 | + return writer; | |
| 100 | + } | |
| 101 | +} |
Aschema-java/test/inputs/schema/anyof-object-union.schema/default/src/main/java/io/quicktype/MyObject.java+42 −0
| @@ -0,0 +1,42 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class MyObject { | |
| 6 | + private String a; | |
| 7 | + private Double b; | |
| 8 | + private Boolean c; | |
| 9 | + private String d; | |
| 10 | + private Double e; | |
| 11 | + private Boolean f; | |
| 12 | + | |
| 13 | + @JsonProperty("a") | |
| 14 | + public String getA() { return a; } | |
| 15 | + @JsonProperty("a") | |
| 16 | + public void setA(String value) { this.a = value; } | |
| 17 | + | |
| 18 | + @JsonProperty("b") | |
| 19 | + public Double getB() { return b; } | |
| 20 | + @JsonProperty("b") | |
| 21 | + public void setB(Double value) { this.b = value; } | |
| 22 | + | |
| 23 | + @JsonProperty("c") | |
| 24 | + public Boolean getC() { return c; } | |
| 25 | + @JsonProperty("c") | |
| 26 | + public void setC(Boolean value) { this.c = value; } | |
| 27 | + | |
| 28 | + @JsonProperty("d") | |
| 29 | + public String getD() { return d; } | |
| 30 | + @JsonProperty("d") | |
| 31 | + public void setD(String value) { this.d = value; } | |
| 32 | + | |
| 33 | + @JsonProperty("e") | |
| 34 | + public Double getE() { return e; } | |
| 35 | + @JsonProperty("e") | |
| 36 | + public void setE(Double value) { this.e = value; } | |
| 37 | + | |
| 38 | + @JsonProperty("f") | |
| 39 | + public Boolean getF() { return f; } | |
| 40 | + @JsonProperty("f") | |
| 41 | + public void setF(Boolean value) { this.f = value; } | |
| 42 | +} |
Aschema-java/test/inputs/schema/anyof-object-union.schema/default/src/main/java/io/quicktype/MyObjectA.java+24 −0
| @@ -0,0 +1,24 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class MyObjectA { | |
| 6 | + private String a; | |
| 7 | + private Double b; | |
| 8 | + private Boolean c; | |
| 9 | + | |
| 10 | + @JsonProperty("a") | |
| 11 | + public String getA() { return a; } | |
| 12 | + @JsonProperty("a") | |
| 13 | + public void setA(String value) { this.a = value; } | |
| 14 | + | |
| 15 | + @JsonProperty("b") | |
| 16 | + public Double getB() { return b; } | |
| 17 | + @JsonProperty("b") | |
| 18 | + public void setB(Double value) { this.b = value; } | |
| 19 | + | |
| 20 | + @JsonProperty("c") | |
| 21 | + public Boolean getC() { return c; } | |
| 22 | + @JsonProperty("c") | |
| 23 | + public void setC(Boolean value) { this.c = value; } | |
| 24 | +} |
Aschema-java/test/inputs/schema/anyof-object-union.schema/default/src/main/java/io/quicktype/MyObjectB.java+24 −0
| @@ -0,0 +1,24 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | + | |
| 5 | +public class MyObjectB { | |
| 6 | + private String d; | |
| 7 | + private Double e; | |
| 8 | + private Boolean f; | |
| 9 | + | |
| 10 | + @JsonProperty("d") | |
| 11 | + public String getD() { return d; } | |
| 12 | + @JsonProperty("d") | |
| 13 | + public void setD(String value) { this.d = value; } | |
| 14 | + | |
| 15 | + @JsonProperty("e") | |
| 16 | + public Double getE() { return e; } | |
| 17 | + @JsonProperty("e") | |
| 18 | + public void setE(Double value) { this.e = value; } | |
| 19 | + | |
| 20 | + @JsonProperty("f") | |
| 21 | + public Boolean getF() { return f; } | |
| 22 | + @JsonProperty("f") | |
| 23 | + public void setF(Boolean value) { this.f = value; } | |
| 24 | +} |
Aschema-java/test/inputs/schema/anyof-object-union.schema/default/src/main/java/io/quicktype/SecondProperty.java+50 −0
| @@ -0,0 +1,50 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import java.io.IOException; | |
| 4 | +import java.io.IOException; | |
| 5 | +import com.fasterxml.jackson.core.*; | |
| 6 | +import com.fasterxml.jackson.databind.*; | |
| 7 | +import com.fasterxml.jackson.databind.annotation.*; | |
| 8 | +import com.fasterxml.jackson.core.type.*; | |
| 9 | +import java.util.List; | |
| 10 | + | |
| 11 | +@JsonDeserialize(using = SecondProperty.Deserializer.class) | |
| 12 | +@JsonSerialize(using = SecondProperty.Serializer.class) | |
| 13 | +public class SecondProperty { | |
| 14 | + public List<MyObjectA> myObjectAArrayValue; | |
| 15 | + public MyObjectB myObjectBValue; | |
| 16 | + | |
| 17 | + static class Deserializer extends JsonDeserializer<SecondProperty> { | |
| 18 | + @Override | |
| 19 | + public SecondProperty deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { | |
| 20 | + SecondProperty value = new SecondProperty(); | |
| 21 | + switch (jsonParser.currentToken()) { | |
| 22 | + case VALUE_NULL: | |
| 23 | + break; | |
| 24 | + case START_ARRAY: | |
| 25 | + value.myObjectAArrayValue = jsonParser.readValueAs(new TypeReference<List<MyObjectA>>() {}); | |
| 26 | + break; | |
| 27 | + case START_OBJECT: | |
| 28 | + value.myObjectBValue = jsonParser.readValueAs(MyObjectB.class); | |
| 29 | + break; | |
| 30 | + default: throw new IOException("Cannot deserialize SecondProperty"); | |
| 31 | + } | |
| 32 | + return value; | |
| 33 | + } | |
| 34 | + } | |
| 35 | + | |
| 36 | + static class Serializer extends JsonSerializer<SecondProperty> { | |
| 37 | + @Override | |
| 38 | + public void serialize(SecondProperty obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { | |
| 39 | + if (obj.myObjectAArrayValue != null) { | |
| 40 | + jsonGenerator.writeObject(obj.myObjectAArrayValue); | |
| 41 | + return; | |
| 42 | + } | |
| 43 | + if (obj.myObjectBValue != null) { | |
| 44 | + jsonGenerator.writeObject(obj.myObjectBValue); | |
| 45 | + return; | |
| 46 | + } | |
| 47 | + jsonGenerator.writeNull(); | |
| 48 | + } | |
| 49 | + } | |
| 50 | +} |
Aschema-java/test/inputs/schema/anyof-object-union.schema/default/src/main/java/io/quicktype/TopLevel.java+19 −0
| @@ -0,0 +1,19 @@ | ||
| 1 | +package io.quicktype; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.*; | |
| 4 | +import java.util.List; | |
| 5 | + | |
| 6 | +public class TopLevel { | |
| 7 | + private MyObject firstProperty; | |
| 8 | + private SecondProperty secondProperty; | |
| 9 | + | |
| 10 | + @JsonProperty("firstProperty") | |
| 11 | + public MyObject getFirstProperty() { return firstProperty; } | |
| 12 | + @JsonProperty("firstProperty") | |
| 13 | + public void setFirstProperty(MyObject value) { this.firstProperty = value; } | |
| 14 | + | |
| 15 | + @JsonProperty("secondProperty") | |
| 16 | + public SecondProperty getSecondProperty() { return secondProperty; } | |
| 17 | + @JsonProperty("secondProperty") | |
| 18 | + public void setSecondProperty(SecondProperty value) { this.secondProperty = value; } | |
| 19 | +} |
Aschema-javascript/test/inputs/schema/anyof-object-union.schema/default/TopLevel.js+201 −0
| @@ -0,0 +1,201 @@ | ||
| 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 | + return val.map(el => transform(el, typ, getProps)); | |
| 86 | + } | |
| 87 | + | |
| 88 | + function transformDate(val) { | |
| 89 | + if (val === null) { | |
| 90 | + return null; | |
| 91 | + } | |
| 92 | + const d = new Date(val); | |
| 93 | + if (isNaN(d.valueOf())) { | |
| 94 | + return invalidValue(l("Date"), val, key, parent); | |
| 95 | + } | |
| 96 | + return d; | |
| 97 | + } | |
| 98 | + | |
| 99 | + function transformObject(props, additional, val) { | |
| 100 | + if (val === null || typeof val !== "object" || Array.isArray(val)) { | |
| 101 | + return invalidValue(l(ref || "object"), val, key, parent); | |
| 102 | + } | |
| 103 | + const result = {}; | |
| 104 | + Object.getOwnPropertyNames(props).forEach(key => { | |
| 105 | + const prop = props[key]; | |
| 106 | + const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined; | |
| 107 | + result[prop.key] = transform(v, prop.typ, getProps, key, ref); | |
| 108 | + }); | |
| 109 | + Object.getOwnPropertyNames(val).forEach(key => { | |
| 110 | + if (!Object.prototype.hasOwnProperty.call(props, key)) { | |
| 111 | + result[key] = transform(val[key], additional, getProps, key, ref); | |
| 112 | + } | |
| 113 | + }); | |
| 114 | + return result; | |
| 115 | + } | |
| 116 | + | |
| 117 | + if (typ === "any") return val; | |
| 118 | + if (typ === null) { | |
| 119 | + if (val === null) return val; | |
| 120 | + return invalidValue(typ, val, key, parent); | |
| 121 | + } | |
| 122 | + if (typ === false) return invalidValue(typ, val, key, parent); | |
| 123 | + let ref = undefined; | |
| 124 | + while (typeof typ === "object" && typ.ref !== undefined) { | |
| 125 | + ref = typ.ref; | |
| 126 | + typ = typeMap[typ.ref]; | |
| 127 | + } | |
| 128 | + if (Array.isArray(typ)) return transformEnum(typ, val); | |
| 129 | + if (typeof typ === "object") { | |
| 130 | + return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val) | |
| 131 | + : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) | |
| 132 | + : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) | |
| 133 | + : invalidValue(typ, val, key, parent); | |
| 134 | + } | |
| 135 | + // Numbers can be parsed by Date but shouldn't be. | |
| 136 | + if (typ === Date && typeof val !== "number") return transformDate(val); | |
| 137 | + return transformPrimitive(typ, val); | |
| 138 | +} | |
| 139 | + | |
| 140 | +function cast(val, typ) { | |
| 141 | + return transform(val, typ, jsonToJSProps); | |
| 142 | +} | |
| 143 | + | |
| 144 | +function uncast(val, typ) { | |
| 145 | + return transform(val, typ, jsToJSONProps); | |
| 146 | +} | |
| 147 | + | |
| 148 | +function l(typ) { | |
| 149 | + return { literal: typ }; | |
| 150 | +} | |
| 151 | + | |
| 152 | +function a(typ) { | |
| 153 | + return { arrayItems: typ }; | |
| 154 | +} | |
| 155 | + | |
| 156 | +function u(...typs) { | |
| 157 | + return { unionMembers: typs }; | |
| 158 | +} | |
| 159 | + | |
| 160 | +function o(props, additional) { | |
| 161 | + return { props, additional }; | |
| 162 | +} | |
| 163 | + | |
| 164 | +function m(additional) { | |
| 165 | + const props = []; | |
| 166 | + return { props, additional }; | |
| 167 | +} | |
| 168 | + | |
| 169 | +function r(name) { | |
| 170 | + return { ref: name }; | |
| 171 | +} | |
| 172 | + | |
| 173 | +const typeMap = { | |
| 174 | + "TopLevel": o([ | |
| 175 | + { json: "firstProperty", js: "firstProperty", typ: u(undefined, r("MyObject")) }, | |
| 176 | + { json: "secondProperty", js: "secondProperty", typ: u(undefined, u(a(r("MyObjectA")), r("MyObjectB"))) }, | |
| 177 | + ], false), | |
| 178 | + "MyObject": o([ | |
| 179 | + { json: "a", js: "a", typ: u(undefined, "") }, | |
| 180 | + { json: "b", js: "b", typ: u(undefined, 3.14) }, | |
| 181 | + { json: "c", js: "c", typ: u(undefined, true) }, | |
| 182 | + { json: "d", js: "d", typ: u(undefined, "") }, | |
| 183 | + { json: "e", js: "e", typ: u(undefined, 3.14) }, | |
| 184 | + { json: "f", js: "f", typ: u(undefined, true) }, | |
| 185 | + ], false), | |
| 186 | + "MyObjectA": o([ | |
| 187 | + { json: "a", js: "a", typ: u(undefined, "") }, | |
| 188 | + { json: "b", js: "b", typ: u(undefined, 3.14) }, | |
| 189 | + { json: "c", js: "c", typ: u(undefined, true) }, | |
| 190 | + ], false), | |
| 191 | + "MyObjectB": o([ | |
| 192 | + { json: "d", js: "d", typ: u(undefined, "") }, | |
| 193 | + { json: "e", js: "e", typ: u(undefined, 3.14) }, | |
| 194 | + { json: "f", js: "f", typ: u(undefined, true) }, | |
| 195 | + ], false), | |
| 196 | +}; | |
| 197 | + | |
| 198 | +module.exports = { | |
| 199 | + "topLevelToJson": topLevelToJson, | |
| 200 | + "toTopLevel": toTopLevel, | |
| 201 | +}; |
Aschema-kotlin-jackson/test/inputs/schema/anyof-object-union.schema/default/TopLevel.kt+81 −0
| @@ -0,0 +1,81 @@ | ||
| 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 com.fasterxml.jackson.annotation.* | |
| 8 | +import com.fasterxml.jackson.core.* | |
| 9 | +import com.fasterxml.jackson.databind.* | |
| 10 | +import com.fasterxml.jackson.databind.deser.std.StdDeserializer | |
| 11 | +import com.fasterxml.jackson.databind.module.SimpleModule | |
| 12 | +import com.fasterxml.jackson.databind.node.* | |
| 13 | +import com.fasterxml.jackson.databind.ser.std.StdSerializer | |
| 14 | +import com.fasterxml.jackson.module.kotlin.* | |
| 15 | + | |
| 16 | + | |
| 17 | +@Suppress("UNCHECKED_CAST") | |
| 18 | +private fun <T> ObjectMapper.convert(k: kotlin.reflect.KClass<*>, fromJson: (JsonNode) -> T, toJson: (T) -> String, isUnion: Boolean = false) = registerModule(SimpleModule().apply { | |
| 19 | + addSerializer(k.java as Class<T>, object : StdSerializer<T>(k.java as Class<T>) { | |
| 20 | + override fun serialize(value: T, gen: JsonGenerator, provider: SerializerProvider) = gen.writeRawValue(toJson(value)) | |
| 21 | + }) | |
| 22 | + addDeserializer(k.java as Class<T>, object : StdDeserializer<T>(k.java as Class<T>) { | |
| 23 | + override fun deserialize(p: JsonParser, ctxt: DeserializationContext) = fromJson(p.readValueAsTree()) | |
| 24 | + }) | |
| 25 | +}) | |
| 26 | + | |
| 27 | +val mapper = jacksonObjectMapper().apply { | |
| 28 | + propertyNamingStrategy = PropertyNamingStrategy.LOWER_CAMEL_CASE | |
| 29 | + setSerializationInclusion(JsonInclude.Include.NON_NULL) | |
| 30 | + convert(SecondProperty::class, { SecondProperty.fromJson(it) }, { it.toJson() }, true) | |
| 31 | +} | |
| 32 | + | |
| 33 | +data class TopLevel ( | |
| 34 | + val firstProperty: MyObject? = null, | |
| 35 | + val secondProperty: SecondProperty? = null | |
| 36 | +) { | |
| 37 | + fun toJson() = mapper.writeValueAsString(this) | |
| 38 | + | |
| 39 | + companion object { | |
| 40 | + fun fromJson(json: String) = mapper.readValue<TopLevel>(json) | |
| 41 | + } | |
| 42 | +} | |
| 43 | + | |
| 44 | +data class MyObject ( | |
| 45 | + val a: String? = null, | |
| 46 | + val b: Double? = null, | |
| 47 | + val c: Boolean? = null, | |
| 48 | + val d: String? = null, | |
| 49 | + val e: Double? = null, | |
| 50 | + val f: Boolean? = null | |
| 51 | +) | |
| 52 | + | |
| 53 | +sealed class SecondProperty { | |
| 54 | + class MyObjectAArrayValue(val value: List<MyObjectA>) : SecondProperty() | |
| 55 | + class MyObjectBValue(val value: MyObjectB) : SecondProperty() | |
| 56 | + | |
| 57 | + fun toJson(): String = mapper.writeValueAsString(when (this) { | |
| 58 | + is MyObjectAArrayValue -> this.value | |
| 59 | + is MyObjectBValue -> this.value | |
| 60 | + }) | |
| 61 | + | |
| 62 | + companion object { | |
| 63 | + fun fromJson(jn: JsonNode): SecondProperty = when (jn) { | |
| 64 | + is ArrayNode -> MyObjectAArrayValue(mapper.treeToValue(jn)) | |
| 65 | + is ObjectNode -> MyObjectBValue(mapper.treeToValue(jn)) | |
| 66 | + else -> throw IllegalArgumentException() | |
| 67 | + } | |
| 68 | + } | |
| 69 | +} | |
| 70 | + | |
| 71 | +data class MyObjectA ( | |
| 72 | + val a: String? = null, | |
| 73 | + val b: Double? = null, | |
| 74 | + val c: Boolean? = null | |
| 75 | +) | |
| 76 | + | |
| 77 | +data class MyObjectB ( | |
| 78 | + val d: String? = null, | |
| 79 | + val e: Double? = null, | |
| 80 | + val f: Boolean? = null | |
| 81 | +) |
Aschema-php/test/inputs/schema/anyof-object-union.schema/default/TopLevel.php+1,101 −0
| @@ -0,0 +1,1101 @@ | ||
| 1 | +<?php | |
| 2 | +declare(strict_types=1); | |
| 3 | + | |
| 4 | +// This is an autogenerated file:TopLevel | |
| 5 | + | |
| 6 | +class TopLevel { | |
| 7 | + private ?MyObject $firstProperty; // json:firstProperty Optional | |
| 8 | + private MyObjectB|array|null $secondProperty; // json:secondProperty Optional | |
| 9 | + | |
| 10 | + /** | |
| 11 | + * @param MyObject|null $firstProperty | |
| 12 | + * @param MyObjectB|array|null $secondProperty | |
| 13 | + */ | |
| 14 | + public function __construct(?MyObject $firstProperty, MyObjectB|array|null $secondProperty) { | |
| 15 | + $this->firstProperty = $firstProperty; | |
| 16 | + $this->secondProperty = $secondProperty; | |
| 17 | + } | |
| 18 | + | |
| 19 | + /** | |
| 20 | + * @param ?stdClass $value | |
| 21 | + * @throws Exception | |
| 22 | + * @return ?MyObject | |
| 23 | + */ | |
| 24 | + public static function fromFirstProperty(?stdClass $value): ?MyObject { | |
| 25 | + if (!is_null($value)) { | |
| 26 | + return MyObject::from($value); /*class*/ | |
| 27 | + } else { | |
| 28 | + return null; | |
| 29 | + } | |
| 30 | + } | |
| 31 | + | |
| 32 | + /** | |
| 33 | + * @throws Exception | |
| 34 | + * @return ?stdClass | |
| 35 | + */ | |
| 36 | + public function toFirstProperty(): ?stdClass { | |
| 37 | + if (TopLevel::validateFirstProperty($this->firstProperty)) { | |
| 38 | + if (!is_null($this->firstProperty)) { | |
| 39 | + return $this->firstProperty->to(); /*class*/ | |
| 40 | + } else { | |
| 41 | + return null; | |
| 42 | + } | |
| 43 | + } | |
| 44 | + throw new Exception('never get to this TopLevel::firstProperty'); | |
| 45 | + } | |
| 46 | + | |
| 47 | + /** | |
| 48 | + * @param MyObject|null | |
| 49 | + * @return bool | |
| 50 | + * @throws Exception | |
| 51 | + */ | |
| 52 | + public static function validateFirstProperty(?MyObject $value): bool { | |
| 53 | + if (!is_null($value)) { | |
| 54 | + $value->validate(); | |
| 55 | + } | |
| 56 | + return true; | |
| 57 | + } | |
| 58 | + | |
| 59 | + /** | |
| 60 | + * @throws Exception | |
| 61 | + * @return ?MyObject | |
| 62 | + */ | |
| 63 | + public function getFirstProperty(): ?MyObject { | |
| 64 | + if (TopLevel::validateFirstProperty($this->firstProperty)) { | |
| 65 | + return $this->firstProperty; | |
| 66 | + } | |
| 67 | + throw new Exception('never get to getFirstProperty TopLevel::firstProperty'); | |
| 68 | + } | |
| 69 | + | |
| 70 | + /** | |
| 71 | + * @return ?MyObject | |
| 72 | + */ | |
| 73 | + public static function sampleFirstProperty(): ?MyObject { | |
| 74 | + return MyObject::sample(); /*31:firstProperty*/ | |
| 75 | + } | |
| 76 | + | |
| 77 | + /** | |
| 78 | + * @param stdClass|array|null $value | |
| 79 | + * @throws Exception | |
| 80 | + * @return MyObjectB|array|null | |
| 81 | + */ | |
| 82 | + public static function fromSecondProperty(stdClass|array|null $value): MyObjectB|array|null { | |
| 83 | + if (is_null($value)) { | |
| 84 | + return $value; /*null*/ | |
| 85 | + } elseif (is_object($value)) { | |
| 86 | + return MyObjectB::from($value); /*class*/ | |
| 87 | + } elseif (is_array($value)) { | |
| 88 | + return array_map(function ($value) { | |
| 89 | + return MyObjectA::from($value); /*class*/ | |
| 90 | + }, $value); | |
| 91 | + } else { | |
| 92 | + throw new Exception('Cannot deserialize union value in TopLevel'); | |
| 93 | + } | |
| 94 | + } | |
| 95 | + | |
| 96 | + /** | |
| 97 | + * @throws Exception | |
| 98 | + * @return stdClass|array|null | |
| 99 | + */ | |
| 100 | + public function toSecondProperty(): stdClass|array|null { | |
| 101 | + if (TopLevel::validateSecondProperty($this->secondProperty)) { | |
| 102 | + if (is_null($this->secondProperty)) { | |
| 103 | + return $this->secondProperty; /*null*/ | |
| 104 | + } elseif ($this->secondProperty instanceof MyObjectB) { | |
| 105 | + return $this->secondProperty->to(); /*class*/ | |
| 106 | + } elseif (is_array($this->secondProperty)) { | |
| 107 | + return array_map(function ($value) { | |
| 108 | + return $value->to(); /*class*/ | |
| 109 | + }, $this->secondProperty); | |
| 110 | + } else { | |
| 111 | + throw new Exception('Union value has no matching member in TopLevel'); | |
| 112 | + } | |
| 113 | + } | |
| 114 | + throw new Exception('never get to this TopLevel::secondProperty'); | |
| 115 | + } | |
| 116 | + | |
| 117 | + /** | |
| 118 | + * @param MyObjectB|array|null | |
| 119 | + * @return bool | |
| 120 | + * @throws Exception | |
| 121 | + */ | |
| 122 | + public static function validateSecondProperty(MyObjectB|array|null $value): bool { | |
| 123 | + if (is_null($value)) { | |
| 124 | + if (!is_null($value)) { | |
| 125 | + throw new Exception("Attribute Error:TopLevel::secondProperty"); | |
| 126 | + } | |
| 127 | + } elseif ($value instanceof MyObjectB) { | |
| 128 | + $value->validate(); | |
| 129 | + } elseif (is_array($value)) { | |
| 130 | + if (!is_array($value)) { | |
| 131 | + throw new Exception("Attribute Error:TopLevel::secondProperty"); | |
| 132 | + } | |
| 133 | + array_walk($value, function($value_v) { | |
| 134 | + $value_v->validate(); | |
| 135 | + }); | |
| 136 | + } else { | |
| 137 | + throw new Exception("Attribute Error:TopLevel::secondProperty"); | |
| 138 | + } | |
| 139 | + return true; | |
| 140 | + } | |
| 141 | + | |
| 142 | + /** | |
| 143 | + * @throws Exception | |
| 144 | + * @return MyObjectB|array|null | |
| 145 | + */ | |
| 146 | + public function getSecondProperty(): MyObjectB|array|null { | |
| 147 | + if (TopLevel::validateSecondProperty($this->secondProperty)) { | |
| 148 | + return $this->secondProperty; | |
| 149 | + } | |
| 150 | + throw new Exception('never get to getSecondProperty TopLevel::secondProperty'); | |
| 151 | + } | |
| 152 | + | |
| 153 | + /** | |
| 154 | + * @return MyObjectB|array|null | |
| 155 | + */ | |
| 156 | + public static function sampleSecondProperty(): MyObjectB|array|null { | |
| 157 | + return MyObjectB::sample(); /*32:secondProperty*/ | |
| 158 | + } | |
| 159 | + | |
| 160 | + /** | |
| 161 | + * @throws Exception | |
| 162 | + * @return bool | |
| 163 | + */ | |
| 164 | + public function validate(): bool { | |
| 165 | + return TopLevel::validateFirstProperty($this->firstProperty) | |
| 166 | + || TopLevel::validateSecondProperty($this->secondProperty); | |
| 167 | + } | |
| 168 | + | |
| 169 | + /** | |
| 170 | + * @return stdClass | |
| 171 | + * @throws Exception | |
| 172 | + */ | |
| 173 | + public function to(): stdClass { | |
| 174 | + $out = new stdClass(); | |
| 175 | + $out->{'firstProperty'} = $this->toFirstProperty(); | |
| 176 | + $out->{'secondProperty'} = $this->toSecondProperty(); | |
| 177 | + return $out; | |
| 178 | + } | |
| 179 | + | |
| 180 | + /** | |
| 181 | + * @param stdClass $obj | |
| 182 | + * @return TopLevel | |
| 183 | + * @throws Exception | |
| 184 | + */ | |
| 185 | + public static function from(stdClass $obj): TopLevel { | |
| 186 | + return new TopLevel( | |
| 187 | + TopLevel::fromFirstProperty($obj->{'firstProperty'}) | |
| 188 | + ,TopLevel::fromSecondProperty($obj->{'secondProperty'}) | |
| 189 | + ); | |
| 190 | + } | |
| 191 | + | |
| 192 | + /** | |
| 193 | + * @return TopLevel | |
| 194 | + */ | |
| 195 | + public static function sample(): TopLevel { | |
| 196 | + return new TopLevel( | |
| 197 | + TopLevel::sampleFirstProperty() | |
| 198 | + ,TopLevel::sampleSecondProperty() | |
| 199 | + ); | |
| 200 | + } | |
| 201 | +} | |
| 202 | + | |
| 203 | +// This is an autogenerated file:MyObject | |
| 204 | + | |
| 205 | +class MyObject { | |
| 206 | + private ?string $a; // json:a Optional | |
| 207 | + private ?float $b; // json:b Optional | |
| 208 | + private ?bool $c; // json:c Optional | |
| 209 | + private ?string $d; // json:d Optional | |
| 210 | + private ?float $e; // json:e Optional | |
| 211 | + private ?bool $f; // json:f Optional | |
| 212 | + | |
| 213 | + /** | |
| 214 | + * @param string|null $a | |
| 215 | + * @param float|null $b | |
| 216 | + * @param bool|null $c | |
| 217 | + * @param string|null $d | |
| 218 | + * @param float|null $e | |
| 219 | + * @param bool|null $f | |
| 220 | + */ | |
| 221 | + public function __construct(?string $a, ?float $b, ?bool $c, ?string $d, ?float $e, ?bool $f) { | |
| 222 | + $this->a = $a; | |
| 223 | + $this->b = $b; | |
| 224 | + $this->c = $c; | |
| 225 | + $this->d = $d; | |
| 226 | + $this->e = $e; | |
| 227 | + $this->f = $f; | |
| 228 | + } | |
| 229 | + | |
| 230 | + /** | |
| 231 | + * @param ?string $value | |
| 232 | + * @throws Exception | |
| 233 | + * @return ?string | |
| 234 | + */ | |
| 235 | + public static function fromA(?string $value): ?string { | |
| 236 | + if (!is_null($value)) { | |
| 237 | + return $value; /*string*/ | |
| 238 | + } else { | |
| 239 | + return null; | |
| 240 | + } | |
| 241 | + } | |
| 242 | + | |
| 243 | + /** | |
| 244 | + * @throws Exception | |
| 245 | + * @return ?string | |
| 246 | + */ | |
| 247 | + public function toA(): ?string { | |
| 248 | + if (MyObject::validateA($this->a)) { | |
| 249 | + if (!is_null($this->a)) { | |
| 250 | + return $this->a; /*string*/ | |
| 251 | + } else { | |
| 252 | + return null; | |
| 253 | + } | |
| 254 | + } | |
| 255 | + throw new Exception('never get to this MyObject::a'); | |
| 256 | + } | |
| 257 | + | |
| 258 | + /** | |
| 259 | + * @param string|null | |
| 260 | + * @return bool | |
| 261 | + * @throws Exception | |
| 262 | + */ | |
| 263 | + public static function validateA(?string $value): bool { | |
| 264 | + if (!is_null($value)) { | |
| 265 | + } | |
| 266 | + return true; | |
| 267 | + } | |
| 268 | + | |
| 269 | + /** | |
| 270 | + * @throws Exception | |
| 271 | + * @return ?string | |
| 272 | + */ | |
| 273 | + public function getA(): ?string { | |
| 274 | + if (MyObject::validateA($this->a)) { | |
| 275 | + return $this->a; | |
| 276 | + } | |
| 277 | + throw new Exception('never get to getA MyObject::a'); | |
| 278 | + } | |
| 279 | + | |
| 280 | + /** | |
| 281 | + * @return ?string | |
| 282 | + */ | |
| 283 | + public static function sampleA(): ?string { | |
| 284 | + return 'MyObject::a::31'; /*31:a*/ | |
| 285 | + } | |
| 286 | + | |
| 287 | + /** | |
| 288 | + * @param ?float $value | |
| 289 | + * @throws Exception | |
| 290 | + * @return ?float | |
| 291 | + */ | |
| 292 | + public static function fromB(?float $value): ?float { | |
| 293 | + if (!is_null($value)) { | |
| 294 | + return $value; /*float*/ | |
| 295 | + } else { | |
| 296 | + return null; | |
| 297 | + } | |
| 298 | + } | |
| 299 | + | |
| 300 | + /** | |
| 301 | + * @throws Exception | |
| 302 | + * @return ?float | |
| 303 | + */ | |
| 304 | + public function toB(): ?float { | |
| 305 | + if (MyObject::validateB($this->b)) { | |
| 306 | + if (!is_null($this->b)) { | |
| 307 | + return $this->b; /*float*/ | |
| 308 | + } else { | |
| 309 | + return null; | |
| 310 | + } | |
| 311 | + } | |
| 312 | + throw new Exception('never get to this MyObject::b'); | |
| 313 | + } | |
| 314 | + | |
| 315 | + /** | |
| 316 | + * @param float|null | |
| 317 | + * @return bool | |
| 318 | + * @throws Exception | |
| 319 | + */ | |
| 320 | + public static function validateB(?float $value): bool { | |
| 321 | + if (!is_null($value)) { | |
| 322 | + } | |
| 323 | + return true; | |
| 324 | + } | |
| 325 | + | |
| 326 | + /** | |
| 327 | + * @throws Exception | |
| 328 | + * @return ?float | |
| 329 | + */ | |
| 330 | + public function getB(): ?float { | |
| 331 | + if (MyObject::validateB($this->b)) { | |
| 332 | + return $this->b; | |
| 333 | + } | |
| 334 | + throw new Exception('never get to getB MyObject::b'); | |
| 335 | + } | |
| 336 | + | |
| 337 | + /** | |
| 338 | + * @return ?float | |
| 339 | + */ | |
| 340 | + public static function sampleB(): ?float { | |
| 341 | + return 32.032; /*32:b*/ | |
| 342 | + } | |
| 343 | + | |
| 344 | + /** | |
| 345 | + * @param ?bool $value | |
| 346 | + * @throws Exception | |
| 347 | + * @return ?bool | |
| 348 | + */ | |
| 349 | + public static function fromC(?bool $value): ?bool { | |
| 350 | + if (!is_null($value)) { | |
| 351 | + return $value; /*bool*/ | |
| 352 | + } else { | |
| 353 | + return null; | |
| 354 | + } | |
| 355 | + } | |
| 356 | + | |
| 357 | + /** | |
| 358 | + * @throws Exception | |
| 359 | + * @return ?bool | |
| 360 | + */ | |
| 361 | + public function toC(): ?bool { | |
| 362 | + if (MyObject::validateC($this->c)) { | |
| 363 | + if (!is_null($this->c)) { | |
| 364 | + return $this->c; /*bool*/ | |
| 365 | + } else { | |
| 366 | + return null; | |
| 367 | + } | |
| 368 | + } | |
| 369 | + throw new Exception('never get to this MyObject::c'); | |
| 370 | + } | |
| 371 | + | |
| 372 | + /** | |
| 373 | + * @param bool|null | |
| 374 | + * @return bool | |
| 375 | + * @throws Exception | |
| 376 | + */ | |
| 377 | + public static function validateC(?bool $value): bool { | |
| 378 | + if (!is_null($value)) { | |
| 379 | + } | |
| 380 | + return true; | |
| 381 | + } | |
| 382 | + | |
| 383 | + /** | |
| 384 | + * @throws Exception | |
| 385 | + * @return ?bool | |
| 386 | + */ | |
| 387 | + public function getC(): ?bool { | |
| 388 | + if (MyObject::validateC($this->c)) { | |
| 389 | + return $this->c; | |
| 390 | + } | |
| 391 | + throw new Exception('never get to getC MyObject::c'); | |
| 392 | + } | |
| 393 | + | |
| 394 | + /** | |
| 395 | + * @return ?bool | |
| 396 | + */ | |
| 397 | + public static function sampleC(): ?bool { | |
| 398 | + return true; /*33:c*/ | |
| 399 | + } | |
| 400 | + | |
| 401 | + /** | |
| 402 | + * @param ?string $value | |
| 403 | + * @throws Exception | |
| 404 | + * @return ?string | |
| 405 | + */ | |
| 406 | + public static function fromD(?string $value): ?string { | |
| 407 | + if (!is_null($value)) { | |
| 408 | + return $value; /*string*/ | |
| 409 | + } else { | |
| 410 | + return null; | |
| 411 | + } | |
| 412 | + } | |
| 413 | + | |
| 414 | + /** | |
| 415 | + * @throws Exception | |
| 416 | + * @return ?string | |
| 417 | + */ | |
| 418 | + public function toD(): ?string { | |
| 419 | + if (MyObject::validateD($this->d)) { | |
| 420 | + if (!is_null($this->d)) { | |
| 421 | + return $this->d; /*string*/ | |
| 422 | + } else { | |
| 423 | + return null; | |
| 424 | + } | |
| 425 | + } | |
| 426 | + throw new Exception('never get to this MyObject::d'); | |
| 427 | + } | |
| 428 | + | |
| 429 | + /** | |
| 430 | + * @param string|null | |
| 431 | + * @return bool | |
| 432 | + * @throws Exception | |
| 433 | + */ | |
| 434 | + public static function validateD(?string $value): bool { | |
| 435 | + if (!is_null($value)) { | |
| 436 | + } | |
| 437 | + return true; | |
| 438 | + } | |
| 439 | + | |
| 440 | + /** | |
| 441 | + * @throws Exception | |
| 442 | + * @return ?string | |
| 443 | + */ | |
| 444 | + public function getD(): ?string { | |
| 445 | + if (MyObject::validateD($this->d)) { | |
| 446 | + return $this->d; | |
| 447 | + } | |
| 448 | + throw new Exception('never get to getD MyObject::d'); | |
| 449 | + } | |
| 450 | + | |
| 451 | + /** | |
| 452 | + * @return ?string | |
| 453 | + */ | |
| 454 | + public static function sampleD(): ?string { | |
| 455 | + return 'MyObject::d::34'; /*34:d*/ | |
| 456 | + } | |
| 457 | + | |
| 458 | + /** | |
| 459 | + * @param ?float $value | |
| 460 | + * @throws Exception | |
| 461 | + * @return ?float | |
| 462 | + */ | |
| 463 | + public static function fromE(?float $value): ?float { | |
| 464 | + if (!is_null($value)) { | |
| 465 | + return $value; /*float*/ | |
| 466 | + } else { | |
| 467 | + return null; | |
| 468 | + } | |
| 469 | + } | |
| 470 | + | |
| 471 | + /** | |
| 472 | + * @throws Exception | |
| 473 | + * @return ?float | |
| 474 | + */ | |
| 475 | + public function toE(): ?float { | |
| 476 | + if (MyObject::validateE($this->e)) { | |
| 477 | + if (!is_null($this->e)) { | |
| 478 | + return $this->e; /*float*/ | |
| 479 | + } else { | |
| 480 | + return null; | |
| 481 | + } | |
| 482 | + } | |
| 483 | + throw new Exception('never get to this MyObject::e'); | |
| 484 | + } | |
| 485 | + | |
| 486 | + /** | |
| 487 | + * @param float|null | |
| 488 | + * @return bool | |
| 489 | + * @throws Exception | |
| 490 | + */ | |
| 491 | + public static function validateE(?float $value): bool { | |
| 492 | + if (!is_null($value)) { | |
| 493 | + } | |
| 494 | + return true; | |
| 495 | + } | |
| 496 | + | |
| 497 | + /** | |
| 498 | + * @throws Exception | |
| 499 | + * @return ?float | |
| 500 | + */ | |
| 501 | + public function getE(): ?float { | |
| 502 | + if (MyObject::validateE($this->e)) { | |
| 503 | + return $this->e; | |
| 504 | + } | |
| 505 | + throw new Exception('never get to getE MyObject::e'); | |
| 506 | + } | |
| 507 | + | |
| 508 | + /** | |
| 509 | + * @return ?float | |
| 510 | + */ | |
| 511 | + public static function sampleE(): ?float { | |
| 512 | + return 35.035; /*35:e*/ | |
| 513 | + } | |
| 514 | + | |
| 515 | + /** | |
| 516 | + * @param ?bool $value | |
| 517 | + * @throws Exception | |
| 518 | + * @return ?bool | |
| 519 | + */ | |
| 520 | + public static function fromF(?bool $value): ?bool { | |
| 521 | + if (!is_null($value)) { | |
| 522 | + return $value; /*bool*/ | |
| 523 | + } else { | |
| 524 | + return null; | |
| 525 | + } | |
| 526 | + } | |
| 527 | + | |
| 528 | + /** | |
| 529 | + * @throws Exception | |
| 530 | + * @return ?bool | |
| 531 | + */ | |
| 532 | + public function toF(): ?bool { | |
| 533 | + if (MyObject::validateF($this->f)) { | |
| 534 | + if (!is_null($this->f)) { | |
| 535 | + return $this->f; /*bool*/ | |
| 536 | + } else { | |
| 537 | + return null; | |
| 538 | + } | |
| 539 | + } | |
| 540 | + throw new Exception('never get to this MyObject::f'); | |
| 541 | + } | |
| 542 | + | |
| 543 | + /** | |
| 544 | + * @param bool|null | |
| 545 | + * @return bool | |
| 546 | + * @throws Exception | |
| 547 | + */ | |
| 548 | + public static function validateF(?bool $value): bool { | |
| 549 | + if (!is_null($value)) { | |
| 550 | + } | |
| 551 | + return true; | |
| 552 | + } | |
| 553 | + | |
| 554 | + /** | |
| 555 | + * @throws Exception | |
| 556 | + * @return ?bool | |
| 557 | + */ | |
| 558 | + public function getF(): ?bool { | |
| 559 | + if (MyObject::validateF($this->f)) { | |
| 560 | + return $this->f; | |
| 561 | + } | |
| 562 | + throw new Exception('never get to getF MyObject::f'); | |
| 563 | + } | |
| 564 | + | |
| 565 | + /** | |
| 566 | + * @return ?bool | |
| 567 | + */ | |
| 568 | + public static function sampleF(): ?bool { | |
| 569 | + return true; /*36:f*/ | |
| 570 | + } | |
| 571 | + | |
| 572 | + /** | |
| 573 | + * @throws Exception | |
| 574 | + * @return bool | |
| 575 | + */ | |
| 576 | + public function validate(): bool { | |
| 577 | + return MyObject::validateA($this->a) | |
| 578 | + || MyObject::validateB($this->b) | |
| 579 | + || MyObject::validateC($this->c) | |
| 580 | + || MyObject::validateD($this->d) | |
| 581 | + || MyObject::validateE($this->e) | |
| 582 | + || MyObject::validateF($this->f); | |
| 583 | + } | |
| 584 | + | |
| 585 | + /** | |
| 586 | + * @return stdClass | |
| 587 | + * @throws Exception | |
| 588 | + */ | |
| 589 | + public function to(): stdClass { | |
| 590 | + $out = new stdClass(); | |
| 591 | + $out->{'a'} = $this->toA(); | |
| 592 | + $out->{'b'} = $this->toB(); | |
| 593 | + $out->{'c'} = $this->toC(); | |
| 594 | + $out->{'d'} = $this->toD(); | |
| 595 | + $out->{'e'} = $this->toE(); | |
| 596 | + $out->{'f'} = $this->toF(); | |
| 597 | + return $out; | |
| 598 | + } | |
| 599 | + | |
| 600 | + /** | |
| 601 | + * @param stdClass $obj | |
| 602 | + * @return MyObject | |
| 603 | + * @throws Exception | |
| 604 | + */ | |
| 605 | + public static function from(stdClass $obj): MyObject { | |
| 606 | + return new MyObject( | |
| 607 | + MyObject::fromA($obj->{'a'}) | |
| 608 | + ,MyObject::fromB($obj->{'b'}) | |
| 609 | + ,MyObject::fromC($obj->{'c'}) | |
| 610 | + ,MyObject::fromD($obj->{'d'}) | |
| 611 | + ,MyObject::fromE($obj->{'e'}) | |
| 612 | + ,MyObject::fromF($obj->{'f'}) | |
| 613 | + ); | |
| 614 | + } | |
| 615 | + | |
| 616 | + /** | |
| 617 | + * @return MyObject | |
| 618 | + */ | |
| 619 | + public static function sample(): MyObject { | |
| 620 | + return new MyObject( | |
| 621 | + MyObject::sampleA() | |
| 622 | + ,MyObject::sampleB() | |
| 623 | + ,MyObject::sampleC() | |
| 624 | + ,MyObject::sampleD() | |
| 625 | + ,MyObject::sampleE() | |
| 626 | + ,MyObject::sampleF() | |
| 627 | + ); | |
| 628 | + } | |
| 629 | +} | |
| 630 | + | |
| 631 | +// This is an autogenerated file:MyObjectA | |
| 632 | + | |
| 633 | +class MyObjectA { | |
| 634 | + private ?string $a; // json:a Optional | |
| 635 | + private ?float $b; // json:b Optional | |
| 636 | + private ?bool $c; // json:c Optional | |
| 637 | + | |
| 638 | + /** | |
| 639 | + * @param string|null $a | |
| 640 | + * @param float|null $b | |
| 641 | + * @param bool|null $c | |
| 642 | + */ | |
| 643 | + public function __construct(?string $a, ?float $b, ?bool $c) { | |
| 644 | + $this->a = $a; | |
| 645 | + $this->b = $b; | |
| 646 | + $this->c = $c; | |
| 647 | + } | |
| 648 | + | |
| 649 | + /** | |
| 650 | + * @param ?string $value | |
| 651 | + * @throws Exception | |
| 652 | + * @return ?string | |
| 653 | + */ | |
| 654 | + public static function fromA(?string $value): ?string { | |
| 655 | + if (!is_null($value)) { | |
| 656 | + return $value; /*string*/ | |
| 657 | + } else { | |
| 658 | + return null; | |
| 659 | + } | |
| 660 | + } | |
| 661 | + | |
| 662 | + /** | |
| 663 | + * @throws Exception | |
| 664 | + * @return ?string | |
| 665 | + */ | |
| 666 | + public function toA(): ?string { | |
| 667 | + if (MyObjectA::validateA($this->a)) { | |
| 668 | + if (!is_null($this->a)) { | |
| 669 | + return $this->a; /*string*/ | |
| 670 | + } else { | |
| 671 | + return null; | |
| 672 | + } | |
| 673 | + } | |
| 674 | + throw new Exception('never get to this MyObjectA::a'); | |
| 675 | + } | |
| 676 | + | |
| 677 | + /** | |
| 678 | + * @param string|null | |
| 679 | + * @return bool | |
| 680 | + * @throws Exception | |
| 681 | + */ | |
| 682 | + public static function validateA(?string $value): bool { | |
| 683 | + if (!is_null($value)) { | |
| 684 | + } | |
| 685 | + return true; | |
| 686 | + } | |
| 687 | + | |
| 688 | + /** | |
| 689 | + * @throws Exception | |
| 690 | + * @return ?string | |
| 691 | + */ | |
| 692 | + public function getA(): ?string { | |
| 693 | + if (MyObjectA::validateA($this->a)) { | |
| 694 | + return $this->a; | |
| 695 | + } | |
| 696 | + throw new Exception('never get to getA MyObjectA::a'); | |
| 697 | + } | |
| 698 | + | |
| 699 | + /** | |
| 700 | + * @return ?string | |
| 701 | + */ | |
| 702 | + public static function sampleA(): ?string { | |
| 703 | + return 'MyObjectA::a::31'; /*31:a*/ | |
| 704 | + } | |
| 705 | + | |
| 706 | + /** | |
| 707 | + * @param ?float $value | |
| 708 | + * @throws Exception | |
| 709 | + * @return ?float | |
| 710 | + */ | |
| 711 | + public static function fromB(?float $value): ?float { | |
| 712 | + if (!is_null($value)) { | |
| 713 | + return $value; /*float*/ | |
| 714 | + } else { | |
| 715 | + return null; | |
| 716 | + } | |
| 717 | + } | |
| 718 | + | |
| 719 | + /** | |
| 720 | + * @throws Exception | |
| 721 | + * @return ?float | |
| 722 | + */ | |
| 723 | + public function toB(): ?float { | |
| 724 | + if (MyObjectA::validateB($this->b)) { | |
| 725 | + if (!is_null($this->b)) { | |
| 726 | + return $this->b; /*float*/ | |
| 727 | + } else { | |
| 728 | + return null; | |
| 729 | + } | |
| 730 | + } | |
| 731 | + throw new Exception('never get to this MyObjectA::b'); | |
| 732 | + } | |
| 733 | + | |
| 734 | + /** | |
| 735 | + * @param float|null | |
| 736 | + * @return bool | |
| 737 | + * @throws Exception | |
| 738 | + */ | |
| 739 | + public static function validateB(?float $value): bool { | |
| 740 | + if (!is_null($value)) { | |
| 741 | + } | |
| 742 | + return true; | |
| 743 | + } | |
| 744 | + | |
| 745 | + /** | |
| 746 | + * @throws Exception | |
| 747 | + * @return ?float | |
| 748 | + */ | |
| 749 | + public function getB(): ?float { | |
| 750 | + if (MyObjectA::validateB($this->b)) { | |
| 751 | + return $this->b; | |
| 752 | + } | |
| 753 | + throw new Exception('never get to getB MyObjectA::b'); | |
| 754 | + } | |
| 755 | + | |
| 756 | + /** | |
| 757 | + * @return ?float | |
| 758 | + */ | |
| 759 | + public static function sampleB(): ?float { | |
| 760 | + return 32.032; /*32:b*/ | |
| 761 | + } | |
| 762 | + | |
| 763 | + /** | |
| 764 | + * @param ?bool $value | |
| 765 | + * @throws Exception | |
| 766 | + * @return ?bool | |
| 767 | + */ | |
| 768 | + public static function fromC(?bool $value): ?bool { | |
| 769 | + if (!is_null($value)) { | |
| 770 | + return $value; /*bool*/ | |
| 771 | + } else { | |
| 772 | + return null; | |
| 773 | + } | |
| 774 | + } | |
| 775 | + | |
| 776 | + /** | |
| 777 | + * @throws Exception | |
| 778 | + * @return ?bool | |
| 779 | + */ | |
| 780 | + public function toC(): ?bool { | |
| 781 | + if (MyObjectA::validateC($this->c)) { | |
| 782 | + if (!is_null($this->c)) { | |
| 783 | + return $this->c; /*bool*/ | |
| 784 | + } else { | |
| 785 | + return null; | |
| 786 | + } | |
| 787 | + } | |
| 788 | + throw new Exception('never get to this MyObjectA::c'); | |
| 789 | + } | |
| 790 | + | |
| 791 | + /** | |
| 792 | + * @param bool|null | |
| 793 | + * @return bool | |
| 794 | + * @throws Exception | |
| 795 | + */ | |
| 796 | + public static function validateC(?bool $value): bool { | |
| 797 | + if (!is_null($value)) { | |
| 798 | + } | |
| 799 | + return true; | |
| 800 | + } | |
| 801 | + | |
| 802 | + /** | |
| 803 | + * @throws Exception | |
| 804 | + * @return ?bool | |
| 805 | + */ | |
| 806 | + public function getC(): ?bool { | |
| 807 | + if (MyObjectA::validateC($this->c)) { | |
| 808 | + return $this->c; | |
| 809 | + } | |
| 810 | + throw new Exception('never get to getC MyObjectA::c'); | |
| 811 | + } | |
| 812 | + | |
| 813 | + /** | |
| 814 | + * @return ?bool | |
| 815 | + */ | |
| 816 | + public static function sampleC(): ?bool { | |
| 817 | + return true; /*33:c*/ | |
| 818 | + } | |
| 819 | + | |
| 820 | + /** | |
| 821 | + * @throws Exception | |
| 822 | + * @return bool | |
| 823 | + */ | |
| 824 | + public function validate(): bool { | |
| 825 | + return MyObjectA::validateA($this->a) | |
| 826 | + || MyObjectA::validateB($this->b) | |
| 827 | + || MyObjectA::validateC($this->c); | |
| 828 | + } | |
| 829 | + | |
| 830 | + /** | |
| 831 | + * @return stdClass | |
| 832 | + * @throws Exception | |
| 833 | + */ | |
| 834 | + public function to(): stdClass { | |
| 835 | + $out = new stdClass(); | |
| 836 | + $out->{'a'} = $this->toA(); | |
| 837 | + $out->{'b'} = $this->toB(); | |
| 838 | + $out->{'c'} = $this->toC(); | |
| 839 | + return $out; | |
| 840 | + } | |
| 841 | + | |
| 842 | + /** | |
| 843 | + * @param stdClass $obj | |
| 844 | + * @return MyObjectA | |
| 845 | + * @throws Exception | |
| 846 | + */ | |
| 847 | + public static function from(stdClass $obj): MyObjectA { | |
| 848 | + return new MyObjectA( | |
| 849 | + MyObjectA::fromA($obj->{'a'}) | |
| 850 | + ,MyObjectA::fromB($obj->{'b'}) | |
| 851 | + ,MyObjectA::fromC($obj->{'c'}) | |
| 852 | + ); | |
| 853 | + } | |
| 854 | + | |
| 855 | + /** | |
| 856 | + * @return MyObjectA | |
| 857 | + */ | |
| 858 | + public static function sample(): MyObjectA { | |
| 859 | + return new MyObjectA( | |
| 860 | + MyObjectA::sampleA() | |
| 861 | + ,MyObjectA::sampleB() | |
| 862 | + ,MyObjectA::sampleC() | |
| 863 | + ); | |
| 864 | + } | |
| 865 | +} | |
| 866 | + | |
| 867 | +// This is an autogenerated file:MyObjectB | |
| 868 | + | |
| 869 | +class MyObjectB { | |
| 870 | + private ?string $d; // json:d Optional | |
| 871 | + private ?float $e; // json:e Optional | |
| 872 | + private ?bool $f; // json:f Optional | |
| 873 | + | |
| 874 | + /** | |
| 875 | + * @param string|null $d | |
| 876 | + * @param float|null $e | |
| 877 | + * @param bool|null $f | |
| 878 | + */ | |
| 879 | + public function __construct(?string $d, ?float $e, ?bool $f) { | |
| 880 | + $this->d = $d; | |
| 881 | + $this->e = $e; | |
| 882 | + $this->f = $f; | |
| 883 | + } | |
| 884 | + | |
| 885 | + /** | |
| 886 | + * @param ?string $value | |
| 887 | + * @throws Exception | |
| 888 | + * @return ?string | |
| 889 | + */ | |
| 890 | + public static function fromD(?string $value): ?string { | |
| 891 | + if (!is_null($value)) { | |
| 892 | + return $value; /*string*/ | |
| 893 | + } else { | |
| 894 | + return null; | |
| 895 | + } | |
| 896 | + } | |
| 897 | + | |
| 898 | + /** | |
| 899 | + * @throws Exception | |
| 900 | + * @return ?string | |
| 901 | + */ | |
| 902 | + public function toD(): ?string { | |
| 903 | + if (MyObjectB::validateD($this->d)) { | |
| 904 | + if (!is_null($this->d)) { | |
| 905 | + return $this->d; /*string*/ | |
| 906 | + } else { | |
| 907 | + return null; | |
| 908 | + } | |
| 909 | + } | |
| 910 | + throw new Exception('never get to this MyObjectB::d'); | |
| 911 | + } | |
| 912 | + | |
| 913 | + /** | |
| 914 | + * @param string|null | |
| 915 | + * @return bool | |
| 916 | + * @throws Exception | |
| 917 | + */ | |
| 918 | + public static function validateD(?string $value): bool { | |
| 919 | + if (!is_null($value)) { | |
| 920 | + } | |
| 921 | + return true; | |
| 922 | + } | |
| 923 | + | |
| 924 | + /** | |
| 925 | + * @throws Exception | |
| 926 | + * @return ?string | |
| 927 | + */ | |
| 928 | + public function getD(): ?string { | |
| 929 | + if (MyObjectB::validateD($this->d)) { | |
| 930 | + return $this->d; | |
| 931 | + } | |
| 932 | + throw new Exception('never get to getD MyObjectB::d'); | |
| 933 | + } | |
| 934 | + | |
| 935 | + /** | |
| 936 | + * @return ?string | |
| 937 | + */ | |
| 938 | + public static function sampleD(): ?string { | |
| 939 | + return 'MyObjectB::d::31'; /*31:d*/ | |
| 940 | + } | |
| 941 | + | |
| 942 | + /** | |
| 943 | + * @param ?float $value | |
| 944 | + * @throws Exception | |
| 945 | + * @return ?float | |
| 946 | + */ | |
| 947 | + public static function fromE(?float $value): ?float { | |
| 948 | + if (!is_null($value)) { | |
| 949 | + return $value; /*float*/ | |
| 950 | + } else { | |
| 951 | + return null; | |
| 952 | + } | |
| 953 | + } | |
| 954 | + | |
| 955 | + /** | |
| 956 | + * @throws Exception | |
| 957 | + * @return ?float | |
| 958 | + */ | |
| 959 | + public function toE(): ?float { | |
| 960 | + if (MyObjectB::validateE($this->e)) { | |
| 961 | + if (!is_null($this->e)) { | |
| 962 | + return $this->e; /*float*/ | |
| 963 | + } else { | |
| 964 | + return null; | |
| 965 | + } | |
| 966 | + } | |
| 967 | + throw new Exception('never get to this MyObjectB::e'); | |
| 968 | + } | |
| 969 | + | |
| 970 | + /** | |
| 971 | + * @param float|null | |
| 972 | + * @return bool | |
| 973 | + * @throws Exception | |
| 974 | + */ | |
| 975 | + public static function validateE(?float $value): bool { | |
| 976 | + if (!is_null($value)) { | |
| 977 | + } | |
| 978 | + return true; | |
| 979 | + } | |
| 980 | + | |
| 981 | + /** | |
| 982 | + * @throws Exception | |
| 983 | + * @return ?float | |
| 984 | + */ | |
| 985 | + public function getE(): ?float { | |
| 986 | + if (MyObjectB::validateE($this->e)) { | |
| 987 | + return $this->e; | |
| 988 | + } | |
| 989 | + throw new Exception('never get to getE MyObjectB::e'); | |
| 990 | + } | |
| 991 | + | |
| 992 | + /** | |
| 993 | + * @return ?float | |
| 994 | + */ | |
| 995 | + public static function sampleE(): ?float { | |
| 996 | + return 32.032; /*32:e*/ | |
| 997 | + } | |
| 998 | + | |
| 999 | + /** | |
| 1000 | + * @param ?bool $value | |
| 1001 | + * @throws Exception | |
| 1002 | + * @return ?bool | |
| 1003 | + */ | |
| 1004 | + public static function fromF(?bool $value): ?bool { | |
| 1005 | + if (!is_null($value)) { | |
| 1006 | + return $value; /*bool*/ | |
| 1007 | + } else { | |
| 1008 | + return null; | |
| 1009 | + } | |
| 1010 | + } | |
| 1011 | + | |
| 1012 | + /** | |
| 1013 | + * @throws Exception | |
| 1014 | + * @return ?bool | |
| 1015 | + */ | |
| 1016 | + public function toF(): ?bool { | |
| 1017 | + if (MyObjectB::validateF($this->f)) { | |
| 1018 | + if (!is_null($this->f)) { | |
| 1019 | + return $this->f; /*bool*/ | |
| 1020 | + } else { | |
| 1021 | + return null; | |
| 1022 | + } | |
| 1023 | + } | |
| 1024 | + throw new Exception('never get to this MyObjectB::f'); | |
| 1025 | + } | |
| 1026 | + | |
| 1027 | + /** | |
| 1028 | + * @param bool|null | |
| 1029 | + * @return bool | |
| 1030 | + * @throws Exception | |
| 1031 | + */ | |
| 1032 | + public static function validateF(?bool $value): bool { | |
| 1033 | + if (!is_null($value)) { | |
| 1034 | + } | |
| 1035 | + return true; | |
| 1036 | + } | |
| 1037 | + | |
| 1038 | + /** | |
| 1039 | + * @throws Exception | |
| 1040 | + * @return ?bool | |
| 1041 | + */ | |
| 1042 | + public function getF(): ?bool { | |
| 1043 | + if (MyObjectB::validateF($this->f)) { | |
| 1044 | + return $this->f; | |
| 1045 | + } | |
| 1046 | + throw new Exception('never get to getF MyObjectB::f'); | |
| 1047 | + } | |
| 1048 | + | |
| 1049 | + /** | |
| 1050 | + * @return ?bool | |
| 1051 | + */ | |
| 1052 | + public static function sampleF(): ?bool { | |
| 1053 | + return true; /*33:f*/ | |
| 1054 | + } | |
| 1055 | + | |
| 1056 | + /** | |
| 1057 | + * @throws Exception | |
| 1058 | + * @return bool | |
| 1059 | + */ | |
| 1060 | + public function validate(): bool { | |
| 1061 | + return MyObjectB::validateD($this->d) | |
| 1062 | + || MyObjectB::validateE($this->e) | |
| 1063 | + || MyObjectB::validateF($this->f); | |
| 1064 | + } | |
| 1065 | + | |
| 1066 | + /** | |
| 1067 | + * @return stdClass | |
| 1068 | + * @throws Exception | |
| 1069 | + */ | |
| 1070 | + public function to(): stdClass { | |
| 1071 | + $out = new stdClass(); | |
| 1072 | + $out->{'d'} = $this->toD(); | |
| 1073 | + $out->{'e'} = $this->toE(); | |
| 1074 | + $out->{'f'} = $this->toF(); | |
| 1075 | + return $out; | |
| 1076 | + } | |
| 1077 | + | |
| 1078 | + /** | |
| 1079 | + * @param stdClass $obj | |
| 1080 | + * @return MyObjectB | |
| 1081 | + * @throws Exception | |
| 1082 | + */ | |
| 1083 | + public static function from(stdClass $obj): MyObjectB { | |
| 1084 | + return new MyObjectB( | |
| 1085 | + MyObjectB::fromD($obj->{'d'}) | |
| 1086 | + ,MyObjectB::fromE($obj->{'e'}) | |
| 1087 | + ,MyObjectB::fromF($obj->{'f'}) | |
| 1088 | + ); | |
| 1089 | + } | |
| 1090 | + | |
| 1091 | + /** | |
| 1092 | + * @return MyObjectB | |
| 1093 | + */ | |
| 1094 | + public static function sample(): MyObjectB { | |
| 1095 | + return new MyObjectB( | |
| 1096 | + MyObjectB::sampleD() | |
| 1097 | + ,MyObjectB::sampleE() | |
| 1098 | + ,MyObjectB::sampleF() | |
| 1099 | + ); | |
| 1100 | + } | |
| 1101 | +} |
Aschema-pike/test/inputs/schema/anyof-object-union.schema/default/TopLevel.pmod+129 −0
| @@ -0,0 +1,129 @@ | ||
| 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 | + MyObject|mixed first_property; // json: "firstProperty" | |
| 17 | + SecondProperty second_property; // json: "secondProperty" | |
| 18 | + | |
| 19 | + string encode_json() { | |
| 20 | + mapping(string:mixed) json = ([ | |
| 21 | + "firstProperty" : first_property, | |
| 22 | + "secondProperty" : second_property, | |
| 23 | + ]); | |
| 24 | + | |
| 25 | + return Standards.JSON.encode(json); | |
| 26 | + } | |
| 27 | +} | |
| 28 | + | |
| 29 | +TopLevel TopLevel_from_JSON(mixed json) { | |
| 30 | + TopLevel retval = TopLevel(); | |
| 31 | + | |
| 32 | + retval.first_property = json["firstProperty"]; | |
| 33 | + retval.second_property = json["secondProperty"]; | |
| 34 | + | |
| 35 | + return retval; | |
| 36 | +} | |
| 37 | + | |
| 38 | +class MyObject { | |
| 39 | + mixed|string a; // json: "a" | |
| 40 | + float|mixed b; // json: "b" | |
| 41 | + bool|mixed c; // json: "c" | |
| 42 | + mixed|string d; // json: "d" | |
| 43 | + float|mixed e; // json: "e" | |
| 44 | + bool|mixed f; // json: "f" | |
| 45 | + | |
| 46 | + string encode_json() { | |
| 47 | + mapping(string:mixed) json = ([ | |
| 48 | + "a" : a, | |
| 49 | + "b" : b, | |
| 50 | + "c" : c, | |
| 51 | + "d" : d, | |
| 52 | + "e" : e, | |
| 53 | + "f" : f, | |
| 54 | + ]); | |
| 55 | + | |
| 56 | + return Standards.JSON.encode(json); | |
| 57 | + } | |
| 58 | +} | |
| 59 | + | |
| 60 | +MyObject MyObject_from_JSON(mixed json) { | |
| 61 | + MyObject retval = MyObject(); | |
| 62 | + | |
| 63 | + retval.a = json["a"]; | |
| 64 | + retval.b = json["b"]; | |
| 65 | + retval.c = json["c"]; | |
| 66 | + retval.d = json["d"]; | |
| 67 | + retval.e = json["e"]; | |
| 68 | + retval.f = json["f"]; | |
| 69 | + | |
| 70 | + return retval; | |
| 71 | +} | |
| 72 | + | |
| 73 | +typedef array(MyObjectA)|MyObjectB SecondProperty; | |
| 74 | + | |
| 75 | +SecondProperty SecondProperty_from_JSON(mixed json) { | |
| 76 | + return json; | |
| 77 | +} | |
| 78 | + | |
| 79 | +class MyObjectA { | |
| 80 | + mixed|string a; // json: "a" | |
| 81 | + float|mixed b; // json: "b" | |
| 82 | + bool|mixed c; // json: "c" | |
| 83 | + | |
| 84 | + string encode_json() { | |
| 85 | + mapping(string:mixed) json = ([ | |
| 86 | + "a" : a, | |
| 87 | + "b" : b, | |
| 88 | + "c" : c, | |
| 89 | + ]); | |
| 90 | + | |
| 91 | + return Standards.JSON.encode(json); | |
| 92 | + } | |
| 93 | +} | |
| 94 | + | |
| 95 | +MyObjectA MyObjectA_from_JSON(mixed json) { | |
| 96 | + MyObjectA retval = MyObjectA(); | |
| 97 | + | |
| 98 | + retval.a = json["a"]; | |
| 99 | + retval.b = json["b"]; | |
| 100 | + retval.c = json["c"]; | |
| 101 | + | |
| 102 | + return retval; | |
| 103 | +} | |
| 104 | + | |
| 105 | +class MyObjectB { | |
| 106 | + mixed|string d; // json: "d" | |
| 107 | + float|mixed e; // json: "e" | |
| 108 | + bool|mixed f; // json: "f" | |
| 109 | + | |
| 110 | + string encode_json() { | |
| 111 | + mapping(string:mixed) json = ([ | |
| 112 | + "d" : d, | |
| 113 | + "e" : e, | |
| 114 | + "f" : f, | |
| 115 | + ]); | |
| 116 | + | |
| 117 | + return Standards.JSON.encode(json); | |
| 118 | + } | |
| 119 | +} | |
| 120 | + | |
| 121 | +MyObjectB MyObjectB_from_JSON(mixed json) { | |
| 122 | + MyObjectB retval = MyObjectB(); | |
| 123 | + | |
| 124 | + retval.d = json["d"]; | |
| 125 | + retval.e = json["e"]; | |
| 126 | + retval.f = json["f"]; | |
| 127 | + | |
| 128 | + return retval; | |
| 129 | +} |
Aschema-python/test/inputs/schema/anyof-object-union.schema/default/quicktype.py+165 −0
| @@ -0,0 +1,165 @@ | ||
| 1 | +from dataclasses import dataclass | |
| 2 | +from typing import Any, TypeVar, Callable, Type, cast | |
| 3 | + | |
| 4 | + | |
| 5 | +T = TypeVar("T") | |
| 6 | + | |
| 7 | + | |
| 8 | +def from_str(x: Any) -> str: | |
| 9 | + assert isinstance(x, str) | |
| 10 | + return x | |
| 11 | + | |
| 12 | + | |
| 13 | +def from_none(x: Any) -> Any: | |
| 14 | + assert x is None | |
| 15 | + return x | |
| 16 | + | |
| 17 | + | |
| 18 | +def from_union(fs, x): | |
| 19 | + for f in fs: | |
| 20 | + try: | |
| 21 | + return f(x) | |
| 22 | + except: | |
| 23 | + pass | |
| 24 | + assert False | |
| 25 | + | |
| 26 | + | |
| 27 | +def from_float(x: Any) -> float: | |
| 28 | + assert isinstance(x, (float, int)) and not isinstance(x, bool) | |
| 29 | + return float(x) | |
| 30 | + | |
| 31 | + | |
| 32 | +def from_bool(x: Any) -> bool: | |
| 33 | + assert isinstance(x, bool) | |
| 34 | + return x | |
| 35 | + | |
| 36 | + | |
| 37 | +def to_float(x: Any) -> float: | |
| 38 | + assert isinstance(x, (int, float)) | |
| 39 | + return x | |
| 40 | + | |
| 41 | + | |
| 42 | +def from_list(f: Callable[[Any], T], x: Any) -> list[T]: | |
| 43 | + assert isinstance(x, list) | |
| 44 | + return [f(y) for y in x] | |
| 45 | + | |
| 46 | + | |
| 47 | +def to_class(c: Type[T], x: Any) -> dict: | |
| 48 | + assert isinstance(x, c) | |
| 49 | + return cast(Any, x).to_dict() | |
| 50 | + | |
| 51 | + | |
| 52 | +@dataclass | |
| 53 | +class MyObject: | |
| 54 | + a: str | None = None | |
| 55 | + b: float | None = None | |
| 56 | + c: bool | None = None | |
| 57 | + d: str | None = None | |
| 58 | + e: float | None = None | |
| 59 | + f: bool | None = None | |
| 60 | + | |
| 61 | + @staticmethod | |
| 62 | + def from_dict(obj: Any) -> 'MyObject': | |
| 63 | + assert isinstance(obj, dict) | |
| 64 | + a = from_union([from_str, from_none], obj.get("a")) | |
| 65 | + b = from_union([from_float, from_none], obj.get("b")) | |
| 66 | + c = from_union([from_bool, from_none], obj.get("c")) | |
| 67 | + d = from_union([from_str, from_none], obj.get("d")) | |
| 68 | + e = from_union([from_float, from_none], obj.get("e")) | |
| 69 | + f = from_union([from_bool, from_none], obj.get("f")) | |
| 70 | + return MyObject(a, b, c, d, e, f) | |
| 71 | + | |
| 72 | + def to_dict(self) -> dict: | |
| 73 | + result: dict = {} | |
| 74 | + if self.a is not None: | |
| 75 | + result["a"] = from_union([from_str, from_none], self.a) | |
| 76 | + if self.b is not None: | |
| 77 | + result["b"] = from_union([to_float, from_none], self.b) | |
| 78 | + if self.c is not None: | |
| 79 | + result["c"] = from_union([from_bool, from_none], self.c) | |
| 80 | + if self.d is not None: | |
| 81 | + result["d"] = from_union([from_str, from_none], self.d) | |
| 82 | + if self.e is not None: | |
| 83 | + result["e"] = from_union([to_float, from_none], self.e) | |
| 84 | + if self.f is not None: | |
| 85 | + result["f"] = from_union([from_bool, from_none], self.f) | |
| 86 | + return result | |
| 87 | + | |
| 88 | + | |
| 89 | +@dataclass | |
| 90 | +class MyObjectA: | |
| 91 | + a: str | None = None | |
| 92 | + b: float | None = None | |
| 93 | + c: bool | None = None | |
| 94 | + | |
| 95 | + @staticmethod | |
| 96 | + def from_dict(obj: Any) -> 'MyObjectA': | |
| 97 | + assert isinstance(obj, dict) | |
| 98 | + a = from_union([from_str, from_none], obj.get("a")) | |
| 99 | + b = from_union([from_float, from_none], obj.get("b")) | |
| 100 | + c = from_union([from_bool, from_none], obj.get("c")) | |
| 101 | + return MyObjectA(a, b, c) | |
| 102 | + | |
| 103 | + def to_dict(self) -> dict: | |
| 104 | + result: dict = {} | |
| 105 | + if self.a is not None: | |
| 106 | + result["a"] = from_union([from_str, from_none], self.a) | |
| 107 | + if self.b is not None: | |
| 108 | + result["b"] = from_union([to_float, from_none], self.b) | |
| 109 | + if self.c is not None: | |
| 110 | + result["c"] = from_union([from_bool, from_none], self.c) | |
| 111 | + return result | |
| 112 | + | |
| 113 | + | |
| 114 | +@dataclass | |
| 115 | +class MyObjectB: | |
| 116 | + d: str | None = None | |
| 117 | + e: float | None = None | |
| 118 | + f: bool | None = None | |
| 119 | + | |
| 120 | + @staticmethod | |
| 121 | + def from_dict(obj: Any) -> 'MyObjectB': | |
| 122 | + assert isinstance(obj, dict) | |
| 123 | + d = from_union([from_str, from_none], obj.get("d")) | |
| 124 | + e = from_union([from_float, from_none], obj.get("e")) | |
| 125 | + f = from_union([from_bool, from_none], obj.get("f")) | |
| 126 | + return MyObjectB(d, e, f) | |
| 127 | + | |
| 128 | + def to_dict(self) -> dict: | |
| 129 | + result: dict = {} | |
| 130 | + if self.d is not None: | |
| 131 | + result["d"] = from_union([from_str, from_none], self.d) | |
| 132 | + if self.e is not None: | |
| 133 | + result["e"] = from_union([to_float, from_none], self.e) | |
| 134 | + if self.f is not None: | |
| 135 | + result["f"] = from_union([from_bool, from_none], self.f) | |
| 136 | + return result | |
| 137 | + | |
| 138 | + | |
| 139 | +@dataclass | |
| 140 | +class TopLevel: | |
| 141 | + first_property: MyObject | None = None | |
| 142 | + second_property: list[MyObjectA] | MyObjectB | None = None | |
| 143 | + | |
| 144 | + @staticmethod | |
| 145 | + def from_dict(obj: Any) -> 'TopLevel': | |
| 146 | + assert isinstance(obj, dict) | |
| 147 | + first_property = from_union([MyObject.from_dict, from_none], obj.get("firstProperty")) | |
| 148 | + second_property = from_union([lambda x: from_list(MyObjectA.from_dict, x), MyObjectB.from_dict, from_none], obj.get("secondProperty")) | |
| 149 | + return TopLevel(first_property, second_property) | |
| 150 | + | |
| 151 | + def to_dict(self) -> dict: | |
| 152 | + result: dict = {} | |
| 153 | + if self.first_property is not None: | |
| 154 | + result["firstProperty"] = from_union([lambda x: to_class(MyObject, x), from_none], self.first_property) | |
| 155 | + if self.second_property is not None: | |
| 156 | + result["secondProperty"] = from_union([lambda x: from_list(lambda x: to_class(MyObjectA, x), x), lambda x: to_class(MyObjectB, x), from_none], self.second_property) | |
| 157 | + return result | |
| 158 | + | |
| 159 | + | |
| 160 | +def top_level_from_dict(s: Any) -> TopLevel: | |
| 161 | + return TopLevel.from_dict(s) | |
| 162 | + | |
| 163 | + | |
| 164 | +def top_level_to_dict(x: TopLevel) -> Any: | |
| 165 | + return to_class(TopLevel, x) |
Aschema-ruby/test/inputs/schema/anyof-object-union.schema/default/TopLevel.rb+191 −0
| @@ -0,0 +1,191 @@ | ||
| 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.first_property&.a | |
| 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 | + Bool = Strict::Bool | |
| 19 | + Hash = Strict::Hash | |
| 20 | + String = Strict::String | |
| 21 | + Double = Strict::Float | Strict::Integer | |
| 22 | +end | |
| 23 | + | |
| 24 | +class MyObject < Dry::Struct | |
| 25 | + attribute :a, Types::String.optional | |
| 26 | + attribute :b, Types::Double.optional | |
| 27 | + attribute :c, Types::Bool.optional | |
| 28 | + attribute :d, Types::String.optional | |
| 29 | + attribute :e, Types::Double.optional | |
| 30 | + attribute :f, Types::Bool.optional | |
| 31 | + | |
| 32 | + def self.from_dynamic!(d) | |
| 33 | + d = Types::Hash[d] | |
| 34 | + new( | |
| 35 | + a: d["a"], | |
| 36 | + b: d["b"], | |
| 37 | + c: d["c"], | |
| 38 | + d: d["d"], | |
| 39 | + e: d["e"], | |
| 40 | + f: d["f"], | |
| 41 | + ) | |
| 42 | + end | |
| 43 | + | |
| 44 | + def self.from_json!(json) | |
| 45 | + from_dynamic!(JSON.parse(json)) | |
| 46 | + end | |
| 47 | + | |
| 48 | + def to_dynamic | |
| 49 | + { | |
| 50 | + "a" => a, | |
| 51 | + "b" => b, | |
| 52 | + "c" => c, | |
| 53 | + "d" => d, | |
| 54 | + "e" => e, | |
| 55 | + "f" => f, | |
| 56 | + } | |
| 57 | + end | |
| 58 | + | |
| 59 | + def to_json(options = nil) | |
| 60 | + JSON.generate(to_dynamic, options) | |
| 61 | + end | |
| 62 | +end | |
| 63 | + | |
| 64 | +class MyObjectA < Dry::Struct | |
| 65 | + attribute :a, Types::String.optional | |
| 66 | + attribute :b, Types::Double.optional | |
| 67 | + attribute :c, Types::Bool.optional | |
| 68 | + | |
| 69 | + def self.from_dynamic!(d) | |
| 70 | + d = Types::Hash[d] | |
| 71 | + new( | |
| 72 | + a: d["a"], | |
| 73 | + b: d["b"], | |
| 74 | + c: d["c"], | |
| 75 | + ) | |
| 76 | + end | |
| 77 | + | |
| 78 | + def self.from_json!(json) | |
| 79 | + from_dynamic!(JSON.parse(json)) | |
| 80 | + end | |
| 81 | + | |
| 82 | + def to_dynamic | |
| 83 | + { | |
| 84 | + "a" => a, | |
| 85 | + "b" => b, | |
| 86 | + "c" => c, | |
| 87 | + } | |
| 88 | + end | |
| 89 | + | |
| 90 | + def to_json(options = nil) | |
| 91 | + JSON.generate(to_dynamic, options) | |
| 92 | + end | |
| 93 | +end | |
| 94 | + | |
| 95 | +class MyObjectB < Dry::Struct | |
| 96 | + attribute :d, Types::String.optional | |
| 97 | + attribute :e, Types::Double.optional | |
| 98 | + attribute :f, Types::Bool.optional | |
| 99 | + | |
| 100 | + def self.from_dynamic!(d) | |
| 101 | + d = Types::Hash[d] | |
| 102 | + new( | |
| 103 | + d: d["d"], | |
| 104 | + e: d["e"], | |
| 105 | + f: d["f"], | |
| 106 | + ) | |
| 107 | + end | |
| 108 | + | |
| 109 | + def self.from_json!(json) | |
| 110 | + from_dynamic!(JSON.parse(json)) | |
| 111 | + end | |
| 112 | + | |
| 113 | + def to_dynamic | |
| 114 | + { | |
| 115 | + "d" => d, | |
| 116 | + "e" => e, | |
| 117 | + "f" => f, | |
| 118 | + } | |
| 119 | + end | |
| 120 | + | |
| 121 | + def to_json(options = nil) | |
| 122 | + JSON.generate(to_dynamic, options) | |
| 123 | + end | |
| 124 | +end | |
| 125 | + | |
| 126 | +class SecondProperty < Dry::Struct | |
| 127 | + attribute :my_object_a_array, Types.Array(MyObjectA).optional | |
| 128 | + attribute :my_object_b, MyObjectB.optional | |
| 129 | + | |
| 130 | + def self.from_dynamic!(d) | |
| 131 | + begin | |
| 132 | + value = d.map { |x| MyObjectA.from_dynamic!(x) } | |
| 133 | + if schema[:my_object_a_array].right.valid? value | |
| 134 | + return new(my_object_a_array: value, my_object_b: nil) | |
| 135 | + end | |
| 136 | + rescue | |
| 137 | + end | |
| 138 | + begin | |
| 139 | + value = MyObjectB.from_dynamic!(d) | |
| 140 | + if schema[:my_object_b].right.valid? value | |
| 141 | + return new(my_object_b: value, my_object_a_array: nil) | |
| 142 | + end | |
| 143 | + rescue | |
| 144 | + end | |
| 145 | + raise "Invalid union" | |
| 146 | + end | |
| 147 | + | |
| 148 | + def self.from_json!(json) | |
| 149 | + from_dynamic!(JSON.parse(json)) | |
| 150 | + end | |
| 151 | + | |
| 152 | + def to_dynamic | |
| 153 | + if my_object_a_array != nil | |
| 154 | + my_object_a_array.map { |x| x.to_dynamic } | |
| 155 | + elsif my_object_b != nil | |
| 156 | + my_object_b.to_dynamic | |
| 157 | + end | |
| 158 | + end | |
| 159 | + | |
| 160 | + def to_json(options = nil) | |
| 161 | + JSON.generate(to_dynamic, options) | |
| 162 | + end | |
| 163 | +end | |
| 164 | + | |
| 165 | +class TopLevel < Dry::Struct | |
| 166 | + attribute :first_property, MyObject.optional | |
| 167 | + attribute :second_property, Types.Instance(SecondProperty).optional | |
| 168 | + | |
| 169 | + def self.from_dynamic!(d) | |
| 170 | + d = Types::Hash[d] | |
| 171 | + new( | |
| 172 | + first_property: d["firstProperty"] ? MyObject.from_dynamic!(d["firstProperty"]) : nil, | |
| 173 | + second_property: d["secondProperty"] ? SecondProperty.from_dynamic!(d["secondProperty"]) : nil, | |
| 174 | + ) | |
| 175 | + end | |
| 176 | + | |
| 177 | + def self.from_json!(json) | |
| 178 | + from_dynamic!(JSON.parse(json)) | |
| 179 | + end | |
| 180 | + | |
| 181 | + def to_dynamic | |
| 182 | + { | |
| 183 | + "firstProperty" => first_property&.to_dynamic, | |
| 184 | + "secondProperty" => second_property&.to_dynamic, | |
| 185 | + } | |
| 186 | + end | |
| 187 | + | |
| 188 | + def to_json(options = nil) | |
| 189 | + JSON.generate(to_dynamic, options) | |
| 190 | + end | |
| 191 | +end |
Aschema-rust/test/inputs/schema/anyof-object-union.schema/default/module_under_test.rs+63 −0
| @@ -0,0 +1,63 @@ | ||
| 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 first_property: Option<MyObject>, | |
| 20 | + | |
| 21 | + pub second_property: Option<SecondProperty>, | |
| 22 | +} | |
| 23 | + | |
| 24 | +#[derive(Debug, Clone, Serialize, Deserialize)] | |
| 25 | +pub struct MyObject { | |
| 26 | + pub a: Option<String>, | |
| 27 | + | |
| 28 | + pub b: Option<f64>, | |
| 29 | + | |
| 30 | + pub c: Option<bool>, | |
| 31 | + | |
| 32 | + pub d: Option<String>, | |
| 33 | + | |
| 34 | + pub e: Option<f64>, | |
| 35 | + | |
| 36 | + pub f: Option<bool>, | |
| 37 | +} | |
| 38 | + | |
| 39 | +#[derive(Debug, Clone, Serialize, Deserialize)] | |
| 40 | +#[serde(untagged)] | |
| 41 | +pub enum SecondProperty { | |
| 42 | + MyObjectAArray(Vec<MyObjectA>), | |
| 43 | + | |
| 44 | + MyObjectB(MyObjectB), | |
| 45 | +} | |
| 46 | + | |
| 47 | +#[derive(Debug, Clone, Serialize, Deserialize)] | |
| 48 | +pub struct MyObjectA { | |
| 49 | + pub a: Option<String>, | |
| 50 | + | |
| 51 | + pub b: Option<f64>, | |
| 52 | + | |
| 53 | + pub c: Option<bool>, | |
| 54 | +} | |
| 55 | + | |
| 56 | +#[derive(Debug, Clone, Serialize, Deserialize)] | |
| 57 | +pub struct MyObjectB { | |
| 58 | + pub d: Option<String>, | |
| 59 | + | |
| 60 | + pub e: Option<f64>, | |
| 61 | + | |
| 62 | + pub f: Option<bool>, | |
| 63 | +} |
Aschema-scala3-upickle/test/inputs/schema/anyof-object-union.schema/default/TopLevel.scala+47 −0
| @@ -0,0 +1,47 @@ | ||
| 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 firstProperty : Option[MyObject] = None, | |
| 12 | + val secondProperty : Option[SecondProperty] = None | |
| 13 | +) derives Encoder.AsObject, Decoder | |
| 14 | + | |
| 15 | +case class MyObject ( | |
| 16 | + val a : Option[String] = None, | |
| 17 | + val b : Option[Double] = None, | |
| 18 | + val c : Option[Boolean] = None, | |
| 19 | + val d : Option[String] = None, | |
| 20 | + val e : Option[Double] = None, | |
| 21 | + val f : Option[Boolean] = None | |
| 22 | +) derives Encoder.AsObject, Decoder | |
| 23 | + | |
| 24 | +type SecondProperty = Seq[MyObjectA] | MyObjectB | |
| 25 | +given Decoder[SecondProperty] = { | |
| 26 | + List[Decoder[SecondProperty]]( | |
| 27 | + Decoder[Seq[MyObjectA]].widen, | |
| 28 | + Decoder[MyObjectB].widen, | |
| 29 | + ).reduceLeft(_ or _) | |
| 30 | +} | |
| 31 | + | |
| 32 | +given Encoder[SecondProperty] = Encoder.instance { | |
| 33 | + case enc0 : Seq[MyObjectA] => Encoder.encodeSeq[MyObjectA].apply(enc0) | |
| 34 | + case enc1 : MyObjectB => Encoder.AsObject[MyObjectB].apply(enc1) | |
| 35 | +} | |
| 36 | + | |
| 37 | +case class MyObjectA ( | |
| 38 | + val a : Option[String] = None, | |
| 39 | + val b : Option[Double] = None, | |
| 40 | + val c : Option[Boolean] = None | |
| 41 | +) derives Encoder.AsObject, Decoder | |
| 42 | + | |
| 43 | +case class MyObjectB ( | |
| 44 | + val d : Option[String] = None, | |
| 45 | + val e : Option[Double] = None, | |
| 46 | + val f : Option[Boolean] = None | |
| 47 | +) derives Encoder.AsObject, Decoder |
Aschema-scala3/test/inputs/schema/anyof-object-union.schema/default/TopLevel.scala+104 −0
| @@ -0,0 +1,104 @@ | ||
| 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 | + | |
| 29 | +object JsonExt: | |
| 30 | + val valueReader = OptionPickler.readwriter[ujson.Value] | |
| 31 | + | |
| 32 | + // upickle's built-in primitive readers are lenient -- the numeric and | |
| 33 | + // boolean readers accept strings, and the string reader accepts | |
| 34 | + // numbers and booleans -- so untagged unions need strict readers to | |
| 35 | + // pick the right member. | |
| 36 | + val strictString: OptionPickler.Reader[String] = valueReader.map { | |
| 37 | + case ujson.Str(s) => s | |
| 38 | + case json => throw new upickle.core.Abort("expected string, got " + json) | |
| 39 | + } | |
| 40 | + val strictLong: OptionPickler.Reader[Long] = valueReader.map { | |
| 41 | + case ujson.Num(n) if n.isWhole => n.toLong | |
| 42 | + case json => throw new upickle.core.Abort("expected integer, got " + json) | |
| 43 | + } | |
| 44 | + val strictDouble: OptionPickler.Reader[Double] = valueReader.map { | |
| 45 | + case ujson.Num(n) => n | |
| 46 | + case json => throw new upickle.core.Abort("expected number, got " + json) | |
| 47 | + } | |
| 48 | + val strictBoolean: OptionPickler.Reader[Boolean] = valueReader.map { | |
| 49 | + case ujson.Bool(b) => b | |
| 50 | + case json => throw new upickle.core.Abort("expected boolean, got " + json) | |
| 51 | + } | |
| 52 | + | |
| 53 | + def badMerge[T](r1: => OptionPickler.Reader[?], rest: OptionPickler.Reader[?]*): OptionPickler.Reader[T] = valueReader.map { json => | |
| 54 | + var t: T | Null = null | |
| 55 | + val stack = Vector.newBuilder[Throwable] | |
| 56 | + (r1 +: rest).foreach { reader => | |
| 57 | + if t == null then | |
| 58 | + try | |
| 59 | + t = OptionPickler.read[T](json, trace = true)(using reader.asInstanceOf[OptionPickler.Reader[T]]) | |
| 60 | + catch | |
| 61 | + case exc => stack += exc | |
| 62 | + } | |
| 63 | + if t != null then t.nn else throw new Exception(json.toString(), stack.result().headOption.getOrElse(null)) | |
| 64 | + } | |
| 65 | +end JsonExt | |
| 66 | + | |
| 67 | + | |
| 68 | +case class TopLevel ( | |
| 69 | + val firstProperty : Option[MyObject] = None, | |
| 70 | + val secondProperty : Option[SecondProperty] = None | |
| 71 | +) derives OptionPickler.ReadWriter | |
| 72 | + | |
| 73 | +case class MyObject ( | |
| 74 | + val a : Option[String] = None, | |
| 75 | + val b : Option[Double] = None, | |
| 76 | + val c : Option[Boolean] = None, | |
| 77 | + val d : Option[String] = None, | |
| 78 | + val e : Option[Double] = None, | |
| 79 | + val f : Option[Boolean] = None | |
| 80 | +) derives OptionPickler.ReadWriter | |
| 81 | + | |
| 82 | +type SecondProperty = Seq[MyObjectA] | MyObjectB | |
| 83 | +given unionReaderSecondProperty: OptionPickler.Reader[SecondProperty] = JsonExt.badMerge[SecondProperty]( | |
| 84 | + summon[OptionPickler.Reader[Seq[MyObjectA]]], | |
| 85 | + summon[OptionPickler.Reader[MyObjectB]], | |
| 86 | + ) | |
| 87 | + | |
| 88 | +given unionWriterSecondProperty: OptionPickler.Writer[SecondProperty] = OptionPickler.writer[ujson.Value].comap[SecondProperty]{ _v => | |
| 89 | + (_v: @unchecked) match | |
| 90 | + case v: Seq[MyObjectA] => OptionPickler.writeJs[Seq[MyObjectA]](v) | |
| 91 | + case v: MyObjectB => OptionPickler.writeJs[MyObjectB](v) | |
| 92 | +} | |
| 93 | + | |
| 94 | +case class MyObjectA ( | |
| 95 | + val a : Option[String] = None, | |
| 96 | + val b : Option[Double] = None, | |
| 97 | + val c : Option[Boolean] = None | |
| 98 | +) derives OptionPickler.ReadWriter | |
| 99 | + | |
| 100 | +case class MyObjectB ( | |
| 101 | + val d : Option[String] = None, | |
| 102 | + val e : Option[Double] = None, | |
| 103 | + val f : Option[Boolean] = None | |
| 104 | +) derives OptionPickler.ReadWriter |
Aschema-schema/test/inputs/schema/anyof-object-union.schema/default/TopLevel.schema+94 −0
| @@ -0,0 +1,94 @@ | ||
| 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 | + "firstProperty": { | |
| 10 | + "$ref": "#/definitions/MyObject" | |
| 11 | + }, | |
| 12 | + "secondProperty": { | |
| 13 | + "$ref": "#/definitions/SecondProperty" | |
| 14 | + } | |
| 15 | + }, | |
| 16 | + "required": [], | |
| 17 | + "title": "TopLevel" | |
| 18 | + }, | |
| 19 | + "MyObject": { | |
| 20 | + "type": "object", | |
| 21 | + "additionalProperties": false, | |
| 22 | + "properties": { | |
| 23 | + "a": { | |
| 24 | + "type": "string" | |
| 25 | + }, | |
| 26 | + "b": { | |
| 27 | + "type": "number" | |
| 28 | + }, | |
| 29 | + "c": { | |
| 30 | + "type": "boolean" | |
| 31 | + }, | |
| 32 | + "d": { | |
| 33 | + "type": "string" | |
| 34 | + }, | |
| 35 | + "e": { | |
| 36 | + "type": "number" | |
| 37 | + }, | |
| 38 | + "f": { | |
| 39 | + "type": "boolean" | |
| 40 | + } | |
| 41 | + }, | |
| 42 | + "required": [], | |
| 43 | + "title": "MyObject" | |
| 44 | + }, | |
| 45 | + "MyObjectA": { | |
| 46 | + "type": "object", | |
| 47 | + "additionalProperties": false, | |
| 48 | + "properties": { | |
| 49 | + "a": { | |
| 50 | + "type": "string" | |
| 51 | + }, | |
| 52 | + "b": { | |
| 53 | + "type": "number" | |
| 54 | + }, | |
| 55 | + "c": { | |
| 56 | + "type": "boolean" | |
| 57 | + } | |
| 58 | + }, | |
| 59 | + "required": [], | |
| 60 | + "title": "MyObjectA" | |
| 61 | + }, | |
| 62 | + "MyObjectB": { | |
| 63 | + "type": "object", | |
| 64 | + "additionalProperties": false, | |
| 65 | + "properties": { | |
| 66 | + "d": { | |
| 67 | + "type": "string" | |
| 68 | + }, | |
| 69 | + "e": { | |
| 70 | + "type": "number" | |
| 71 | + }, | |
| 72 | + "f": { | |
| 73 | + "type": "boolean" | |
| 74 | + } | |
| 75 | + }, | |
| 76 | + "required": [], | |
| 77 | + "title": "MyObjectB" | |
| 78 | + }, | |
| 79 | + "SecondProperty": { | |
| 80 | + "anyOf": [ | |
| 81 | + { | |
| 82 | + "type": "array", | |
| 83 | + "items": { | |
| 84 | + "$ref": "#/definitions/MyObjectA" | |
| 85 | + } | |
| 86 | + }, | |
| 87 | + { | |
| 88 | + "$ref": "#/definitions/MyObjectB" | |
| 89 | + } | |
| 90 | + ], | |
| 91 | + "title": "SecondProperty" | |
| 92 | + } | |
| 93 | + } | |
| 94 | +} |
Aschema-swift/test/inputs/schema/anyof-object-union.schema/default/quicktype.swift+286 −0
| @@ -0,0 +1,286 @@ | ||
| 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 firstProperty: MyObject? | |
| 11 | + let secondProperty: SecondProperty? | |
| 12 | + | |
| 13 | + enum CodingKeys: String, CodingKey { | |
| 14 | + case firstProperty = "firstProperty" | |
| 15 | + case secondProperty = "secondProperty" | |
| 16 | + } | |
| 17 | +} | |
| 18 | + | |
| 19 | +// MARK: TopLevel convenience initializers and mutators | |
| 20 | + | |
| 21 | +extension TopLevel { | |
| 22 | + init(data: Data) throws { | |
| 23 | + self = try newJSONDecoder().decode(TopLevel.self, from: data) | |
| 24 | + } | |
| 25 | + | |
| 26 | + init(_ json: String, using encoding: String.Encoding = .utf8) throws { | |
| 27 | + guard let data = json.data(using: encoding) else { | |
| 28 | + throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil) | |
| 29 | + } | |
| 30 | + try self.init(data: data) | |
| 31 | + } | |
| 32 | + | |
| 33 | + init(fromURL url: URL) throws { | |
| 34 | + try self.init(data: try Data(contentsOf: url)) | |
| 35 | + } | |
| 36 | + | |
| 37 | + func with( | |
| 38 | + firstProperty: MyObject?? = nil, | |
| 39 | + secondProperty: SecondProperty?? = nil | |
| 40 | + ) -> TopLevel { | |
| 41 | + return TopLevel( | |
| 42 | + firstProperty: firstProperty ?? self.firstProperty, | |
| 43 | + secondProperty: secondProperty ?? self.secondProperty | |
| 44 | + ) | |
| 45 | + } | |
| 46 | + | |
| 47 | + func jsonData() throws -> Data { | |
| 48 | + return try newJSONEncoder().encode(self) | |
| 49 | + } | |
| 50 | + | |
| 51 | + func jsonString(encoding: String.Encoding = .utf8) throws -> String? { | |
| 52 | + return String(data: try self.jsonData(), encoding: encoding) | |
| 53 | + } | |
| 54 | +} | |
| 55 | + | |
| 56 | +// MARK: - MyObject | |
| 57 | +struct MyObject: Codable { | |
| 58 | + let a: String? | |
| 59 | + let b: Double? | |
| 60 | + let c: Bool? | |
| 61 | + let d: String? | |
| 62 | + let e: Double? | |
| 63 | + let f: Bool? | |
| 64 | + | |
| 65 | + enum CodingKeys: String, CodingKey { | |
| 66 | + case a = "a" | |
| 67 | + case b = "b" | |
| 68 | + case c = "c" | |
| 69 | + case d = "d" | |
| 70 | + case e = "e" | |
| 71 | + case f = "f" | |
| 72 | + } | |
| 73 | +} | |
| 74 | + | |
| 75 | +// MARK: MyObject convenience initializers and mutators | |
| 76 | + | |
| 77 | +extension MyObject { | |
| 78 | + init(data: Data) throws { | |
| 79 | + self = try newJSONDecoder().decode(MyObject.self, from: data) | |
| 80 | + } | |
| 81 | + | |
| 82 | + init(_ json: String, using encoding: String.Encoding = .utf8) throws { | |
| 83 | + guard let data = json.data(using: encoding) else { | |
| 84 | + throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil) | |
| 85 | + } | |
| 86 | + try self.init(data: data) | |
| 87 | + } | |
| 88 | + | |
| 89 | + init(fromURL url: URL) throws { | |
| 90 | + try self.init(data: try Data(contentsOf: url)) | |
| 91 | + } | |
| 92 | + | |
| 93 | + func with( | |
| 94 | + a: String?? = nil, | |
| 95 | + b: Double?? = nil, | |
| 96 | + c: Bool?? = nil, | |
| 97 | + d: String?? = nil, | |
| 98 | + e: Double?? = nil, | |
| 99 | + f: Bool?? = nil | |
| 100 | + ) -> MyObject { | |
| 101 | + return MyObject( | |
| 102 | + a: a ?? self.a, | |
| 103 | + b: b ?? self.b, | |
| 104 | + c: c ?? self.c, | |
| 105 | + d: d ?? self.d, | |
| 106 | + e: e ?? self.e, | |
| 107 | + f: f ?? self.f | |
| 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 | +enum SecondProperty: Codable { | |
| 121 | + case myObjectAArray([MyObjectA]) | |
| 122 | + case myObjectB(MyObjectB) | |
| 123 | + | |
| 124 | + init(from decoder: Decoder) throws { | |
| 125 | + let container = try decoder.singleValueContainer() | |
| 126 | + if let x = try? container.decode([MyObjectA].self) { | |
| 127 | + self = .myObjectAArray(x) | |
| 128 | + return | |
| 129 | + } | |
| 130 | + if let x = try? container.decode(MyObjectB.self) { | |
| 131 | + self = .myObjectB(x) | |
| 132 | + return | |
| 133 | + } | |
| 134 | + throw DecodingError.typeMismatch(SecondProperty.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for SecondProperty")) | |
| 135 | + } | |
| 136 | + | |
| 137 | + func encode(to encoder: Encoder) throws { | |
| 138 | + var container = encoder.singleValueContainer() | |
| 139 | + switch self { | |
| 140 | + case .myObjectAArray(let x): | |
| 141 | + try container.encode(x) | |
| 142 | + case .myObjectB(let x): | |
| 143 | + try container.encode(x) | |
| 144 | + } | |
| 145 | + } | |
| 146 | +} | |
| 147 | + | |
| 148 | +// MARK: - MyObjectA | |
| 149 | +struct MyObjectA: Codable { | |
| 150 | + let a: String? | |
| 151 | + let b: Double? | |
| 152 | + let c: Bool? | |
| 153 | + | |
| 154 | + enum CodingKeys: String, CodingKey { | |
| 155 | + case a = "a" | |
| 156 | + case b = "b" | |
| 157 | + case c = "c" | |
| 158 | + } | |
| 159 | +} | |
| 160 | + | |
| 161 | +// MARK: MyObjectA convenience initializers and mutators | |
| 162 | + | |
| 163 | +extension MyObjectA { | |
| 164 | + init(data: Data) throws { | |
| 165 | + self = try newJSONDecoder().decode(MyObjectA.self, from: data) | |
| 166 | + } | |
| 167 | + | |
| 168 | + init(_ json: String, using encoding: String.Encoding = .utf8) throws { | |
| 169 | + guard let data = json.data(using: encoding) else { | |
| 170 | + throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil) | |
| 171 | + } | |
| 172 | + try self.init(data: data) | |
| 173 | + } | |
| 174 | + | |
| 175 | + init(fromURL url: URL) throws { | |
| 176 | + try self.init(data: try Data(contentsOf: url)) | |
| 177 | + } | |
| 178 | + | |
| 179 | + func with( | |
| 180 | + a: String?? = nil, | |
| 181 | + b: Double?? = nil, | |
| 182 | + c: Bool?? = nil | |
| 183 | + ) -> MyObjectA { | |
| 184 | + return MyObjectA( | |
| 185 | + a: a ?? self.a, | |
| 186 | + b: b ?? self.b, | |
| 187 | + c: c ?? self.c | |
| 188 | + ) | |
| 189 | + } | |
| 190 | + | |
| 191 | + func jsonData() throws -> Data { | |
| 192 | + return try newJSONEncoder().encode(self) | |
| 193 | + } | |
| 194 | + | |
| 195 | + func jsonString(encoding: String.Encoding = .utf8) throws -> String? { | |
| 196 | + return String(data: try self.jsonData(), encoding: encoding) | |
| 197 | + } | |
| 198 | +} | |
| 199 | + | |
| 200 | +// MARK: - MyObjectB | |
| 201 | +struct MyObjectB: Codable { | |
| 202 | + let d: String? | |
| 203 | + let e: Double? | |
| 204 | + let f: Bool? | |
| 205 | + | |
| 206 | + enum CodingKeys: String, CodingKey { | |
| 207 | + case d = "d" | |
| 208 | + case e = "e" | |
| 209 | + case f = "f" | |
| 210 | + } | |
| 211 | +} | |
| 212 | + | |
| 213 | +// MARK: MyObjectB convenience initializers and mutators | |
| 214 | + | |
| 215 | +extension MyObjectB { | |
| 216 | + init(data: Data) throws { | |
| 217 | + self = try newJSONDecoder().decode(MyObjectB.self, from: data) | |
| 218 | + } | |
| 219 | + | |
| 220 | + init(_ json: String, using encoding: String.Encoding = .utf8) throws { | |
| 221 | + guard let data = json.data(using: encoding) else { | |
| 222 | + throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil) | |
| 223 | + } | |
| 224 | + try self.init(data: data) | |
| 225 | + } | |
| 226 | + | |
| 227 | + init(fromURL url: URL) throws { | |
| 228 | + try self.init(data: try Data(contentsOf: url)) | |
| 229 | + } | |
| 230 | + | |
| 231 | + func with( | |
| 232 | + d: String?? = nil, | |
| 233 | + e: Double?? = nil, | |
| 234 | + f: Bool?? = nil | |
| 235 | + ) -> MyObjectB { | |
| 236 | + return MyObjectB( | |
| 237 | + d: d ?? self.d, | |
| 238 | + e: e ?? self.e, | |
| 239 | + f: f ?? self.f | |
| 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 | +// MARK: - Helper functions for creating encoders and decoders | |
| 253 | + | |
| 254 | +func newJSONDecoder() -> JSONDecoder { | |
| 255 | + let decoder = JSONDecoder() | |
| 256 | + decoder.dateDecodingStrategy = .custom({ (decoder) -> Date in | |
| 257 | + let container = try decoder.singleValueContainer() | |
| 258 | + let dateStr = try container.decode(String.self) | |
| 259 | + | |
| 260 | + let formatter = DateFormatter() | |
| 261 | + formatter.calendar = Calendar(identifier: .iso8601) | |
| 262 | + formatter.locale = Locale(identifier: "en_US_POSIX") | |
| 263 | + formatter.timeZone = TimeZone(secondsFromGMT: 0) | |
| 264 | + formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX" | |
| 265 | + if let date = formatter.date(from: dateStr) { | |
| 266 | + return date | |
| 267 | + } | |
| 268 | + formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssXXXXX" | |
| 269 | + if let date = formatter.date(from: dateStr) { | |
| 270 | + return date | |
| 271 | + } | |
| 272 | + throw DecodingError.typeMismatch(Date.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Could not decode date")) | |
| 273 | + }) | |
| 274 | + return decoder | |
| 275 | +} | |
| 276 | + | |
| 277 | +func newJSONEncoder() -> JSONEncoder { | |
| 278 | + let encoder = JSONEncoder() | |
| 279 | + let formatter = DateFormatter() | |
| 280 | + formatter.calendar = Calendar(identifier: .iso8601) | |
| 281 | + formatter.locale = Locale(identifier: "en_US_POSIX") | |
| 282 | + formatter.timeZone = TimeZone(secondsFromGMT: 0) | |
| 283 | + formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssXXXXX" | |
| 284 | + encoder.dateEncodingStrategy = .formatted(formatter) | |
| 285 | + return encoder | |
| 286 | +} |
Aschema-typescript-zod/test/inputs/schema/anyof-object-union.schema/default/TopLevel.ts+211 −0
| @@ -0,0 +1,211 @@ | ||
| 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 | + firstProperty?: FirstProperty; | |
| 12 | + secondProperty?: SecondProperty; | |
| 13 | +} | |
| 14 | + | |
| 15 | +export type FirstProperty = MyObjectA | MyObjectB; | |
| 16 | + | |
| 17 | +export interface MyObjectA { | |
| 18 | + a?: string; | |
| 19 | + b?: number; | |
| 20 | + c?: boolean; | |
| 21 | +} | |
| 22 | + | |
| 23 | +export interface MyObjectB { | |
| 24 | + d?: string; | |
| 25 | + e?: number; | |
| 26 | + f?: boolean; | |
| 27 | +} | |
| 28 | + | |
| 29 | +export type SecondProperty = MyObjectA[] | MyObjectB; | |
| 30 | + | |
| 31 | +// Converts JSON strings to/from your types | |
| 32 | +// and asserts the results of JSON.parse at runtime | |
| 33 | +export class Convert { | |
| 34 | + public static toTopLevel(json: string): TopLevel { | |
| 35 | + return cast(JSON.parse(json), r("TopLevel")); | |
| 36 | + } | |
| 37 | + | |
| 38 | + public static topLevelToJson(value: TopLevel): string { | |
| 39 | + return JSON.stringify(uncast(value, r("TopLevel")), null, 2); | |
| 40 | + } | |
| 41 | +} | |
| 42 | + | |
| 43 | +function invalidValue(typ: any, val: any, key: any, parent: any = ''): never { | |
| 44 | + const prettyTyp = prettyTypeName(typ); | |
| 45 | + const parentText = parent ? ` on ${parent}` : ''; | |
| 46 | + const keyText = key ? ` for key "${key}"` : ''; | |
| 47 | + throw Error(`Invalid value${keyText}${parentText}. Expected ${prettyTyp} but got ${JSON.stringify(val)}`); | |
| 48 | +} | |
| 49 | + | |
| 50 | +function prettyTypeName(typ: any): string { | |
| 51 | + if (Array.isArray(typ)) { | |
| 52 | + if (typ.length === 2 && typ[0] === undefined) { | |
| 53 | + return `an optional ${prettyTypeName(typ[1])}`; | |
| 54 | + } else { | |
| 55 | + return `one of [${typ.map(a => { return prettyTypeName(a); }).join(", ")}]`; | |
| 56 | + } | |
| 57 | + } else if (typeof typ === "object" && typ.literal !== undefined) { | |
| 58 | + return typ.literal; | |
| 59 | + } else { | |
| 60 | + return typeof typ; | |
| 61 | + } | |
| 62 | +} | |
| 63 | + | |
| 64 | +function jsonToJSProps(typ: any): any { | |
| 65 | + if (typ.jsonToJS === undefined) { | |
| 66 | + const map: any = {}; | |
| 67 | + typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ }); | |
| 68 | + typ.jsonToJS = map; | |
| 69 | + } | |
| 70 | + return typ.jsonToJS; | |
| 71 | +} | |
| 72 | + | |
| 73 | +function jsToJSONProps(typ: any): any { | |
| 74 | + if (typ.jsToJSON === undefined) { | |
| 75 | + const map: any = {}; | |
| 76 | + typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ }); | |
| 77 | + typ.jsToJSON = map; | |
| 78 | + } | |
| 79 | + return typ.jsToJSON; | |
| 80 | +} | |
| 81 | + | |
| 82 | +function transform(val: any, typ: any, getProps: any, key: any = '', parent: any = ''): any { | |
| 83 | + function transformPrimitive(typ: string, val: any): any { | |
| 84 | + if (typeof typ === typeof val) return val; | |
| 85 | + return invalidValue(typ, val, key, parent); | |
| 86 | + } | |
| 87 | + | |
| 88 | + function transformUnion(typs: any[], val: any): any { | |
| 89 | + // val must validate against one typ in typs | |
| 90 | + const l = typs.length; | |
| 91 | + for (let i = 0; i < l; i++) { | |
| 92 | + const typ = typs[i]; | |
| 93 | + try { | |
| 94 | + return transform(val, typ, getProps); | |
| 95 | + } catch (_) {} | |
| 96 | + } | |
| 97 | + return invalidValue(typs, val, key, parent); | |
| 98 | + } | |
| 99 | + | |
| 100 | + function transformEnum(cases: string[], val: any): any { | |
| 101 | + if (cases.indexOf(val) !== -1) return val; | |
| 102 | + return invalidValue(cases.map(a => { return l(a); }), val, key, parent); | |
| 103 | + } | |
| 104 | + | |
| 105 | + function transformArray(typ: any, val: any): any { | |
| 106 | + // val must be an array with no invalid elements | |
| 107 | + if (!Array.isArray(val)) return invalidValue(l("array"), val, key, parent); | |
| 108 | + return val.map(el => transform(el, typ, getProps)); | |
| 109 | + } | |
| 110 | + | |
| 111 | + function transformDate(val: any): any { | |
| 112 | + if (val === null) { | |
| 113 | + return null; | |
| 114 | + } | |
| 115 | + const d = new Date(val); | |
| 116 | + if (isNaN(d.valueOf())) { | |
| 117 | + return invalidValue(l("Date"), val, key, parent); | |
| 118 | + } | |
| 119 | + return d; | |
| 120 | + } | |
| 121 | + | |
| 122 | + function transformObject(props: { [k: string]: any }, additional: any, val: any): any { | |
| 123 | + if (val === null || typeof val !== "object" || Array.isArray(val)) { | |
| 124 | + return invalidValue(l(ref || "object"), val, key, parent); | |
| 125 | + } | |
| 126 | + const result: any = {}; | |
| 127 | + Object.getOwnPropertyNames(props).forEach(key => { | |
| 128 | + const prop = props[key]; | |
| 129 | + const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined; | |
| 130 | + result[prop.key] = transform(v, prop.typ, getProps, key, ref); | |
| 131 | + }); | |
| 132 | + Object.getOwnPropertyNames(val).forEach(key => { | |
| 133 | + if (!Object.prototype.hasOwnProperty.call(props, key)) { | |
| 134 | + result[key] = transform(val[key], additional, getProps, key, ref); | |
| 135 | + } | |
| 136 | + }); | |
| 137 | + return result; | |
| 138 | + } | |
| 139 | + | |
| 140 | + if (typ === "any") return val; | |
| 141 | + if (typ === null) { | |
| 142 | + if (val === null) return val; | |
| 143 | + return invalidValue(typ, val, key, parent); | |
| 144 | + } | |
| 145 | + if (typ === false) return invalidValue(typ, val, key, parent); | |
| 146 | + let ref: any = undefined; | |
| 147 | + while (typeof typ === "object" && typ.ref !== undefined) { | |
| 148 | + ref = typ.ref; | |
| 149 | + typ = typeMap[typ.ref]; | |
| 150 | + } | |
| 151 | + if (Array.isArray(typ)) return transformEnum(typ, val); | |
| 152 | + if (typeof typ === "object") { | |
| 153 | + return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val) | |
| 154 | + : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) | |
| 155 | + : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) | |
| 156 | + : invalidValue(typ, val, key, parent); | |
| 157 | + } | |
| 158 | + // Numbers can be parsed by Date but shouldn't be. | |
| 159 | + if (typ === Date && typeof val !== "number") return transformDate(val); | |
| 160 | + return transformPrimitive(typ, val); | |
| 161 | +} | |
| 162 | + | |
| 163 | +function cast<T>(val: any, typ: any): T { | |
| 164 | + return transform(val, typ, jsonToJSProps); | |
| 165 | +} | |
| 166 | + | |
| 167 | +function uncast<T>(val: T, typ: any): any { | |
| 168 | + return transform(val, typ, jsToJSONProps); | |
| 169 | +} | |
| 170 | + | |
| 171 | +function l(typ: any) { | |
| 172 | + return { literal: typ }; | |
| 173 | +} | |
| 174 | + | |
| 175 | +function a(typ: any) { | |
| 176 | + return { arrayItems: typ }; | |
| 177 | +} | |
| 178 | + | |
| 179 | +function u(...typs: any[]) { | |
| 180 | + return { unionMembers: typs }; | |
| 181 | +} | |
| 182 | + | |
| 183 | +function o(props: any[], additional: any) { | |
| 184 | + return { props, additional }; | |
| 185 | +} | |
| 186 | + | |
| 187 | +function m(additional: any) { | |
| 188 | + const props: any[] = []; | |
| 189 | + return { props, additional }; | |
| 190 | +} | |
| 191 | + | |
| 192 | +function r(name: string) { | |
| 193 | + return { ref: name }; | |
| 194 | +} | |
| 195 | + | |
| 196 | +const typeMap: any = { | |
| 197 | + "TopLevel": o([ | |
| 198 | + { json: "firstProperty", js: "firstProperty", typ: u(undefined, u(r("MyObjectA"), r("MyObjectB"))) }, | |
| 199 | + { json: "secondProperty", js: "secondProperty", typ: u(undefined, u(a(r("MyObjectA")), r("MyObjectB"))) }, | |
| 200 | + ], false), | |
| 201 | + "MyObjectA": o([ | |
| 202 | + { json: "a", js: "a", typ: u(undefined, "") }, | |
| 203 | + { json: "b", js: "b", typ: u(undefined, 3.14) }, | |
| 204 | + { json: "c", js: "c", typ: u(undefined, true) }, | |
| 205 | + ], false), | |
| 206 | + "MyObjectB": o([ | |
| 207 | + { json: "d", js: "d", typ: u(undefined, "") }, | |
| 208 | + { json: "e", js: "e", typ: u(undefined, 3.14) }, | |
| 209 | + { json: "f", js: "f", typ: u(undefined, true) }, | |
| 210 | + ], false), | |
| 211 | +}; |
Aschema-typescript/test/inputs/schema/anyof-object-union.schema/default/TopLevel.ts+28 −12
| @@ -8,14 +8,26 @@ | ||
| 8 | 8 | // match the expected interface, even if the JSON is valid. |
| 9 | 9 | |
| 10 | 10 | export interface TopLevel { |
| 11 | - input: Item[]; | |
| 11 | + input: Input[]; | |
| 12 | 12 | } |
| 13 | 13 | |
| 14 | -export interface Item { | |
| 15 | - content?: string; | |
| 16 | - id?: string; | |
| 17 | - output?: string; | |
| 18 | - summary?: string; | |
| 14 | +export type Input = Message | Item; | |
| 15 | + | |
| 16 | +export interface Message { | |
| 17 | + content: string; | |
| 18 | + [property: string]: unknown; | |
| 19 | +} | |
| 20 | + | |
| 21 | +export type Item = FunctionOutput | ReasoningItem; | |
| 22 | + | |
| 23 | +export interface FunctionOutput { | |
| 24 | + id: string; | |
| 25 | + output: string; | |
| 26 | + [property: string]: unknown; | |
| 27 | +} | |
| 28 | + | |
| 29 | +export interface ReasoningItem { | |
| 30 | + summary: string; | |
| 19 | 31 | [property: string]: unknown; |
| 20 | 32 | } |
| 21 | 33 | |
| @@ -186,12 +198,16 @@ function r(name: string) { | ||
| 186 | 198 | |
| 187 | 199 | const typeMap: any = { |
| 188 | 200 | "TopLevel": o([ |
| 189 | - { json: "input", js: "input", typ: a(r("Item")) }, | |
| 201 | + { json: "input", js: "input", typ: a(u(r("Message"), u(r("FunctionOutput"), r("ReasoningItem")))) }, | |
| 190 | 202 | ], false), |
| 191 | - "Item": o([ | |
| 192 | - { json: "content", js: "content", typ: u(undefined, "") }, | |
| 193 | - { json: "id", js: "id", typ: u(undefined, "") }, | |
| 194 | - { json: "output", js: "output", typ: u(undefined, "") }, | |
| 195 | - { json: "summary", js: "summary", typ: u(undefined, "") }, | |
| 203 | + "Message": o([ | |
| 204 | + { json: "content", js: "content", typ: "" }, | |
| 205 | + ], "any"), | |
| 206 | + "FunctionOutput": o([ | |
| 207 | + { json: "id", js: "id", typ: "" }, | |
| 208 | + { json: "output", js: "output", typ: "" }, | |
| 209 | + ], "any"), | |
| 210 | + "ReasoningItem": o([ | |
| 211 | + { json: "summary", js: "summary", typ: "" }, | |
| 196 | 212 | ], "any"), |
| 197 | 213 | }; |
Mschema-typescript/test/inputs/schema/nested-intersection-union.schema/default/TopLevel.ts+24 −8
| @@ -7,23 +7,33 @@ | ||
| 7 | 7 | // These functions will throw an error if the JSON doesn't |
| 8 | 8 | // match the expected interface, even if the JSON is valid. |
| 9 | 9 | |
| 10 | -export interface TopLevel { | |
| 10 | +export type TopLevel = One | Two; | |
| 11 | + | |
| 12 | +export interface One { | |
| 13 | + b: null | string; | |
| 14 | + kind: PurpleKind; | |
| 15 | + [property: string]: unknown; | |
| 16 | +} | |
| 17 | + | |
| 18 | +export type PurpleKind = "one"; | |
| 19 | + | |
| 20 | +export interface Two { | |
| 11 | 21 | b?: null | string; |
| 12 | - kind: Kind; | |
| 22 | + kind: FluffyKind; | |
| 13 | 23 | [property: string]: unknown; |
| 14 | 24 | } |
| 15 | 25 | |
| 16 | -export type Kind = "one" | "two"; | |
| 26 | +export type FluffyKind = "two"; | |
| 17 | 27 | |
| 18 | 28 | // Converts JSON strings to/from your types |
| 19 | 29 | // and asserts the results of JSON.parse at runtime |
| 20 | 30 | export class Convert { |
| 21 | 31 | public static toTopLevel(json: string): TopLevel { |
| 22 | - return cast(JSON.parse(json), r("TopLevel")); | |
| 32 | + return cast(JSON.parse(json), u(r("One"), r("Two"))); | |
| 23 | 33 | } |
| 24 | 34 | |
| 25 | 35 | public static topLevelToJson(value: TopLevel): string { |
| 26 | - return JSON.stringify(uncast(value, r("TopLevel")), null, 2); | |
| 36 | + return JSON.stringify(uncast(value, u(r("One"), r("Two"))), null, 2); | |
| 27 | 37 | } |
| 28 | 38 | } |
| 29 | 39 | |
| @@ -181,12 +191,18 @@ function r(name: string) { | ||
| 181 | 191 | } |
| 182 | 192 | |
| 183 | 193 | const typeMap: any = { |
| 184 | - "TopLevel": o([ | |
| 194 | + "One": o([ | |
| 195 | + { json: "b", js: "b", typ: u(null, "") }, | |
| 196 | + { json: "kind", js: "kind", typ: r("PurpleKind") }, | |
| 197 | + ], "any"), | |
| 198 | + "Two": o([ | |
| 185 | 199 | { json: "b", js: "b", typ: u(undefined, u(null, "")) }, |
| 186 | - { json: "kind", js: "kind", typ: r("Kind") }, | |
| 200 | + { json: "kind", js: "kind", typ: r("FluffyKind") }, | |
| 187 | 201 | ], "any"), |
| 188 | - "Kind": [ | |
| 202 | + "PurpleKind": [ | |
| 189 | 203 | "one", |
| 204 | + ], | |
| 205 | + "FluffyKind": [ | |
| 190 | 206 | "two", |
| 191 | 207 | ], |
| 192 | 208 | }; |
Mschema-typescript/test/inputs/schema/nullable-optional-one-of.schema/default/TopLevel.ts+14 −6
| @@ -7,11 +7,17 @@ | ||
| 7 | 7 | // These functions will throw an error if the JSON doesn't |
| 8 | 8 | // match the expected interface, even if the JSON is valid. |
| 9 | 9 | |
| 10 | +export interface Group { | |
| 11 | + item?: TopLevel[]; | |
| 12 | + [property: string]: unknown; | |
| 13 | +} | |
| 14 | + | |
| 10 | 15 | /** |
| 11 | 16 | * Postman collection |
| 12 | 17 | */ |
| 13 | -export interface TopLevel { | |
| 14 | - item?: TopLevel[]; | |
| 18 | +export type TopLevel = Group | Item; | |
| 19 | + | |
| 20 | +export interface Item { | |
| 15 | 21 | name?: string; |
| 16 | 22 | response?: Response[]; |
| 17 | 23 | [property: string]: unknown; |
| @@ -26,11 +32,11 @@ export interface Response { | ||
| 26 | 32 | // and asserts the results of JSON.parse at runtime |
| 27 | 33 | export class Convert { |
| 28 | 34 | public static toTopLevel(json: string): TopLevel { |
| 29 | - return cast(JSON.parse(json), r("TopLevel")); | |
| 35 | + return cast(JSON.parse(json), u(r("Group"), r("Item"))); | |
| 30 | 36 | } |
| 31 | 37 | |
| 32 | 38 | public static topLevelToJson(value: TopLevel): string { |
| 33 | - return JSON.stringify(uncast(value, r("TopLevel")), null, 2); | |
| 39 | + return JSON.stringify(uncast(value, u(r("Group"), r("Item"))), null, 2); | |
| 34 | 40 | } |
| 35 | 41 | } |
| 36 | 42 | |
| @@ -188,8 +194,10 @@ function r(name: string) { | ||
| 188 | 194 | } |
| 189 | 195 | |
| 190 | 196 | const typeMap: any = { |
| 191 | - "TopLevel": o([ | |
| 192 | - { json: "item", js: "item", typ: u(undefined, a(r("TopLevel"))) }, | |
| 197 | + "Group": o([ | |
| 198 | + { json: "item", js: "item", typ: u(undefined, a(u(r("Group"), r("Item")))) }, | |
| 199 | + ], "any"), | |
| 200 | + "Item": o([ | |
| 193 | 201 | { json: "name", js: "name", typ: u(undefined, "") }, |
| 194 | 202 | { json: "response", js: "response", typ: u(undefined, a(r("Response"))) }, |
| 195 | 203 | ], "any"), |
Mschema-typescript/test/inputs/schema/postman-collection.schema/default/TopLevel.ts+32 −0
| @@ -0,0 +1,32 @@ | ||
| 1 | +import * as z from "zod"; | |
| 2 | + | |
| 3 | + | |
| 4 | +export const MyObjectSchema = z.object({ | |
| 5 | + "a": z.string().optional(), | |
| 6 | + "b": z.number().optional(), | |
| 7 | + "c": z.boolean().optional(), | |
| 8 | + "d": z.string().optional(), | |
| 9 | + "e": z.number().optional(), | |
| 10 | + "f": z.boolean().optional(), | |
| 11 | +}); | |
| 12 | +export type MyObject = z.infer<typeof MyObjectSchema>; | |
| 13 | + | |
| 14 | +export const MyObjectASchema = z.object({ | |
| 15 | + "a": z.string().optional(), | |
| 16 | + "b": z.number().optional(), | |
| 17 | + "c": z.boolean().optional(), | |
| 18 | +}); | |
| 19 | +export type MyObjectA = z.infer<typeof MyObjectASchema>; | |
| 20 | + | |
| 21 | +export const MyObjectBSchema = z.object({ | |
| 22 | + "d": z.string().optional(), | |
| 23 | + "e": z.number().optional(), | |
| 24 | + "f": z.boolean().optional(), | |
| 25 | +}); | |
| 26 | +export type MyObjectB = z.infer<typeof MyObjectBSchema>; | |
| 27 | + | |
| 28 | +export const TopLevelSchema = z.object({ | |
| 29 | + "firstProperty": MyObjectSchema.optional(), | |
| 30 | + "secondProperty": z.union([z.array(MyObjectASchema), MyObjectBSchema]).optional(), | |
| 31 | +}); | |
| 32 | +export type TopLevel = z.infer<typeof TopLevelSchema>; |
No generated files match these filters.