Skip to content

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 →