1--[[ 2 Licensed according to the included 'LICENSE' document 3 Author: Thomas Harning Jr <harningt@gmail.com> 4]] 5local pairs = pairs 6local assert = assert 7 8local type = type 9local tostring = tostring 10 11local table_concat = require("table").concat 12local jsonutil = require("json.util") 13 14local _ENV = nil 15 16local defaultOptions = { 17} 18 19local modeOptions = {} 20 21local function mergeOptions(options, mode) 22 jsonutil.doOptionMerge(options, false, 'object', defaultOptions, mode and modeOptions[mode]) 23end 24 25--[[ 26 Cleanup function to unmark a value as in the encoding process and return 27 trailing results 28]] 29local function unmarkAfterEncode(tab, state, ...) 30 state.already_encoded[tab] = nil 31 return ... 32end 33--[[ 34 Encode a table as a JSON Object ( keys = strings, values = anything else ) 35]] 36local function encodeTable(tab, options, state) 37 -- Make sure this value hasn't been encoded yet 38 state.check_unique(tab) 39 local encode = state.encode 40 local compositeEncoder = state.outputEncoder.composite 41 local valueEncoder = [[ 42 local first = true 43 for k, v in pairs(composite) do 44 local ti = type(k) 45 assert(ti == 'string' or ti == 'number' or ti == 'boolean', "Invalid object index type: " .. ti) 46 local name = encode(tostring(k), state, true) 47 if first then 48 first = false 49 else 50 name = ',' .. name 51 end 52 PUTVALUE(name .. ':') 53 local val = encode(v, state) 54 val = val or '' 55 if val then 56 PUTVALUE(val) 57 end 58 end 59 ]] 60 return unmarkAfterEncode(tab, state, compositeEncoder(valueEncoder, '{', '}', nil, tab, encode, state)) 61end 62 63local function getEncoder(options) 64 options = options and jsonutil.merge({}, defaultOptions, options) or defaultOptions 65 return { 66 table = function(tab, state) 67 return encodeTable(tab, options, state) 68 end 69 } 70end 71 72local object = { 73 mergeOptions = mergeOptions, 74 getEncoder = getEncoder 75} 76 77return object 78