X-Git-Url: http://nitlanguage.org diff --git a/lib/json/static.nit b/lib/json/static.nit index 67ae0db..12dbc7c 100644 --- a/lib/json/static.nit +++ b/lib/json/static.nit @@ -30,18 +30,38 @@ private import json_lexer # Something that can be translated to JSON. interface Jsonable # Encode `self` in JSON. + # + # SEE: `append_json` fun to_json: String is abstract + + # Use `append_json` to implement `to_json`. + # + # Therefore, one that redefine `append_json` may use the following + # redefinition to link `to_json` and `append_json`: + # + # ~~~nitish + # redef fun to_json do return to_json_by_append + # ~~~ + # + # Note: This is not the default implementation of `to_json` in order to + # avoid cyclic references between `append_json` and `to_json` when none are + # implemented. + protected fun to_json_by_append: String do + var buffer = new RopeBuffer + append_json(buffer) + return buffer.write_to_string + end + + # Append the JSON representation of `self` to the specified buffer. + # + # SEE: `to_json` + fun append_json(buffer: Buffer) do buffer.append(to_json) end redef class Text super Jsonable - # Encode `self` in JSON. - # - # assert "\t\"http://example.com\"\r\n\0\\".to_json == - # "\"\\t\\\"http:\\/\\/example.com\\\"\\r\\n\\u0000\\\\\"" - redef fun to_json do - var buffer = new FlatBuffer + redef fun append_json(buffer) do buffer.add '\"' for i in [0..self.length[ do var char = self[i] @@ -72,9 +92,45 @@ redef class Text end end buffer.add '\"' - return buffer.write_to_string end + # Encode `self` in JSON. + # + # assert "\t\"http://example.com\"\r\n\0\\".to_json == + # "\"\\t\\\"http:\\/\\/example.com\\\"\\r\\n\\u0000\\\\\"" + redef fun to_json do return to_json_by_append + + # Parse `self` as JSON. + # + # If `self` is not a valid JSON document or contains an unsupported escape + # sequence, return a `JSONParseError`. + # + # Example with `JsonObject`: + # + # var obj = "\{\"foo\": \{\"bar\": true, \"goo\": [1, 2, 3]\}\}".parse_json + # assert obj isa JsonObject + # assert obj["foo"] isa JsonObject + # assert obj["foo"].as(JsonObject)["bar"] == true + # + # Example with `JsonArray`: + # + # var arr = "[1, 2, 3]".parse_json + # assert arr isa JsonArray + # assert arr.length == 3 + # assert arr.first == 1 + # assert arr.last == 3 + # + # Example with `String`: + # + # var str = "\"foo, bar, baz\"".parse_json + # assert str isa String + # assert str == "foo, bar, baz" + # + # Example of a syntaxic error: + # + # var bad = "\{foo: \"bar\"\}".parse_json + # assert bad isa JsonParseError + # assert bad.position.col_start == 2 fun parse_json: nullable Jsonable do var lexer = new Lexer_json(to_s) var parser = new Parser_json @@ -145,16 +201,7 @@ interface JsonMapRead[K: String, V: nullable Jsonable] super MapRead[K, V] super Jsonable - # Encode `self` in JSON. - # - # var obj = new JsonObject - # obj["foo"] = "bar" - # assert obj.to_json == "\{\"foo\":\"bar\"\}" - # obj = new JsonObject - # obj["baz"] = null - # assert obj.to_json == "\{\"baz\":null\}" - redef fun to_json do - var buffer = new FlatBuffer + redef fun append_json(buffer) do buffer.append "\{" var it = iterator if it.is_ok then @@ -166,9 +213,18 @@ interface JsonMapRead[K: String, V: nullable Jsonable] end it.finish buffer.append "\}" - return buffer.write_to_string end + # Encode `self` in JSON. + # + # var obj = new JsonObject + # obj["foo"] = "bar" + # assert obj.to_json == "\{\"foo\":\"bar\"\}" + # obj = new JsonObject + # obj["baz"] = null + # assert obj.to_json == "\{\"baz\":null\}" + redef fun to_json do return to_json_by_append + private fun append_json_entry(iterator: MapIterator[String, nullable Jsonable], buffer: Buffer) do buffer.append iterator.key.to_json @@ -189,16 +245,7 @@ class JsonSequenceRead[E: nullable Jsonable] super Jsonable super SequenceRead[E] - # Encode `self` in JSON. - # - # var arr = new JsonArray.with_items("foo", null) - # assert arr.to_json == "[\"foo\",null]" - # arr.pop - # assert arr.to_json =="[\"foo\"]" - # arr.pop - # assert arr.to_json =="[]" - redef fun to_json do - var buffer = new FlatBuffer + redef fun append_json(buffer) do buffer.append "[" var it = iterator if it.is_ok then @@ -210,9 +257,18 @@ class JsonSequenceRead[E: nullable Jsonable] end it.finish buffer.append "]" - return buffer.write_to_string end + # Encode `self` in JSON. + # + # var arr = new JsonArray.with_items("foo", null) + # assert arr.to_json == "[\"foo\",null]" + # arr.pop + # assert arr.to_json =="[\"foo\"]" + # arr.pop + # assert arr.to_json =="[]" + redef fun to_json do return to_json_by_append + private fun append_json_entry(iterator: Iterator[nullable Jsonable], buffer: Buffer) do buffer.append_json_of(iterator.item) @@ -267,7 +323,8 @@ end # Redef parser redef class Nvalue - fun to_nit_object: nullable Jsonable is abstract + # The represented value. + private fun to_nit_object: nullable Jsonable is abstract end redef class Nvalue_number @@ -296,7 +353,8 @@ redef class Nvalue_null end redef class Nstring - fun to_nit_string: String do + # The represented string. + private fun to_nit_string: String do var res = new FlatBuffer var i = 1 while i < text.length - 1 do @@ -346,7 +404,8 @@ redef class Nvalue_object end redef class Nmembers - fun pairs: Array[Npair] is abstract + # All the key-value pairs. + private fun pairs: Array[Npair] is abstract end redef class Nmembers_tail @@ -363,8 +422,11 @@ redef class Nmembers_head end redef class Npair - fun name: String do return n_string.to_nit_string - fun value: nullable Jsonable do return n_value.to_nit_object + # The represented key. + private fun name: String do return n_string.to_nit_string + + # The represented value. + private fun value: nullable Jsonable do return n_value.to_nit_object end redef class Nvalue_array @@ -381,7 +443,8 @@ redef class Nvalue_array end redef class Nelements - fun items: Array[Nvalue] is abstract + # All the items. + private fun items: Array[Nvalue] is abstract end redef class Nelements_tail