jbe/bsw@0: --[[-- jbe/bsw@0: json_string = -- JavaScript code representing the given datum (with quotes, if needed) jbe/bsw@0: encode.json( jbe/bsw@0: obj -- true, false, nil or a number or string jbe/bsw@0: ) jbe/bsw@0: jbe/bsw@0: This function encodes any native datatype or atom in JavaScript object notation (JSON). jbe@1: TODO: can't distinguish unambiguously between empty object and empty list! jbe/bsw@0: jbe/bsw@0: --]]-- jbe/bsw@0: jbe@1: -- TODO: check if numeric representations are JSON compatible jbe@1: jbe/bsw@0: function encode.json(obj) jbe/bsw@0: if obj == nil then jbe/bsw@0: return "null"; jbe/bsw@0: elseif atom.has_type(obj, atom.boolean) then jbe/bsw@0: return tostring(obj) jbe/bsw@0: elseif atom.has_type(obj, atom.number) then jbe/bsw@0: return tostring(obj) jbe@1: elseif type(obj) == "table" then jbe@1: local parts = {} jbe@1: local first = true jbe@1: if #obj > 0 then jbe@1: parts[#parts+1] = "[" jbe@1: for idx, value in ipairs(obj) do jbe@1: if first then jbe@1: first = false jbe@1: else jbe@1: parts[#parts+1] = "," jbe@1: end jbe@1: parts[#parts+1] = tostring(value) jbe@1: end jbe@1: parts[#parts+1] = "]" jbe@1: else jbe@1: parts[#parts+1] = "{" jbe@1: for key, value in pairs(obj) do jbe@1: if first then jbe@1: first = false jbe@1: else jbe@1: parts[#parts+1] = "," jbe@1: end jbe@1: parts[#parts+1] = encode.json(key) jbe@1: parts[#parts+1] = ":" jbe@1: parts[#parts+1] = encode.json(value) jbe@1: end jbe@1: parts[#parts+1] = "}" jbe@1: end jbe@1: return table.concat(parts) jbe/bsw@0: else jbe/bsw@0: return jbe@1: '"' .. jbe/bsw@0: string.gsub(atom.dump(obj), ".", jbe/bsw@0: function (char) jbe@1: if char == '\r' then return '\\r' end jbe@1: if char == '\n' then return '\\n' end jbe@1: if char == '\\' then return '\\\\' end jbe@1: if char == '"' then return '\\"' end jbe@1: if char == '/' then return '\\/' end -- allowed according to RFC4627, needed for jbe/bsw@0: local byte = string.byte(char) jbe/bsw@0: if byte < 32 then return string.format("\\u%04x", byte) end jbe/bsw@0: end jbe/bsw@0: ) .. jbe@1: '"' jbe/bsw@0: end jbe/bsw@0: end