The log of my #100DaysOfCode challenge. Started on 1 January 2018.
Created SwiftJson as a Swift port of ktjson and c++17-json. Coded
up the basic JsonValue
enum type.
Implemented a basic JSON value printer.
Converted the JSON value printer to use visitor pattern, which is how it should have been to begin with.
Support initialising JsonValue
with literals. Yay for yummy syntactic
sugar!
Support pretty printing of JsonValue
. The implementation approach is
a bit fugly so I'll try to refactor this later.
Add a very basic parser, that does not support parsing numbers and strings yet.
Add number and string parsing.
Track down why printing out large JSON trees is so slow. It turned out
to be because, by default, objects passed to print
or debugPrint
are
sent to a _TeeStream
, which collects the output into a string that is
then sent to _playgroundPrintHook
.
You have to set _playgroundPrintHook
to nil to disable this; it is
initially set to a no-op closure, which means the string buffer is still
built, only to be discarded.
What kind of slow are we talking about? For a 4MB JSON document, it
takes about 1 second to print with _playgroundPrintHook
disabled, and
on the order of minutes with it enabled.
Reorganise the code into multiple modules, so that there's SwiftJson
library and a PrettyPrintJson
executable.
Add some simple tests for the SwiftJson
module.
Move JsonPrettyPrinter
to the PrettyPrintJson
module, and make
JsonVisitor
use argument name overloading, which seems more idiomatic
for Swift.
Print numbers in JsonPrettyPrinter
as integers if they actually are.
Convert JsonPrettyPrinter
to use JsonPrettyPrintVisitor
, a new
subclass of JsonPrinterVisitor
. This is where the true power of
visitors come in: open methods become extension points for the visitor,
something that isn't as clean to achieve using switch
alone.
Implement ASCII-only mode in JsonPrettyPrinter
, where non-ASCII
characters are escaped with \u
.