Json — Type-Safe JSON with Try

GALA’s Json module wraps Go’s encoding/json with type safety. All operations return Try[T] — no unchecked errors, no forgotten if err != nil. Combined with pattern matching, you get a clean, composable JSON pipeline.

import . "martianoff/gala/std"

Serialization

type Person struct {
    var Name string
    var Age  int
}

val person = Person{Name: "Alice", Age: 30}

// Compact JSON
val jsonStr = JsonStringify(person).Get()
// => {"Name":"Alice","Age":30}

// Pretty-printed JSON
val pretty = JsonStringifyPretty(person).Get()
// => {
//   "Name": "Alice",
//   "Age": 30
// }

Deserialization

val parsed = JsonParse[Person](jsonStr)
// parsed: Try[Person]

// Safe access via Map
val name = parsed.Map((p) => p.Name).GetOrElse("unknown")

// Side effect on success
parsed.ForEach((p) => {
    Println(s"Parsed: ${p.Name}, age ${p.Age}")
})

Invalid JSON returns Failure instead of panicking:

val bad = JsonParse[Person]("invalid json")
Println(bad.IsFailure())  // true

Pattern Matching with Json[T]

The Json[T] extractor parses JSON strings directly inside match expressions. If parsing fails, the case does not match — no exception, no panic:

val result = jsonStr match {
    case Json[Person](p) => s"Found: ${p.Name}, age ${p.Age}"
    case _ => "invalid JSON"
}

This is especially useful when handling input from external sources:

func handleMessage(raw string) string = raw match {
    case Json[Command](cmd) => processCommand(cmd)
    case Json[Event](evt)   => processEvent(evt)
    case _                  => "unknown message format"
}

The Json[T] extractor calls Unapply under the hood, returning Some[T] on success and None on failure — the same pattern used by sealed types and regex extractors.


Chaining with Try

Because JsonParse returns Try[T], you can chain operations without intermediate error checks:

val greeting = JsonParse[Person](input)
    .Map((p) => p.Name)
    .Map((name) => s"Hello, $name!")
    .GetOrElse("Hello, stranger!")

Convert to other monadic types:

val opt = JsonParse[Person](input).ToOption()     // Option[Person]
val either = JsonParse[Person](input).ToEither()  // Either[error, Person]

API Reference

Function Signature Description
JsonParse[T](data) string → Try[T] Deserialize JSON string to T
JsonStringify[T](value) T → Try[string] Serialize value to JSON string
JsonStringifyPretty[T](value) T → Try[string] Serialize to pretty-printed JSON
Json[T].Unapply(s) string → Option[T] Pattern matching extractor

Further Reading