11{ {> header} }
22import json
33import tables
4+ import marshal
5+ import options
46
57{ {#imports} }import { {import} }
6- { {/imports} }{ {#models} }{ {#model} }{ {#vars} }{ {#isEnum} }
8+ { {/imports} }{ {#models} }{ {#model} }{ {#isEnum} }
9+ type { {{classname} }}* { .pure.} = enum{ {#allowableValues} }{ {#enumVars} }
10+ { {{name} }}{ {/enumVars} }{ {/allowableValues} }
11+
12+ { {#vendorExtensions.x-is-integer-enum} }
13+ func `%`*(v: { {{classname} }}): JsonNode =
14+ result = case v:{ {#allowableValues} }{ {#enumVars} }
15+ of { {{classname} }}.{ {{name} }}: %({ {{value} }}){ {/enumVars} }{ {/allowableValues} }
16+
17+ { {/vendorExtensions.x-is-integer-enum} }
18+ { {^vendorExtensions.x-is-integer-enum} }
19+ func `%`*(v: { {{classname} }}): JsonNode =
20+ result = case v:{ {#allowableValues} }{ {#enumVars} }
21+ of { {{classname} }}.{ {{name} }}: %{ {{value} }}{ {/enumVars} }{ {/allowableValues} }
22+
23+ { {/vendorExtensions.x-is-integer-enum} }
24+ func `$`*(v: { {{classname} }}): string =
25+ result = case v:{ {#allowableValues} }{ {#enumVars} }
26+ of { {{classname} }}.{ {{name} }}: $({ {{value} }}){ {/enumVars} }{ {/allowableValues} }
27+ { {#vendorExtensions.x-is-integer-enum} }
28+ proc to*(node: JsonNode, T: typedesc[{ {{classname} }}]): { {{classname} }} =
29+ if node.kind != JInt:
30+ raise newException(ValueError, "Expected integer for enum { {{classname} }}, got " & $node.kind)
31+ let intVal = node.getInt()
32+ case intVal:{ {#allowableValues} }{ {#enumVars} }
33+ of { {{value} }}:
34+ return { {{classname} }}.{ {{name} }}{ {/enumVars} }{ {/allowableValues} }
35+ else:
36+ raise newException(ValueError, "Invalid enum value for { {{classname} }}: " & $intVal)
37+ { {/vendorExtensions.x-is-integer-enum} }{ {^vendorExtensions.x-is-integer-enum} }
38+ proc to*(node: JsonNode, T: typedesc[{ {{classname} }}]): { {{classname} }} =
39+ if node.kind != JString:
40+ raise newException(ValueError, "Expected string for enum { {{classname} }}, got " & $node.kind)
41+ let strVal = node.getStr()
42+ case strVal:{ {#allowableValues} }{ {#enumVars} }
43+ of $({ {{value} }}):
44+ return { {{classname} }}.{ {{name} }}{ {/enumVars} }{ {/allowableValues} }
45+ else:
46+ raise newException(ValueError, "Invalid enum value for { {{classname} }}: " & strVal)
47+ { {/vendorExtensions.x-is-integer-enum} }
48+ { {/isEnum} }{ {^isEnum} }{ {#vendorExtensions.x-is-one-of} }
49+ # OneOf type
50+ type { {{classname} }}Kind* { .pure.} = enum{ {#composedSchemas.oneOf} }
51+ { {{name} }}Variant{ {/composedSchemas.oneOf} }
52+
53+ type { {{classname} }}* = object
54+ ## { {{description} }}
55+ case kind*: { {{classname} }}Kind{ {#composedSchemas.oneOf} }
56+ of { {{classname} }}Kind.{ {{name} }}Variant:
57+ { {{baseName} }}Value*: { {{dataType} }}{ {/composedSchemas.oneOf} }
58+
59+ proc to*(node: JsonNode, T: typedesc[{ {{classname} }}]): { {{classname} }} =
60+ ## Custom deserializer for oneOf type - tries each variant{ {#composedSchemas.oneOf} }
61+ try:
62+ return { {{classname} }}(kind: { {{classname} }}Kind.{ {{name} }}Variant, { {{baseName} }}Value: to(node, { {{dataType} }}))
63+ except Exception as e:
64+ when defined(debug):
65+ echo "Failed to deserialize as { {{dataType} }}: ", e.msg{ {/composedSchemas.oneOf} }
66+ raise newException(ValueError, "Unable to deserialize into any variant of { {{classname} }}. JSON: " & $node)
67+ { {/vendorExtensions.x-is-one-of} }{ {#vendorExtensions.x-is-any-of} }
68+ # AnyOf type
69+ type { {{classname} }}Kind* { .pure.} = enum{ {#composedSchemas.anyOf} }
70+ { {{name} }}Variant{ {/composedSchemas.anyOf} }
71+
72+ type { {{classname} }}* = object
73+ ## { {{description} }}
74+ case kind*: { {{classname} }}Kind{ {#composedSchemas.anyOf} }
75+ of { {{classname} }}Kind.{ {{name} }}Variant:
76+ { {{baseName} }}Value*: { {{dataType} }}{ {/composedSchemas.anyOf} }
77+
78+ proc to*(node: JsonNode, T: typedesc[{ {{classname} }}]): { {{classname} }} =
79+ ## Custom deserializer for anyOf type - tries each variant{ {#composedSchemas.anyOf} }
80+ try:
81+ return { {{classname} }}(kind: { {{classname} }}Kind.{ {{name} }}Variant, { {{baseName} }}Value: to(node, { {{dataType} }}))
82+ except Exception as e:
83+ when defined(debug):
84+ echo "Failed to deserialize as { {{dataType} }}: ", e.msg{ {/composedSchemas.anyOf} }
85+ raise newException(ValueError, "Unable to deserialize into any variant of { {{classname} }}. JSON: " & $node)
86+ { {/vendorExtensions.x-is-any-of} }{ {^vendorExtensions.x-is-one-of} }{ {^vendorExtensions.x-is-any-of} }{ {#vars} }{ {#isEnum} }
787type { {{enumName} }}* { .pure.} = enum{ {#allowableValues} }{ {#enumVars} }
888 { {{name} }}{ {/enumVars} }{ {/allowableValues} }
989{ {/isEnum} }{ {/vars} }
1090type { {{classname} }}* = object
1191 ## { {{description} }}{ {#vars} }
12- { {{name} }}*: { {#isEnum} }{ {{ enumName} }}{ {/isEnum} }{ {^isEnum} }{ {{dataType} }}{ {/isEnum} }{ {#description} } ## { {{.} }}{ {/description} }{ {/vars} }
13- { {#vars} }{ {#isEnum} }
92+ { {{name} }}*: { {#isEnum} }{ {#vendorExtensions.x-is-optional } }Option[ { {{ enumName} }}] { {/vendorExtensions.x-is-optional } } { {^vendorExtensions.x-is-optional } } { {{enumName } }} { {/vendorExtensions.x-is-optional } }{ {/isEnum} }{ {^isEnum} }{ {{dataType} }}{ {/isEnum} }{ {#description} } ## { {{.} }}{ {/description} }{ {/vars} }
93+ { {#vars} }{ {#isEnum} }{ {#vendorExtensions.x-is-integer-enum } }
1494func `%`*(v: { {{enumName} }}): JsonNode =
15- let str = case v:{ {#allowableValues} }{ {#enumVars} }
16- of { {{enumName} }}.{ {{name} }}: { {{value} }}{ {/enumVars} }{ {/allowableValues} }
17-
18- JsonNode(kind: JString, str: str)
19-
95+ result = case v:{ {#allowableValues} }{ {#enumVars} }
96+ of { {{enumName} }}.{ {{name} }}: %({ {{value} }}){ {/enumVars} }{ {/allowableValues} }
97+ { {/vendorExtensions.x-is-integer-enum} }{ {^vendorExtensions.x-is-integer-enum} }
98+ func `%`*(v: { {{enumName} }}): JsonNode =
99+ result = case v:{ {#allowableValues} }{ {#enumVars} }
100+ of { {{enumName} }}.{ {{name} }}: %{ {{value} }}{ {/enumVars} }{ {/allowableValues} }
101+ { {/vendorExtensions.x-is-integer-enum} }
20102func `$`*(v: { {{enumName} }}): string =
21103 result = case v:{ {#allowableValues} }{ {#enumVars} }
22- of { {{enumName} }}.{ {{name} }}: { {{value} }}{ {/enumVars} }{ {/allowableValues} }
23- { {/isEnum} }{ {/vars} }{ {/model} }{ {/models} }
104+ of { {{enumName} }}.{ {{name} }}: $({ {{value} }}){ {/enumVars} }{ {/allowableValues} }
105+ { {#vendorExtensions.x-is-integer-enum} }
106+ proc to*(node: JsonNode, T: typedesc[{ {{enumName} }}]): { {{enumName} }} =
107+ if node.kind != JInt:
108+ raise newException(ValueError, "Expected integer for enum { {{enumName} }}, got " & $node.kind)
109+ let intVal = node.getInt()
110+ case intVal:{ {#allowableValues} }{ {#enumVars} }
111+ of { {{value} }}:
112+ return { {{enumName} }}.{ {{name} }}{ {/enumVars} }{ {/allowableValues} }
113+ else:
114+ raise newException(ValueError, "Invalid enum value for { {{enumName} }}: " & $intVal)
115+ { {/vendorExtensions.x-is-integer-enum} }{ {^vendorExtensions.x-is-integer-enum} }
116+ proc to*(node: JsonNode, T: typedesc[{ {{enumName} }}]): { {{enumName} }} =
117+ if node.kind != JString:
118+ raise newException(ValueError, "Expected string for enum { {{enumName} }}, got " & $node.kind)
119+ let strVal = node.getStr()
120+ case strVal:{ {#allowableValues} }{ {#enumVars} }
121+ of $({ {{value} }}):
122+ return { {{enumName} }}.{ {{name} }}{ {/enumVars} }{ {/allowableValues} }
123+ else:
124+ raise newException(ValueError, "Invalid enum value for { {{enumName} }}: " & strVal)
125+ { {/vendorExtensions.x-is-integer-enum} }
126+ { {/isEnum} }{ {/vars} }{ {#vendorExtensions.x-has-custom-json-names} }
127+
128+ # Custom JSON deserialization for { {{classname} }} with custom field names
129+ proc to*(node: JsonNode, T: typedesc[{ {{classname} }}]): { {{classname} }} =
130+ result = { {{classname} }}()
131+ if node.kind == JObject:{ {#vars} }{ {#vendorExtensions.x-json-name} }{ {#vendorExtensions.x-is-optional} }
132+ if node.hasKey("{ {{vendorExtensions.x-json-name} }}") and node["{ {{vendorExtensions.x-json-name} }}"].kind != JNull:{ {#vendorExtensions.x-is-array-with-custom-json} }
133+ # Optional array of types with custom JSON - manually iterate and deserialize
134+ let arrayNode = node["{ {{vendorExtensions.x-json-name} }}"]
135+ if arrayNode.kind == JArray:
136+ var arr: seq[{ {{vendorExtensions.x-array-inner-type} }}] = @[]
137+ for item in arrayNode.items:
138+ arr.add(to(item, { {{vendorExtensions.x-array-inner-type} }}))
139+ result.{ {{name} }} = some(arr){ {/vendorExtensions.x-is-array-with-custom-json} }{ {^vendorExtensions.x-is-array-with-custom-json} }{ {#vendorExtensions.x-is-external-enum} }
140+ result.{ {{name} }} = some({ {{vendorExtensions.x-enum-module} }}.to(node["{ {{vendorExtensions.x-json-name} }}"], { {{vendorExtensions.x-enum-type} }})){ {/vendorExtensions.x-is-external-enum} }{ {^vendorExtensions.x-is-external-enum} }{ {#isEnum} }
141+ result.{ {{name} }} = some(to(node["{ {{vendorExtensions.x-json-name} }}"], { {{enumName} }})){ {/isEnum} }{ {^isEnum} }
142+ result.{ {{name} }} = some(to(node["{ {{vendorExtensions.x-json-name} }}"], typeof(result.{ {{name} }}.get()))){ {/isEnum} }{ {/vendorExtensions.x-is-external-enum} }{ {/vendorExtensions.x-is-array-with-custom-json} }{ {/vendorExtensions.x-is-optional} }{ {^vendorExtensions.x-is-optional} }
143+ if node.hasKey("{ {{vendorExtensions.x-json-name} }}"):{ {#vendorExtensions.x-is-array-with-custom-json} }
144+ # Array of types with custom JSON - manually iterate and deserialize
145+ let arrayNode = node["{ {{vendorExtensions.x-json-name} }}"]
146+ if arrayNode.kind == JArray:
147+ result.{ {{name} }} = @[]
148+ for item in arrayNode.items:
149+ result.{ {{name} }}.add(to(item, { {{vendorExtensions.x-array-inner-type} }})){ {/vendorExtensions.x-is-array-with-custom-json} }{ {^vendorExtensions.x-is-array-with-custom-json} }{ {#vendorExtensions.x-is-external-enum} }
150+ result.{ {{name} }} = { {{vendorExtensions.x-enum-module} }}.to(node["{ {{vendorExtensions.x-json-name} }}"], { {{vendorExtensions.x-enum-type} }}){ {/vendorExtensions.x-is-external-enum} }{ {^vendorExtensions.x-is-external-enum} }{ {#isEnum} }
151+ result.{ {{name} }} = to(node["{ {{vendorExtensions.x-json-name} }}"], { {{enumName} }}){ {/isEnum} }{ {^isEnum} }
152+ result.{ {{name} }} = to(node["{ {{vendorExtensions.x-json-name} }}"], { {{dataType} }}){ {/isEnum} }{ {/vendorExtensions.x-is-external-enum} }{ {/vendorExtensions.x-is-array-with-custom-json} }{ {/vendorExtensions.x-is-optional} }{ {/vendorExtensions.x-json-name} }{ {^vendorExtensions.x-json-name} }{ {#vendorExtensions.x-is-optional} }
153+ if node.hasKey("{ {{baseName} }}") and node["{ {{baseName} }}"].kind != JNull:{ {#vendorExtensions.x-is-array-with-custom-json} }
154+ # Optional array of types with custom JSON - manually iterate and deserialize
155+ let arrayNode = node["{ {{baseName} }}"]
156+ if arrayNode.kind == JArray:
157+ var arr: seq[{ {{vendorExtensions.x-array-inner-type} }}] = @[]
158+ for item in arrayNode.items:
159+ arr.add(to(item, { {{vendorExtensions.x-array-inner-type} }}))
160+ result.{ {{name} }} = some(arr){ {/vendorExtensions.x-is-array-with-custom-json} }{ {^vendorExtensions.x-is-array-with-custom-json} }{ {#vendorExtensions.x-is-external-enum} }
161+ result.{ {{name} }} = some({ {{vendorExtensions.x-enum-module} }}.to(node["{ {{baseName} }}"], { {{vendorExtensions.x-enum-type} }})){ {/vendorExtensions.x-is-external-enum} }{ {^vendorExtensions.x-is-external-enum} }{ {#isEnum} }
162+ result.{ {{name} }} = some(to(node["{ {{baseName} }}"], { {{enumName} }})){ {/isEnum} }{ {^isEnum} }
163+ result.{ {{name} }} = some(to(node["{ {{baseName} }}"], typeof(result.{ {{name} }}.get()))){ {/isEnum} }{ {/vendorExtensions.x-is-external-enum} }{ {/vendorExtensions.x-is-array-with-custom-json} }{ {/vendorExtensions.x-is-optional} }{ {^vendorExtensions.x-is-optional} }
164+ if node.hasKey("{ {{baseName} }}"):{ {#vendorExtensions.x-is-array-with-custom-json} }
165+ # Array of types with custom JSON - manually iterate and deserialize
166+ let arrayNode = node["{ {{baseName} }}"]
167+ if arrayNode.kind == JArray:
168+ result.{ {{name} }} = @[]
169+ for item in arrayNode.items:
170+ result.{ {{name} }}.add(to(item, { {{vendorExtensions.x-array-inner-type} }})){ {/vendorExtensions.x-is-array-with-custom-json} }{ {^vendorExtensions.x-is-array-with-custom-json} }{ {#vendorExtensions.x-is-external-enum} }
171+ result.{ {{name} }} = { {{vendorExtensions.x-enum-module} }}.to(node["{ {{baseName} }}"], { {{vendorExtensions.x-enum-type} }}){ {/vendorExtensions.x-is-external-enum} }{ {^vendorExtensions.x-is-external-enum} }{ {#isEnum} }
172+ result.{ {{name} }} = to(node["{ {{baseName} }}"], { {{enumName} }}){ {/isEnum} }{ {^isEnum} }
173+ result.{ {{name} }} = to(node["{ {{baseName} }}"], { {{dataType} }}){ {/isEnum} }{ {/vendorExtensions.x-is-external-enum} }{ {/vendorExtensions.x-is-array-with-custom-json} }{ {/vendorExtensions.x-is-optional} }{ {/vendorExtensions.x-json-name} }{ {/vars} }
174+
175+ # Custom JSON serialization for { {{classname} }} with custom field names
176+ proc `%`*(obj: { {{classname} }}): JsonNode =
177+ result = newJObject(){ {#vars} }{ {#vendorExtensions.x-json-name} }{ {#vendorExtensions.x-is-optional} }
178+ if obj.{ {{name} }}.isSome():
179+ result["{ {{vendorExtensions.x-json-name} }}"] = %obj.{ {{name} }}.get(){ {/vendorExtensions.x-is-optional} }{ {^vendorExtensions.x-is-optional} }
180+ result["{ {{vendorExtensions.x-json-name} }}"] = %obj.{ {{name} }}{ {/vendorExtensions.x-is-optional} }{ {/vendorExtensions.x-json-name} }{ {^vendorExtensions.x-json-name} }{ {#vendorExtensions.x-is-optional} }
181+ if obj.{ {{name} }}.isSome():
182+ result["{ {{baseName} }}"] = %obj.{ {{name} }}.get(){ {/vendorExtensions.x-is-optional} }{ {^vendorExtensions.x-is-optional} }
183+ result["{ {{baseName} }}"] = %obj.{ {{name} }}{ {/vendorExtensions.x-is-optional} }{ {/vendorExtensions.x-json-name} }{ {/vars} }
184+ { {/vendorExtensions.x-has-custom-json-names} }{ {/vendorExtensions.x-is-any-of} }{ {/vendorExtensions.x-is-one-of} }{ {/isEnum} }{ {/model} }{ {/models} }
0 commit comments