Commits

Ivan Inozemtsev  committed b9dbddf

Extracted JsonPrinter to separate class

  • Participants
  • Parent commits 88c22e0

Comments (0)

Files changed (2)

File fan/Json.fan

     return buf.toStr
   }
   
-  virtual Void toStream(OutStream out) { writeJson(out, val) }
+  virtual Void toStream(OutStream out) { JsonPrinter().writeJson(out, val) }
 
-  private Void writeJson(OutStream out, Obj? obj) 
-  {
-         if (obj == null) { out.writeChars("null") }
-    else if (obj is Jsonable) writeJson(out, (obj->toJson()) )
-    else if (obj is Json) writeJson(out, (obj as Json).val )
-    else if (obj is Str)  writeJsonStr(out, obj)
-    else if (obj is Num)  writeJsonNum(out, obj)
-    else if (obj is Bool) writeJsonBool(out, obj)
-    else if (obj is ConstMap)  writeJsonMap(out, obj)
-    else if (obj is ConstList) writeJsonList(out, obj)
-    else 
-      writeJsonObj(out, obj)
-  }
-
-  private Void writeJsonStr(OutStream out, Str str)
-  {
-    out.writeChar(JsonToken.quote)
-    str.each |char|
-    {
-      if (char <= 0x7f)
-      {
-        switch (char)
-        {
-          case '\b': out.writeChar('\\').writeChar('b')
-          case '\f': out.writeChar('\\').writeChar('f')
-          case '\n': out.writeChar('\\').writeChar('n')
-          case '\r': out.writeChar('\\').writeChar('r')
-          case '\t': out.writeChar('\\').writeChar('t')
-          case '\\': out.writeChar('\\').writeChar('\\')
-          case '"':  out.writeChar('\\').writeChar('"')
-          default: out.writeChar(char)
-        }
-      }
-      else
-      {
-        out.writeChar('\\')
-        out.writeChar('u')
-        out.writeChars(char.toHex(4))
-      }
-    }
-    out.writeChar(JsonToken.quote)
-  }
- 
-  private Void writeJsonNum(OutStream out, Num num) { out.print(num) }
- 
-  private Void writeJsonBool(OutStream out, Bool bool) { out.print(bool) }
-
-  private Void writeJsonMap(OutStream out, ConstMap map)
-  {
-    out.writeChar(JsonToken.objectStart)
-    notFirst := false
-    map.each |entry|
-    {
-      if (notFirst) out.writeChar(JsonToken.comma).writeChar('\n')
-      writeJsonPair(out, entry->key, entry->val)
-      notFirst = true
-    }
-    out.writeChar(JsonToken.objectEnd)
-  }
-
-  private Void writeJsonList(OutStream out, ConstList array)
-  {
-    out.writeChar(JsonToken.arrayStart)
-    notFirst := false
-    array.each |item|
-    {
-      if (notFirst) out.writeChar(JsonToken.comma)
-      writeJson(out, item)
-      notFirst = true
-    }
-    out.writeChar(JsonToken.arrayEnd)
-  }
-
-  private Void writeJsonPair(OutStream out, Str key, Obj? val)
-  {
-    writeJsonStr(out, key)
-    out.writeChar(JsonToken.colon)
-    writeJson(out, val)
-  }
-
-  private Void writeJsonObj(OutStream out, Obj obj)
-  {
-    type := Type.of(obj)
-
-    // if a simple, write it as a string
-    ser := type.facet(Serializable#, false) as Serializable
-    if (ser == null) throw IOErr("Object type not serializable: $type")
-
-    if (ser.simple)
-    {
-      writeJsonStr(out, obj.toStr)
-      return
-    }
-
-    // serialize as JSON object
-    out.writeChar(JsonToken.objectStart)
-    type.fields.each |f, i|
-    {
-      if (i != 0) out.writeChar(JsonToken.comma).writeChar('\n')
-      if (f.isStatic || f.hasFacet(Transient#) == true) return
-      writeJsonPair(out, f.name, f.get(obj))
-    }
-    out.writeChar(JsonToken.objectEnd)
-  }
 
   override Int hash()
   {
     else
       return Str[,]
   }
+  
+  virtual Bool isList() { val is ConstList || val is List }
 }
 
 internal class MutableJson: Json
     } 
   }
   
