summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDerek Chen-Beker <dchenbecker@gmail.com>2010-10-08 20:22:13 +0000
committerDerek Chen-Beker <dchenbecker@gmail.com>2010-10-08 20:22:13 +0000
commit908ed2f29f4dbe03bb2ff73341a74c524f44f964 (patch)
tree6e7ba5f87f82d0d9ecfd018de561127d5376cfb2 /src
parent4af97e33e7f60e61df1483af3605050a3af5dfb6 (diff)
downloadscala-908ed2f29f4dbe03bb2ff73341a74c524f44f964.tar.gz
scala-908ed2f29f4dbe03bb2ff73341a74c524f44f964.tar.bz2
scala-908ed2f29f4dbe03bb2ff73341a74c524f44f964.zip
Made some adjustments to toString formatting of...
Made some adjustments to toString formatting of JSON Closes #3605 Hopefully this is the last time I have to close this ticket. In addition to default behavior, the end user can specify their own JSON value formatting function if they want to customize it.
Diffstat (limited to 'src')
-rw-r--r--src/library/scala/util/parsing/json/Parser.scala76
1 files changed, 72 insertions, 4 deletions
diff --git a/src/library/scala/util/parsing/json/Parser.scala b/src/library/scala/util/parsing/json/Parser.scala
index ce9c1dd3fe..b7c338b3be 100644
--- a/src/library/scala/util/parsing/json/Parser.scala
+++ b/src/library/scala/util/parsing/json/Parser.scala
@@ -19,14 +19,81 @@ import scala.util.parsing.combinator.lexical._
*
* @author Derek Chen-Becker <"java"+@+"chen-becker"+"."+"org">
*/
-sealed abstract class JSONType
+sealed abstract class JSONType {
+ /**
+ * This version of toString allows you to provide your own value
+ * formatter.
+ */
+ def toString (formatter : JSONFormat.ValueFormatter) : String
+
+ /**
+ * Returns a String representation of this JSON value
+ * using the JSONFormat.defaultFormatter.
+ */
+ override def toString = toString(JSONFormat.defaultFormatter)
+}
+
+/**
+ * This object defines functions that are used when converting JSONType
+ * values into String representations. Mostly this is concerned with
+ * proper quoting of strings.
+ *
+ * @author Derek Chen-Becker <"java"+@+"chen-becker"+"."+"org">
+ */
+object JSONFormat {
+ /**
+ * This type defines a function that can be used to
+ * format values into JSON format.
+ */
+ type ValueFormatter = Any => String
+
+ /**
+ * The default formatter used by the library. You can
+ * provide your own with the toString calls on
+ * JSONObject and JSONArray instances.
+ */
+ val defaultFormatter : ValueFormatter = (x : Any) => x match {
+ case s : String => "\"" + quoteString(s) + "\""
+ case jo : JSONObject => jo.toString(defaultFormatter)
+ case ja : JSONArray => ja.toString(defaultFormatter)
+ case other => other.toString
+ }
+
+ /**
+ * This function can be used to properly quote Strings
+ * for JSON output.
+ */
+ def quoteString (s : String) : String =
+ s.map {
+ case '"' => "\\\""
+ case '\\' => "\\\\"
+ case '/' => "\\/"
+ case '\b' => "\\b"
+ case '\f' => "\\f"
+ case '\n' => "\\n"
+ case '\r' => "\\r"
+ case '\t' => "\\t"
+ /* We'll unicode escape any control characters. These include:
+ * 0x0 -> 0x1f : ASCII Control (C0 Control Codes)
+ * 0x7f : ASCII DELETE
+ * 0x80 -> 0x9f : C1 Control Codes
+ *
+ * Per RFC4627, section 2.5, we're not technically required to
+ * encode the C1 codes, but we do to be safe.
+ */
+ case c if ((c >= '\u0000' && c <= '\u001f') || (c >= '\u007f' && c <= '\u009f')) => "\\u%04x".format(c: Int)
+ case c => c
+ }.mkString
+}
/**
* Represents a JSON Object (map).
+ *
* @author Derek Chen-Becker <"java"+@+"chen-becker"+"."+"org">
*/
-case class JSONObject (obj : Map[Any,Any]) extends JSONType {
- override def toString = "{" + obj.map({ case (k,v) => k + " : " + v }).mkString(", ") + "}"
+case class JSONObject (obj : Map[String,Any]) extends JSONType {
+ def toString (formatter : JSONFormat.ValueFormatter) =
+ "{" + obj.map({ case (k,v) => formatter(k.toString) + " : " + formatter(v) }).mkString(", ") + "}"
}
/**
@@ -34,7 +101,8 @@ case class JSONObject (obj : Map[Any,Any]) extends JSONType {
* @author Derek Chen-Becker <"java"+@+"chen-becker"+"."+"org">
*/
case class JSONArray (list : List[Any]) extends JSONType {
- override def toString = "[" + list.mkString(", ") + "]"
+ def toString (formatter : JSONFormat.ValueFormatter) =
+ "[" + list.map(formatter).mkString(", ") + "]"
}
/**