Created
January 10, 2014 21:26
-
-
Save nadako/8362947 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using StringTools; | |
/** | |
* Супер-принтер для JSON. | |
* | |
* От не-супер принтера его отличают две вещи: | |
* 1. Он делает оступы | |
* 2. Он сортирует поля объектов при сериализации | |
* | |
* Он был написан для того чтобы собирать дефы под разными платформами | |
* и везде и всегда они выглядели одинаково. Это удобно, если нужно | |
* посмотреть дифф собранных дефов, и увидеть только то что реально | |
* изменилось, а не в результате сериализации на другой платформе. | |
*/ | |
class FancyJSON | |
{ | |
public static function encode(obj:Dynamic):String | |
{ | |
var printer = new FancyJSON(); | |
printer.encodeValue(obj, 0); | |
printer.buf.addChar("\n".code); | |
return printer.buf.toString(); | |
} | |
var tab:String; | |
var tabCache:Array<String>; | |
var buf:StringBuf; | |
public function new() | |
{ | |
tab = " "; | |
tabCache = [""]; | |
buf = new StringBuf(); | |
} | |
function getTab(n:Int):String | |
{ | |
return if (n < tabCache.length) tabCache[n] else tabCache[n] = getTab(n-1) + tab; | |
} | |
function encodeValue(value:Dynamic, depth:Int):Void | |
{ | |
if (Std.is(value, Float) || Std.is(value, Bool)) | |
{ | |
buf.add(value); | |
} | |
else if (Std.is(value, Array)) | |
{ | |
encodeArray(value, depth + 1); | |
} | |
else if (Std.is(value, String)) | |
{ | |
buf.addChar('"'.code); | |
buf.add(Std.string(value).replace("\\","\\\\").replace("\n","\\n").replace("\r","\\r").replace('"','\\"')); | |
buf.addChar('"'.code); | |
} | |
else if (Reflect.isObject(value)) | |
{ | |
encodeObject(value,depth+1); | |
} | |
else | |
{ | |
throw 'Unsupported field type: $value'; | |
} | |
} | |
function encodeObject(obj:Dynamic, depth:Int):Void | |
{ | |
var fields = Reflect.fields(obj); | |
fields.sort(Reflect.compare); | |
var tab = getTab(depth); | |
var len = fields.length; | |
var last = len - 1; | |
buf.addChar("{".code); | |
for (i in 0...len) | |
{ | |
if (i > 0) buf.add(",\n") else buf.addChar("\n".code); | |
buf.add(tab); | |
var field = fields[i]; | |
buf.addChar('"'.code); | |
buf.add(field); | |
buf.add('": '); | |
encodeValue(Reflect.field(obj, field), depth); | |
if (i == last) | |
{ | |
buf.addChar("\n".code); | |
buf.add(getTab(depth-1)); | |
} | |
} | |
buf.addChar("}".code); | |
} | |
function encodeArray(obj:Array<Dynamic>, depth:Int):Void | |
{ | |
buf.addChar("[".code); | |
var tab = getTab(depth); | |
var len = obj.length; | |
var last = len - 1; | |
for (i in 0...len) | |
{ | |
if (i > 0) buf.add(",\n") else buf.addChar("\n".code); | |
buf.add(tab); | |
encodeValue(obj[i], depth); | |
if (i == last) | |
{ | |
buf.addChar("\n".code); | |
buf.add(getTab(depth - 1)); | |
} | |
} | |
buf.addChar("]".code); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment