Aiming for Jarvis, Creating D.A.N.I.

Tutorial 12: JSON (or, How to handle the internet's favourite data format)

If you've been around the block, you know the drill: JSON is everywhere. It’s the duct tape of the modern web. It’s not particularly elegant, it’s not particularly fast, but it’s the universal language for moving data from point A to point B. In Skink, we use std/json to wrangle this mess.

Parsing JSON: The "Unmarshal" adventure

When you get a blob of JSON, it’s just a string until you tell the machine what it actually is. We use Unmarshal to turn that raw text into a Value—our internal, dynamic representation of the data.

module main

import "std/json"

fn main() -> int {
    raw := "{\"name\":\"skink\",\"version\":1.5}"
    
    v, err := json.Unmarshal(raw)
    if err.message != "" {
        print("The JSON was a lie: {err.String()}")
        return 1
    }

    // We have to be explicit about what we expect the data to be
    name := json.AsString(json.ObjectGet(v, "name"))
    version := json.AsNumber(json.ObjectGet(v, "version"))

    print("{name} v{version}")
    return 0
}

Pro-tip: Never assume the JSON you receive is actually what you asked for. The internet is a wild place, and people will send you all sorts of garbage. Validate everything.

Building JSON: Making the bread

When you need to send data out—maybe telling a remote sensor that it's time to wake up—you need to build that JSON string. It’s a bit more manual than parsing, but it keeps things type-safe and prevents those "I forgot a curly brace" catastrophes.

// Let's create an object representation
v := json.FromObject(
    ["name", "version"],
    [json.FromString("skink"), json.FromNumber(1.5)],
)

// Now turn it into the string the internet wants
text := json.MarshalValue(v)
print(text)

Arrays: The simple list

If you’re just pushing a list of numbers or strings, arrays are straightforward.

arr := json.FromArray([json.FromNumber(1.0), json.FromNumber(2.0)])
print(json.MarshalValue(arr))

Exercises

Don't let the data formatting get the best of you—try these out:

  1. The Array Walker: Parse a JSON array of numbers and print each one using json.ArrayGet and json.AsNumber. If you can't figure out the length, check the json module docs.
  2. The User Object: Build a JSON object representing a user with name and age fields. Then, marshal it and print the result.
  3. The File-to-JSON Pipeline: Read a small JSON file using the fs module from Tutorial 10, parse it with json.Unmarshal, and print one specific field. It's a classic real-world scenario.

Next

When you're ready to make sure your code actually works the way you think it does, we'll talk about Unit testing.