-- modules/json.lua - High-performance JSON module using Go functions local json = {} -- Use the fast Go JSON encoder/decoder function json.encode(value) return moonshark.json_encode(value) end function json.decode(str) local result, err = moonshark.json_decode(str) if result == nil and err then error("json_decode: " .. err) end return result end -- Pretty print JSON with indentation function json.pretty(value, indent) indent = indent or 2 local encoded = json.encode(value) local result = {} local depth = 0 local in_string = false local escape_next = false for i = 1, #encoded do local char = encoded:sub(i, i) if escape_next then table.insert(result, char) escape_next = false elseif char == "\\" and in_string then table.insert(result, char) escape_next = true elseif char == '"' then table.insert(result, char) in_string = not in_string elseif not in_string then if char == "{" or char == "[" then table.insert(result, char) depth = depth + 1 table.insert(result, "\n" .. string.rep(" ", depth * indent)) elseif char == "}" or char == "]" then depth = depth - 1 table.insert(result, "\n" .. string.rep(" ", depth * indent)) table.insert(result, char) elseif char == "," then table.insert(result, char) table.insert(result, "\n" .. string.rep(" ", depth * indent)) elseif char == ":" then table.insert(result, char .. " ") else table.insert(result, char) end else table.insert(result, char) end end return table.concat(result) end -- Load JSON from file function json.load_file(filename) if not moonshark.file_exists(filename) then error("File not found: " .. filename) end local file = io.open(filename, "r") if not file then error("Cannot open file: " .. filename) end local content = file:read("*all") file:close() return json.decode(content) end -- Save data to JSON file function json.save_file(filename, data, pretty) local content if pretty then content = json.pretty(data) else content = json.encode(data) end local file = io.open(filename, "w") if not file then error("Cannot write to file: " .. filename) end file:write(content) file:close() end -- Merge JSON objects function json.merge(...) local result = {} for i = 1, select("#", ...) do local obj = select(i, ...) if type(obj) == "table" then for k, v in pairs(obj) do result[k] = v end end end return result end -- Extract values by JSONPath-like syntax (simplified) function json.extract(data, path) local parts = moonshark.string_split(path, ".") local current = data for _, part in ipairs(parts) do if type(current) ~= "table" then return nil end -- Handle array indices [0], [1], etc. local array_match = part:match("^%[(%d+)%]$") if array_match then local index = tonumber(array_match) + 1 -- Lua is 1-indexed current = current[index] else current = current[part] end if current == nil then return nil end end return current end -- Validate JSON structure against schema (basic) function json.validate(data, schema) local function validate_value(value, schema_value) local value_type = type(value) local schema_type = schema_value.type if schema_type and value_type ~= schema_type then return false, "Expected " .. schema_type .. ", got " .. value_type end if schema_type == "table" and schema_value.properties then for prop, prop_schema in pairs(schema_value.properties) do if schema_value.required and schema_value.required[prop] and value[prop] == nil then return false, "Missing required property: " .. prop end if value[prop] ~= nil then local valid, err = validate_value(value[prop], prop_schema) if not valid then return false, "Property " .. prop .. ": " .. err end end end end return true end return validate_value(data, schema) end return json