@@ -113,13 +113,32 @@ class DataBuilder {
113113 }
114114
115115 return macro {
116+ order = order ?? [];
117+
116118 var indent = buildIndent (space , level );
117119 var firstIndent = (indentFirst ) ? indent : ' ' ;
118120 if (o == null ) { return firstIndent + " null" ; }
119121 var valueWriter = new $clsValue (ignoreNullOptionals );
120122
121123 @:privateAccess {
122- var values = [for (key in o .keys ()) indent + space + ' "' + key + ' ": ' + valueWriter ._write (o .get (key ), space , level + 1 , false , onAllOptionalNull )];
124+ var values = [
125+ for (key in order )
126+ if (o .exists (key ))
127+ indent + space + ' "' + key + ' ": ' + valueWriter ._write (o .get (key ), space , level + 1 , false , onAllOptionalNull )
128+ ];
129+
130+ var remainingKeys = [
131+ for (key in o .keys ())
132+ if (! order .contains (key ))
133+ key
134+ ];
135+ remainingKeys .sort (Reflect .compare );
136+
137+ values = values .concat ([
138+ for (key in remainingKeys )
139+ indent + space + ' "' + key + ' ": ' + valueWriter ._write (o .get (key ), space , level + 1 , false , onAllOptionalNull )
140+ ]);
141+
123142 var newLine = (space != ' ' && values .length > 0 ) ? ' \n ' : ' ' ;
124143
125144 var json = firstIndent + ' {' + newLine ;
@@ -163,7 +182,8 @@ class DataBuilder {
163182 }
164183
165184 var assignations : Array <Expr > = [];
166- var skips : Array <Expr > = [];
185+ var nullSkips : Array <Expr > = [];
186+ var defaultSkips : Array <Expr > = [];
167187
168188 for (field in fields ) {
169189 if (field .meta .has (" :jignored" )) { continue ; }
@@ -205,6 +225,9 @@ class DataBuilder {
205225 } else if (field .meta .has (" :noquoting" )) {
206226 assignation = macro $assignation
207227 + new $f _cls(ignoreNullOptionals ).dontQuote ()._write (cast $f _a, space , level + 1 , false , onAllOptionalNull );
228+ } else if (field .meta .has (" :order" )) {
229+ var order = field .meta .extract (" :order" )[0 ].params [0 ];
230+ assignation = macro $assignation + new $f _cls(ignoreNullOptionals )._write (cast $f _a, space , level + 1 , false , onAllOptionalNull , $order );
208231 } else {
209232 assignation = macro $assignation + new $f _cls(ignoreNullOptionals )._write (cast $f _a, space , level + 1 , false , onAllOptionalNull );
210233 }
@@ -215,38 +238,48 @@ class DataBuilder {
215238 case TAbstract (t , params ):
216239 if (t .toString () == " Null" ) {
217240 // Null<Bool>
218- skips .push (macro $f _a == null );
241+ nullSkips .push (macro $f _a == null );
219242 } else {
220243 // Bool
221- skips .push (macro false );
244+ nullSkips .push (macro false );
222245 }
223246 default :
224- skips .push (macro $f _a == null );
247+ nullSkips .push (macro $f _a == null );
225248 }
226249 } else {
227- skips .push (macro false );
250+ nullSkips .push (macro false );
251+ }
252+
253+ if (field .meta .has (" :default" )) {
254+ defaultSkips .push (macro $f _a == ${field .meta .extract (" :default" )[0 ].params [0 ]});
255+ } else {
256+ defaultSkips .push (macro false );
228257 }
229258
230259 default :
231260 }
232261 }
233262 var array = {expr :EArrayDecl (assignations ), pos :Context .currentPos ()};
234- var skips = {expr :EArrayDecl (skips ), pos :Context .currentPos ()};
263+ var nullSkips = {expr :EArrayDecl (nullSkips ), pos :Context .currentPos ()};
264+ var defaultSkips = {expr :EArrayDecl (defaultSkips ), pos :Context .currentPos ()};
235265
236266 return macro {
237267 var indent = buildIndent (space , level );
238268 var firstIndent = (indentFirst ) ? indent : ' ' ;
239269 if (o == null ) { return firstIndent + " null" ; }
240270 @:privateAccess {
241271 var decl = ${array };
272+ var defaultSkips = ${defaultSkips };
242273 if (ignoreNullOptionals ) {
243- var skips = ${skips };
244- if (skips .indexOf (false ) == - 1 ) {
274+ var nullSkips = ${nullSkips };
275+ if (nullSkips .indexOf (false ) == - 1 ) {
245276 decl = onAllOptionalNull != null ? [onAllOptionalNull ()] : [];
246277 }
247278 else {
248- decl = [ for (i in 0 ... decl .length ) skips [i ] ? continue : decl [i ]];
279+ decl = [ for (i in 0 ... decl .length ) ( nullSkips [i ] || defaultSkips [ i ]) ? continue : decl [i ]];
249280 }
281+ } else {
282+ decl = [ for (i in 0 ... decl .length ) (defaultSkips [i ]) ? continue : decl [i ]];
250283 }
251284 var newLine = (space != ' ' && decl .length > 0 ) ? ' \n ' : ' ' ;
252285
@@ -415,6 +448,9 @@ class DataBuilder {
415448 }
416449 };
417450
451+ var isMapWriter : Bool = false ;
452+ var mapKey : Null <ComplexType > = null ;
453+
418454 var writeExpr = switch (type ) {
419455 case TInst (_ .get ()=> t , p ) :
420456 switch (t .module ) {
@@ -461,6 +497,8 @@ class DataBuilder {
461497 }
462498 }
463499 else if (t .module == #if (haxe_ver >= 4) " haxe.ds.Map" #else " Map" #end) {
500+ isMapWriter = true ;
501+ mapKey = p [0 ].toComplexType ();
464502 makeMapWriter (p [0 ], p [1 ], c );
465503 }
466504 else {
@@ -492,6 +530,8 @@ class DataBuilder {
492530 {name :" indentFirst" , meta :null , opt :false , type :Context .getType (" Bool" ).toComplexType (), value :macro false },
493531 {name :" onAllOptionalNull" , meta :null , opt :true , type :onAllOptionalNullCT , value : macro null }
494532 ];
533+ if (isMapWriter )
534+ args .push ({name :" order" , meta :null , opt :true , type :(macro : Array < $mapKey > ), value :macro null });
495535 var privateWrite : Field = {
496536 doc : null ,
497537 kind : FFun ({args :args , expr :writeExpr , params :null , ret :null }),
0 commit comments