-  Obj?[] toList()
+  Obj?[] toList(Type of := Obj?#)
   {
-    findAll {true}
+    result := List(of, size)
+    each |v| { result.add(v) }
+    return result
   }
 }
 

File fan/JsonPrinter.fan

+using collections
+
+class JsonPrinter
+{
+  virtual Void writeJson(OutStream out, Obj? obj) 
+  {
+         if (obj == null) { out.writeChars("null") }
+    else if (obj is Jsonable) writeJson(out, (obj->toJson()) )
+    else if (obj is Json) writeJson(out, (obj as Json).val )
+    else if (obj is Str)  writeJsonStr(out, obj)
+    else if (obj is Num)  writeJsonNum(out, obj)
+    else if (obj is Bool) writeJsonBool(out, obj)
+    else if (obj is ConstMap)  writeJsonMap(out, obj)
+    else if (obj is ConstList) writeJsonList(out, obj)
+    else 
+      writeJsonObj(out, obj)
+  }
+
+  protected virtual Void writeJsonStr(OutStream out, Str str)
+  {
+    out.writeChar(JsonToken.quote)
+    str.each |char|
+    {
+      if (char <= 0x7f)
+      {
+        switch (char)
+        {
+          case '\b': out.writeChar('\\').writeChar('b')
+          case '\f': out.writeChar('\\').writeChar('f')
+          case '\n': out.writeChar('\\').writeChar('n')
+          case '\r': out.writeChar('\\').writeChar('r')
+          case '\t': out.writeChar('\\').writeChar('t')
+          case '\\': out.writeChar('\\').writeChar('\\')
+          case '"':  out.writeChar('\\').writeChar('"')
+          default: out.writeChar(char)
+        }
+      }
+      else
+      {
+        out.writeChar('\\')
+        out.writeChar('u')
+        out.writeChars(char.toHex(4))
+      }
+    }
+    out.writeChar(JsonToken.quote)
+  }
+ 
+  protected virtual Void writeJsonNum(OutStream out, Num num) { out.print(num) }
+ 
+  protected virtual Void writeJsonBool(OutStream out, Bool bool) { out.print(bool) }
+
+  protected virtual Void writeJsonMap(OutStream out, ConstMap map)
+  {
+    out.writeChar(JsonToken.objectStart)
+    notFirst := false
+    map.each |entry|
+    {
+      if (notFirst) out.writeChar(JsonToken.comma).writeChar('\n')
+      writeJsonPair(out, entry->key, entry->val)
+      notFirst = true
+    }
+    out.writeChar(JsonToken.objectEnd)
+  }
+
+  protected virtual Void writeJsonList(OutStream out, ConstList array)
+  {
+    out.writeChar(JsonToken.arrayStart)
+    notFirst := false
+    array.each |item|
+    {
+      if (notFirst) out.writeChar(JsonToken.comma)
+      writeJson(out, item)
+      notFirst = true
+    }
+    out.writeChar(JsonToken.arrayEnd)
+  }
+
+  protected virtual Void writeJsonPair(OutStream out, Str key, Obj? val)
+  {
+    writeJsonStr(out, key)
+    out.writeChar(JsonToken.colon)
+    writeJson(out, val)
+  }
+
+  protected virtual Void writeJsonObj(OutStream out, Obj obj)
+  {
+    type := Type.of(obj)
+
+    // if a simple, write it as a string
+    ser := type.facet(Serializable#, false) as Serializable
+    if (ser == null) throw IOErr("Object type not serializable: $type")
+
+    if (ser.simple)
+    {
+      writeJsonStr(out, obj.toStr)
+      return
+    }
+
+    // serialize as JSON object
+    out.writeChar(JsonToken.objectStart)
+    type.fields.each |f, i|
+    {
+      if (i != 0) out.writeChar(JsonToken.comma).writeChar('\n')
+      if (f.isStatic || f.hasFacet(Transient#) == true) return
+      writeJsonPair(out, f.name, f.get(obj))
+    }
+    out.writeChar(JsonToken.objectEnd)
+  }
+
+}