8
8
9
9
from . import _logger , schema
10
10
from .codegen_base import CodeGenBase , TypeDef
11
- from .cpp_codegen import isArray , isEnumSchema , isRecordSchema , pred
11
+ from .cpp_codegen import isArray , isEnumSchema , isMapSchema , isRecordSchema , isUnionSchema , pred
12
12
from .exceptions import SchemaException
13
13
from .schema import shortname
14
14
@@ -63,11 +63,10 @@ def prologue(self) -> None:
63
63
self .target .write (
64
64
f"""module { self .package } ;
65
65
66
- import salad.meta.dumper : genDumper;
67
- import salad.meta.impl : genCtor_, genIdentifier, genOpEq;
66
+ import salad.meta.impl : genBody_;
68
67
import salad.meta.parser : import_ = importFromURI;
69
68
import salad.meta.uda : defaultValue, documentRoot, id, idMap, link, LinkResolver, secondaryFilesDSL, typeDSL;
70
- import salad.primitives : SchemaBase ;
69
+ import salad.primitives : EnumSchemaBase, MapSchemaBase, RecordSchemaBase, UnionSchemaBase ;
71
70
import salad.type : None, Union;
72
71
73
72
"""
@@ -83,9 +82,9 @@ def prologue(self) -> None:
83
82
f"""
84
83
enum saladVersion = "{ self .salad_version } ";
85
84
86
- mixin template genCtor ()
85
+ mixin template genBody ()
87
86
{{
88
- mixin genCtor_ !saladVersion;
87
+ mixin genBody_ !saladVersion;
89
88
}}
90
89
""" # noqa: B907
91
90
)
@@ -225,6 +224,9 @@ def parse_record_field_type(
225
224
return annotate_str , shortname (type_ .get ("name" , "record" ))
226
225
elif shortname (type_ ["type" ]) == "enum" :
227
226
return annotate_str , "'not yet implemented'"
227
+ elif shortname (type_ ["type" ]) == "map" :
228
+ value_type = self .parse_record_field_type (type_ ["values" ], None , parent_has_idmap = has_idmap , has_default = True )[1 ]
229
+ type_str = f"{ value_type } [string]"
228
230
return annotate_str , type_str
229
231
230
232
def parse_record_field (self , field : Dict [str , Any ], parent_name : Optional [str ] = None ) -> str :
@@ -242,7 +244,7 @@ def parse_record_field(self, field: Dict[str, Any], parent_name: Optional[str] =
242
244
value = cast (str , parent_name )
243
245
return f'{ doc_comment } static immutable { fname } = "{ value } ";' # noqa: B907
244
246
245
- if field .get ("default" , None ):
247
+ if field .get ("default" , None ) is not None :
246
248
default_value = json .dumps (field ["default" ])
247
249
default_str = f'@defaultValue(q"<{ default_value } >") '
248
250
else :
@@ -271,13 +273,11 @@ def parse_record_schema(self, stype: Dict[str, Any]) -> str:
271
273
doc_comment = self .to_doc_comment (stype .get ("doc" , None ))
272
274
273
275
return f"""
274
- { doc_comment } { doc_root_annotation } class { classname } : SchemaBase
276
+ { doc_comment } { doc_root_annotation } class { classname } : RecordSchemaBase
275
277
{{
276
278
{ decl_str }
277
279
278
- mixin genCtor;
279
- mixin genIdentifier;
280
- mixin genDumper;
280
+ mixin genBody;
281
281
}}"""
282
282
283
283
def parse_enum (self , stype : Dict [str , Any ]) -> str :
@@ -308,7 +308,7 @@ def parse_enum(self, stype: Dict[str, Any]) -> str:
308
308
doc_comment = ""
309
309
310
310
return f"""
311
- { doc_comment } { doc_root_annotation } class { classname } : SchemaBase
311
+ { doc_comment } { doc_root_annotation } class { classname } : EnumSchemaBase
312
312
{{
313
313
///
314
314
enum Symbol
@@ -318,9 +318,47 @@ def parse_enum(self, stype: Dict[str, Any]) -> str:
318
318
319
319
Symbol value;
320
320
321
- mixin genCtor;
322
- mixin genOpEq;
323
- mixin genDumper;
321
+ mixin genBody;
322
+ }}"""
323
+
324
+ def parse_union (self , stype : Dict [str , Any ]) -> str :
325
+ """Return a declaration string for a given union schema."""
326
+ name = cast (str , stype ["name" ])
327
+ classname = self .safe_name (name )
328
+
329
+ types = self .parse_record_field_type (stype ["names" ], None )[1 ]
330
+
331
+ if "doc" in stype :
332
+ doc_comment = self .to_doc_comment (stype ["doc" ])
333
+ else :
334
+ doc_comment = ""
335
+
336
+ return f"""
337
+ { doc_comment } class { classname } : UnionSchemaBase
338
+ {{
339
+ { types } payload;
340
+
341
+ mixin genBody;
342
+ }}"""
343
+
344
+ def parse_map (self , stype : Dict [str , Any ]) -> str :
345
+ """Return a declaration string for a given map schema."""
346
+ name = cast (str , stype ["name" ])
347
+ classname = self .safe_name (name )
348
+
349
+ values = self .parse_record_field_type (stype ["values" ], None , has_default = True )[1 ]
350
+
351
+ if "doc" in stype :
352
+ doc_comment = self .to_doc_comment (stype ["doc" ])
353
+ else :
354
+ doc_comment = ""
355
+
356
+ return f"""
357
+ { doc_comment } class { classname } : MapSchemaBase
358
+ {{
359
+ { values } [string] payload;
360
+
361
+ mixin genBody;
324
362
}}"""
325
363
326
364
def parse (self , items : List [Dict [str , Any ]]) -> None :
@@ -343,8 +381,12 @@ def parse(self, items: List[Dict[str, Any]]) -> None:
343
381
dlang_defs .append (self .parse_record_schema (stype ))
344
382
elif isEnumSchema (stype ):
345
383
dlang_defs .append (self .parse_enum (stype ))
384
+ elif isUnionSchema (stype ):
385
+ dlang_defs .append (self .parse_union (stype ))
386
+ elif isMapSchema (stype ):
387
+ dlang_defs .append (self .parse_map (stype ))
346
388
else :
347
- _logger .error ("not parsed %s" , stype )
389
+ _logger .error ("not parsed %s" , json . dumps ( stype ) )
348
390
349
391
self .target .write ("\n " .join (dlang_defs ))
350
392
self .target .write ("\n " )
0 commit comments