Skip to content

Json.Kind

Standard library enum · Nested in Json

Every JSON value is one of six kinds: null, true or false, a number, text, a list, or an object. Json.Kind names them, and a Json value’s kind says which one it is.

You need it when a program can’t know ahead of time what it will find, and has to decide what to do by looking. A case over the kind handles every possibility, and Emerald checks that none is left out:

func describe(value: Json): String {
return case value.kind {
when Json.Kind.null then "nothing"
when Json.Kind.bool then "true or false"
when Json.Kind.number then "a number"
when Json.Kind.string then "text"
when Json.Kind.list then "a list of #{value.count}"
when Json.Kind.object then "an object with #{value.count} keys"
}
}
print(describe(Json.parse('["new", "fast"]'))) # → a list of 2
print(describe(Json.parse("7"))) # → a number

When you already know what a value should be, you don’t need the kind: a conversion such as string() raises an error if the value isn’t text, and string_maybe() gives nothing.

Like any enum, a kind is written with its type’s name in front, Json.Kind.list, and prints the same way. Kinds can be compared with == and used as dictionary keys. They have no order, so < doesn’t apply to them.

Value JSON text Read it with
Json.Kind.null null null?()
Json.Kind.bool true, false bool()
Json.Kind.number 7, 2.5, -3e8 int(), float()
Json.Kind.string "Ada" string()
Json.Kind.list [1, 2, 3] list(), at(index)
Json.Kind.object {"name": "Ada"} object(), get(key)

Json.Kind.null

JSON’s null, which a document uses to say that something has no value. It is still a value in the document, unlike a key that isn’t there at all.

Json.parse("null").kind # → Json.Kind.null

Json.Kind.bool

true or false.

Json.parse("true").kind # → Json.Kind.bool

Json.Kind.number

Any number. JSON has only one kind of number, so a whole number and a fraction are both number. int() reads a whole one as an Int, and float() reads any of them as a Float.

Json.parse("7").kind # → Json.Kind.number
Json.parse("2.5").kind # → Json.Kind.number

Json.Kind.string

Text, written in double quotes. Text that looks like a number is still text:

Json.parse('"Ada"').kind # → Json.Kind.string
Json.parse('"7"').kind # → Json.Kind.string

Json.Kind.list

A list of values in square brackets. The values can be of any kinds, mixed together.

Json.parse('[1, "two", null]').kind # → Json.Kind.list

Json.Kind.object

Keys paired with values, in braces. Each key is text.

Json.parse('{"name": "Ada"}').kind # → Json.Kind.object

A case that produces a value, like describe above, must cover all six kinds, or the program won’t run. A case statement that runs blocks may leave some out, but Emerald warns about it, so a kind isn’t forgotten by accident. Add else { } to say that the rest are deliberately left alone:

const value = Json.parse("[1, 2]")
case value.kind {
when Json.Kind.list {
print("#{value.count} items")
}
else { }
}