maria_json_parser

A pure MoonBit JSON parser with comprehensive parsing and serialization capabilities

json
parser
serialization
encoding
moon add tonyfettes/maria_json_parser@0.1.0
Download zip
Version
0.1.0
License
Apache-2.0
Last updated
9 months ago
Downloads
17
README

#Maria JSON Parser

A pure MoonBit JSON parser with comprehensive parsing and serialization capabilities.

#Features

  • Full JSON Support: Parse and serialize all JSON types (objects, arrays, strings, numbers, booleans, null)
  • Pretty Printing: Format JSON with customizable indentation
  • Error Handling: Detailed error reporting with position information
  • Unicode Support: Handle unicode escape sequences (\uXXXX)
  • Zero Dependencies: Built entirely with MoonBit standard library
  • Type Safe: Strongly typed JSON value representation

#Installation

Add to your moon.pkg.json:

{ "import": [ "tonyfettes/maria_json_parser" ] }

#Quick Start

#Parsing JSON

///|
test "parse basic json" {
let json_text = "{\"name\": \"Alice\", \"age\": 30}"
let value = @maria_json_parser.parse(json_text)
match value {
@maria_json_parser.JsonValue::Object(obj) => {
inspect(obj.get("name"), content="Some(String(\"Alice\"))")
inspect(obj.get("age"), content="Some(Number(30))")
}
_ => fail("Expected object")
}
}

#Serializing JSON

///|
test "serialize to json" {
let data : Map[String, @maria_json_parser.JsonValue] = {
"name": @maria_json_parser.JsonValue::String("Bob"),
"score": @maria_json_parser.JsonValue::Number(95.5),
"passed": @maria_json_parser.JsonValue::Boolean(true),
}
let json = @maria_json_parser.stringify(
@maria_json_parser.JsonValue::Object(data),
)
assert_true(json.contains("\"name\":\"Bob\""))
assert_true(json.contains("\"score\":95.5"))
}

#Pretty Printing

///|
test "pretty print json" {
let data : Map[String, @maria_json_parser.JsonValue] = {
"users": @maria_json_parser.JsonValue::Array([
@maria_json_parser.JsonValue::String("Alice"),
@maria_json_parser.JsonValue::String("Bob"),
]),
}
let pretty = @maria_json_parser.stringify(
@maria_json_parser.JsonValue::Object(data),
indent=2,
)
assert_true(pretty.contains("\n"))
assert_true(pretty.contains(" "))
}

#API Reference

#Types

#JsonValue

The main JSON value type:

///|
pub(all) enum JsonValue {
Object(Map[String, JsonValue])
Array(Array[JsonValue])
String(String)
Number(Double)
Boolean(Bool)
Null
}

#ParseError

Error type for parsing failures:

///|
pub(all) suberror ParseError {
UnexpectedToken(Position, Token, String)
UnexpectedChar(Position, Char)
UnexpectedEof(Position)
InvalidNumber(Position, String)
InvalidEscape(Position, Char)
InvalidUnicode(Position, String)
}

#Functions

#parse

Parse a JSON string into a JsonValue.

Function signature: pub fn parse(input : String) -> JsonValue raise ParseError

Example:

///|
test "parse example" {
let value = @maria_json_parser.parse("[1, 2, 3]")
match value {
@maria_json_parser.JsonValue::Array(arr) =>
inspect(arr.length(), content="3")
_ => fail("Expected array")
}
}

#stringify

Convert a JsonValue to a JSON string.

Function signature: pub fn stringify(value : JsonValue, indent? : Int = 0) -> String

Example:

///|
test "stringify example" {
let arr = @maria_json_parser.JsonValue::Array([
@maria_json_parser.JsonValue::Number(1.0),
@maria_json_parser.JsonValue::Number(2.0),
])
let json = @maria_json_parser.stringify(arr)
inspect(json, content="[1,2]")
}

#to_pretty_string

Convert a JsonValue to a pretty-printed JSON string (2-space indentation).

Function signature: pub fn JsonValue::to_pretty_string(self : JsonValue) -> String

Example:

///|
test "pretty string example" {
let obj : Map[String, @maria_json_parser.JsonValue] = {
"key": @maria_json_parser.JsonValue::String("value"),
}
let pretty = @maria_json_parser.JsonValue::Object(obj).to_pretty_string()
assert_true(pretty.contains("\n"))
}

#Error Handling

The parser provides detailed error information:

///|
test "handle parse errors" {
let result : Result[
@maria_json_parser.JsonValue,
@maria_json_parser.ParseError,
] = try! @maria_json_parser.parse("invalid")
match result {
Err(_error) =>
// Handle error - position and details available in error
inspect(true, content="true")
Ok(_) => fail("Expected error")
}
}

#Advanced Examples

#Complex Nested Structures

///|
test "complex structure" {
let json =
#|{
#| "user": {
#| "name": "Alice",
#| "settings": {
#| "theme": "dark",
#| "notifications": true
#| }
#| }
#|}
let value = @maria_json_parser.parse(json)
match value {
@maria_json_parser.JsonValue::Object(root) =>
match root.get("user") {
Some(@maria_json_parser.JsonValue::Object(user)) =>
match user.get("settings") {
Some(@maria_json_parser.JsonValue::Object(settings)) => {
inspect(settings.get("theme"), content="Some(String(\"dark\"))")
inspect(
settings.get("notifications"),
content="Some(Boolean(true))",
)
}
_ => fail("Expected settings object")
}
_ => fail("Expected user object")
}
_ => fail("Expected root object")
}
}

#Round-Trip Conversion

///|
test "round trip" {
let original = @maria_json_parser.JsonValue::Array([
@maria_json_parser.JsonValue::String("hello"),
@maria_json_parser.JsonValue::Number(42.0),
@maria_json_parser.JsonValue::Boolean(true),
@maria_json_parser.JsonValue::Null,
])
let json = @maria_json_parser.stringify(original)
let parsed = @maria_json_parser.parse(json)
inspect(parsed == original, content="true")
}

#Supported JSON Features

  • ✅ Objects with string keys
  • ✅ Arrays
  • ✅ Strings with escape sequences (\", \\, \/, \b, \f, \n, \r, \t)
  • ✅ Unicode escape sequences (\uXXXX)
  • ✅ Numbers (integers, decimals, scientific notation)
  • ✅ Booleans (true, false)
  • ✅ Null
  • ✅ Whitespace handling
  • ✅ Pretty printing with configurable indentation

#License

See LICENSE file in the project root.

#
ParseError

pub(all) suberror ParseError {
UnexpectedToken(Position, Token, String)
UnexpectedChar(Position, Char)
UnexpectedEof(Position)
InvalidNumber(Position, String)
InvalidEscape(Position, Char)
InvalidUnicode(Position, String)
}

Parser errors
impl Eq for ParseError
impl Show for ParseError

#
JsonValue

pub(all) enum JsonValue {
Object(Map[String, JsonValue])
Array(Array[JsonValue])
String(String)
Number(Double)
Boolean(Bool)
Null
}

JSON value representation
impl Eq for JsonValue
impl Show for JsonValue

#
JsonValue::to_pretty_string

fn JsonValue::to_pretty_string(self : JsonValue) -> String

Convert JsonValue to pretty-printed string

#
Position

type Position

Position in source for error reporting
impl Eq for Position
impl Show for Position

#
Token

type Token

Token types for JSON lexer
impl Eq for Token
impl Show for Token

#
parse

fn parse(input : String) -> JsonValue raise ParseError

Parse JSON string into a JsonValue

#
stringify

fn stringify(value : JsonValue, indent? : Int) -> String

Stringify a JsonValue with optional indentation