8000 GitHub - cladam/json: JSON library for the hica ecosystem · GitHub
[go: up one dir, main page]

Skip to content
cladamPublic

About

JSON library for the hica ecosystem

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

18 Commits

Folders and files

Repository files navigation

json

A JSON parser and serializer library for hica. Parses any valid JSON and provides a pipe-friendly API for navigating and extracting values.

Installation

1. Add the package

hica add json
hica fetch

This records the dependency in hica.hml and downloads the package.

2. Import

import "json"

Supported JSON

  • Null: null
  • Booleans: true, false
  • Numbers: integers (42, -7) and floats (3.14, -3.14, 1e10, 1.5e-2)
    • Integer tokens (no . or exponent) parse as JInt and emit without a decimal point
    • Float tokens parse as JNumber and emit with the shortest round-trip decimal
  • Strings: double-quoted with escape sequences (\", \\, \n, \r, \t, \uXXXX)
  • Arrays: [1, "two", true], nested, trailing whitespace
  • Objects: {"key": value}, nested, any JSON value as field value
  • Whitespace: ignored between tokens

API

Types

type Json {
  JNull,
  JBool(value: bool),
  JInt(value: int),
  JNumber(value: float),
  JString(value: string),
  JArray(value: list<Json>),
  JObject(fields: list<(string, Json)>)
}

Use JInt when constructing integer values so they serialise without a decimal point (7 not 7.0). JNumber is for values that are genuinely floating-point.

Parsing

parse_json(input: string) : result<Json, string>

Pipe-friendly navigation

Chain operations with |> or . to navigate nested JSON:

let host = parse_json(input)
  |> json_ok
  |> at("database")
  |> at("host")
  |> as_str

// host : maybe<string>

Hica supports Uniform Function Call Syntax (UFCS), so you can also write:

let host = parse_json(input)
  .json_ok
  .at("database")
  .at("host")
  .as_str
Function Signature Purpose
json_ok result<Json, string> -> maybe<Json> Convert parse result to maybe
at maybe<Json>, string -> maybe<Json> Navigate into an object field
nth maybe<Json>, int -> maybe<Json> Index into an array
as_str maybe<Json> -> maybe<string> Extract string value
as_int maybe<Json> -> maybe<int> Extract int value (truncates float)
as_num maybe<Json> -> maybe<float> Extract number as float
as_bool maybe<Json> -> maybe<bool> Extract bool value
as_array maybe<Json> -> maybe<list<Json>> Extract array items
as_object maybe<Json> -> maybe<list<(string, Json)>> Extract object fields

Defaults

let port = parse_json(input)
  |> json_ok
  |> at("server")
  |> at("port")
let p = int_or(port, 8080)
Function Signature
str_or maybe<Json>, string -> string
int_or maybe<Json>, int -> int
num_or maybe<Json>, float -> float
bool_or maybe<Json>, bool -> bool

Inspection

Function Signature Purpose
has_key maybe<Json>, string -> bool Check if object has field
keys maybe<Json> -> list<string> Get object field names
json_length maybe<Json> -> int Count array items or object fields

Direct accessors

For when you already have a Json value (not wrapped in maybe):

Function Signature
json_get Json, string -> maybe<Json>
json_str Json -> maybe<string>
json_int Json -> maybe<int>
json_num Json -> maybe<float>
json_bool Json -> maybe<bool>
json_array Json -> maybe<list<Json>>
json_object Json -> maybe<list<(string, Json)>>
json_is_null Json -> bool

Display

json_show(j: Json) : string                  // compact one-line (type summary for containers)
json_pretty(j: Json, indent: int) : string   // indented multi-line output

Serialization

Emit compact JSON from Json values:

json_emit(j: Json) : string   // compact single-line JSON

Example:

let data = JObject([("name", JString("myapp")), ("port", JInt(8080))])
println(json_emit(data))
// {"name": "myapp", "port": 8080}

println(json_pretty(data, 0))
// {
//   "name": "myapp",
//   "port": 8080
// }

Using with the HTTP library

The two core patterns when combining JSON with the hica HTTP library:

GET → parse → navigate

extern import "http"
import "./lib/json/src/json"

let resp = http_get("https://api.example.com/users/1")
match parse_json(resp.body) {
  Ok(doc) => {
    let name = Some(doc) |> at("name") |> as_str
    println(str_or(name, "<no name>"))
  },
  Err(e) => println("error: " + e)
}

Build JSON → json_emit → POST

let payload = JObject([
  ("name",  JString("Alice")),
  ("age",   JInt(30)),
  ("admin", JBool(false))
])

let post_resp = http_post(
  "https://api.example.com/users",
  json_emit(payload),
  content_type="application/json"
)
println("Status: " + show(post_resp.status))

See examples/http_json.hc for a full working example with both patterns.

Examples

See the examples/ directory for runnable programs:

Run an example:

hica run examples/basic_parsing.hc

About

JSON library for the hica ecosystem

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

0