diff options
author | Derek Chen-Beker <dchenbecker@gmail.com> | 2010-10-08 20:22:13 +0000 |
---|---|---|
committer | Derek Chen-Beker <dchenbecker@gmail.com> | 2010-10-08 20:22:13 +0000 |
commit | 908ed2f29f4dbe03bb2ff73341a74c524f44f964 (patch) | |
tree | 6e7ba5f87f82d0d9ecfd018de561127d5376cfb2 /src | |
parent | 4af97e33e7f60e61df1483af3605050a3af5dfb6 (diff) | |
download | scala-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.scala | 76 |
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(", ") + "]" } /** |