module json

module lib/json.mu

import "json"

json provides a collection of JSON encoding and decoding functions.

Imports

Functions

decode#

fn decode(text)

decode parses JSON text into mu values, rejecting trailing data.

Source lib/json.mu:199
fn decode(text) {
  if !typing.is_str(text) {
    return error("json.decode expects string text, got " + type(text))
  }
  startIdx := _skip_whitespace(text, 0)
  parsed := _parse_value(text, startIdx)
  if is_error(parsed) {
    return parsed
  }
  value := parsed[0]
  idx := parsed[1]
  idx = _skip_whitespace(text, idx)
  if idx != len(text) {
    return error("json.decode: unexpected characters")
  }
  return value
}

encode#

fn encode(value)

encode serializes primitives, decimals, lists, and maps into compact JSON text.

Source lib/json.mu:10
fn encode(value) {
  typ := type(value)
  if typ == "STRING" {
    return escape_string(value)
  }
  if typ == "INTEGER" {
    return inspect(value)
  }
  if typ == "Decimal" {
    return value.str()
  }
  if typ == "BOOLEAN" {
    if value {
      return "true"
    }
    return "false"
  }
  if typ == "NULL" {
    return "null"
  }
  if typ == "LIST" {
    return _encode_list(value)
  }
  if typ == "MAP" {
    return _encode_map(value)
  }
  return error("json.encode unsupported type " + typ)
}

escape_string#

fn escape_string(value)

escape_string returns a quoted, backslash-escaped JSON string.

Source lib/json.mu:104
fn escape_string(value) {
  out := "\""
  i := 0
  total := len(value)
  while i < total {
    ch := value[i]
    if ch == "\"" {
      out = out + "\\\""
    } else if ch == "\\" {
      out = out + "\\\\"
    } else if ch == chr(8) {
      out = out + "\\b"
    } else if ch == chr(12) {
      out = out + "\\f"
    } else if ch == "\n" {
      out = out + "\\n"
    } else if ch == "\r" {
      out = out + "\\r"
    } else if ch == "\t" {
      out = out + "\\t"
    } else {
      code := ord(ch)
      if code < 32 {
        out = out + "\\u00" + encoding.hex_digit((code >> 4) & 15, true) + encoding.hex_digit(code & 15, true)
      } else {
        out = out + ch
      }
    }
    i = i + 1
  }
  return out + "\""
}

pretty#

fn pretty(value)

pretty emits JSON text with indentation for readability.

Source lib/json.mu:138
fn pretty(value) {
  return _encode_pretty(value, 0)
}

Internal helpers

Underscore-prefixed names are implementation detail. They are listed so the module's source reads without surprises, not as API — they may change at any time.

_encode_list(arr)_encode_list produces a compact JSON array text for arr.
_encode_map(m)_encode_map serializes a map using string keys sorted for deterministic output.
_encode_pretty(value, indent)_encode_pretty recursively formats value with the given indent depth.
_integer_digit_value(ch)_integer_digit_value enforces valid base-10 digits.
_is_nonzero_digit(ch)_is_nonzero_digit reports whether ch is 1..9.
_json_simple_escape(ch)_json_simple_escape maps single-character escape codes to their literal characters.
_literal_matches(text, idx, literal)_literal_matches ensures the literal occurs at idx and is not part of a longer token.
_parse_array(text, idx)_parse_array reads a JSON array starting at idx and returns the array plus next index.
_parse_integer(text)_parse_integer parses a base-10 integer with an optional leading '-'.
_parse_number(text, idx)_parse_number consumes a strict JSON number.
_parse_object(text, idx)_parse_object reads a JSON object starting after the opening brace.
_parse_string(text, start)_parse_string consumes a quoted string, handling escapes, and returns value+next index.
_parse_unicode_escape(text, start)_parse_unicode_escape reads a \uXXXX escape and returns the decoded rune plus next index.
_parse_value(text, idx)_parse_value routes to the parser that matches the next JSON token.
_skip_whitespace(text, idx)_skip_whitespace advances idx past spaces, tabs, and line terminators.
_string_keys_sorted(m)_string_keys_sorted validates that m has string keys and returns them sorted.