changeset 271:bb4723fec05e

Support for encoding objects, dictionaries, lists and arrays to JSON in json module
author Michael Pavone <pavone@retrodev.com>
date Sat, 19 Jul 2014 19:59:51 -0700
parents b74956a2196f
children bb2b4613fdc8
files modules/array.tp modules/dict.tp modules/json.tp modules/list.tp modules/string.tp
diffstat 5 files changed, 86 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/modules/array.tp	Fri Jul 18 20:45:50 2014 -0700
+++ b/modules/array.tp	Sat Jul 19 19:59:51 2014 -0700
@@ -144,4 +144,9 @@
 			""
 		}
 	}
+
+	jsonEncode <- {
+		parts <- map: :el { json encode: el }
+		"[" . (parts join: ",") . "]"
+	}
 }
--- a/modules/dict.tp	Fri Jul 18 20:45:50 2014 -0700
+++ b/modules/dict.tp	Sat Jul 19 19:59:51 2014 -0700
@@ -1,4 +1,12 @@
 {
+	_jsonEncode <- :dict {
+		parts <- #[]
+		foreach: dict :key val {
+			//TODO: escape field names
+			parts append: (key jsonEncode) . ":" . (json encode: val)
+		}
+		"{" . (parts join: ",") . "}"
+	}
 	linearWithEls <- :els {
 		key:val <- :k v {
 			#{
@@ -77,6 +85,10 @@
 			}
 
 			length <- { els length }
+
+			jsonEncode <- {
+				_jsonEncode: self
+			}
 		}
 	}
 	_empty <- #{
@@ -202,6 +214,10 @@
 						}
 					}
 				}
+
+				jsonEncode <- {
+					_jsonEncode: self
+				}
 			}
 		}
 
--- a/modules/json.tp	Fri Jul 18 20:45:50 2014 -0700
+++ b/modules/json.tp	Sat Jul 19 19:59:51 2014 -0700
@@ -163,5 +163,35 @@
 		decode <- :text {
 			(_decode: text at: 0) value
 		}
+
+		encode <- :value {
+			if: (object does: value understand?: "jsonEncode") {
+				value jsonEncode
+			} else: {
+				toEncode <- #[]
+				if: (object does: value understand?: "serializeFields") {
+					toEncode <- value serializeFields
+				} else: {
+					toEncode <- object propertiesOf: value
+				}
+				parts <- #[]
+				foreach: toEncode :idx field {
+					fieldVal <- object sendMessage: field to: value
+					parts append: (field jsonEncode) . ":" . (encode: fieldVal)
+				}
+				"{" . (parts join: ",") . "}"
+			}
+		}
+
+		main <- {
+			o <- #{
+				foo <- "bar"
+				baz <- ["fizz" "buzz" "buzzzz"]
+				qux <- ((dict hash) set: "fo" "shizzle") set: "my" "nizzle"
+				arr <- #["pirate" "booty"]
+			}
+			print: (encode: o) . "\n"
+			0
+		}
 	}
 }
--- a/modules/list.tp	Fri Jul 18 20:45:50 2014 -0700
+++ b/modules/list.tp	Sat Jul 19 19:59:51 2014 -0700
@@ -14,6 +14,7 @@
 		contains? <- :val { false }
 		string <- { "[]" }
 		print <- { print: string }
+		jsonEncode <- { "[]" }
 	}
 	#{
 		empty <- { _empty }
@@ -83,6 +84,11 @@
 					}
 					print: "]"
 				}
+
+				jsonEncode <- {
+					parts <- map: :el { json encode: el }
+					"[" . (parts join: ",") . "]"
+				}
 			}
 		}
 	}
--- a/modules/string.tp	Fri Jul 18 20:45:50 2014 -0700
+++ b/modules/string.tp	Sat Jul 19 19:59:51 2014 -0700
@@ -310,6 +310,35 @@
 		}
 	}
 
+	jsonEncode <- {
+		i <- 0
+		start <- 0
+		parts <- #["\""]
+		q <- "\"" byte: 0
+		s <- "\\" byte: 0
+		while: { i < byte_length } do: {
+			b <- byte: i
+			if: b = q {
+				parts append: (from: start withLength: i - start)
+				start <- i + 1
+				parts append: "\\\""
+			} else: {
+				if: b = s {
+					parts append: (from: start withLength: i - start)
+					start <- i + 1
+					parts append: "\\\\"
+				}
+			}
+
+			i <- i + 1
+		}
+		if: start < byte_length {
+			parts append: (from: start)
+		}
+		parts append: "\""
+		parts join: ""
+	}
+
 	isInteger? <- { false }
 	isString? <- { true }
 	isBasicString? <- { true }