JSON Validator — Ruby source
Validate JSON and pinpoint errors with line and column numbers. Clear valid/invalid verdict plus the exact error location - runs entirely in your browser.
This is the Ruby implementation — the same logic the interactive tool runs, in a shareable, citable form.
# json-validator — Ruby port using the stdlib json gem, ported from src/lib/jsonValidate.ts.
require 'json'
module JsonValidator
POSITION = /at position (\d+)/.freeze
module_function
# 1-based [line, column] for a 0-based char offset; "\n", a lone "\r" and
# "\r\n" each count as one break — the algorithm shared by every port.
def offset_to_line_col(text, offset)
line = column = 1
i = 0
while i < offset && i < text.length
case text[i]
when "\n" then line += 1; column = 1
when "\r" then line += 1; column = 1; i += 1 if text[i + 1] == "\n"
else column += 1
end
i += 1
end
[line, column]
end
# Best-effort parity with the JS port: when an engine message embeds
# "at position N", map it to a location; otherwise the location is nil.
def locate_error(text, message)
m = POSITION.match(message)
m ? offset_to_line_col(text, m[1].to_i) : [nil, nil]
end
# Validate JSON. Never raises. Mirrors validateJson in jsonValidate.ts.
def validate_json(text)
if !text.is_a?(String) || text.strip.empty?
return { valid: false, error: 'Input is empty', line: nil, column: nil }
end
JSON.parse(text) # raises on malformed input; the decoded value is not needed
{ valid: true, error: nil, line: nil, column: nil }
rescue JSON::ParserError => e
# Ruby prefixes "JSON::ParserError:" — strip it the same way the JS port
# strips JavaScriptCore's "JSON Parse error:" prefix.
message = e.message.to_s.sub(/\AJSON::ParserError:\s*/, '')
line, column = locate_error(text, e.message.to_s)
{ valid: false, error: message, line: line, column: column }
end
end
# {"name": "Ada", "admin": true} is valid; a stray comma is not.
p JsonValidator.validate_json('{"name": "Ada", "admin": true}')
p JsonValidator.validate_json("{\n \"a\": ,\n}")
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →