Rand Stats

SION

zef:dankogai

CI

NAME

SION - a serialization format a little more expressive than JSON

SYNOPSIS

use SION;    # exports to-sion() and from-sion()

my $data = from-sion($sion-text);    # Str or utf-8 Blob
my $sion = to-sion($data);

# options, a la JSON::Fast
my $sion = to-sion($data, :pretty, :sorted-keys);

DESCRIPTION

SION is a data serialization format whose origin is Swift literals, just like JSON's origin is JavaScript literals. It is a little more expressive than JSON:

[
    "nil":      nil,                // nil is allowed
    "bool":     true,
    "int":      -42,                // Int is distinguished from Double
    "double":   0x1.518f5c28f5c29p+5,   // C99 hexadecimal notation
    "string":   "漢字、カタカナ、ひらがなの入ったstring😇",
    "array":    [nil, true, 1, 1.0, "one", [1], ["one":1.0]],
    "dictionary": ["nil":nil, "array":[], "object":[:]],
    "data":     .Data("R0lGODlh"),  // binary data in Base64
    "date":     .Date(0x0p+0),      // date in seconds since epoch
    "ext":      .Ext("1NTU"),       // msgpack-style extension
    1:          "non-string keys are also allowed", // comments, too!
]

This module implements a SION encoder/decoder for Raku. It is standalone — no dependency on other modules.

MAPPING

Raku is expressive enough that almost every SION type maps to a native Raku type:

SIONRaku
nilAny (undefined)
true/falseBool
IntInt
DoubleNum
StringStr
DataBlob
DateDateTime (fractional epoch preserved)
ExtSION::Ext
ArrayArray
DictionaryHash (object hash for non-Str keys)

Int vs Double

Int and Num are distinct types in Raku, so the distinction round-trips with no scalar-flag tricks: 1 encodes to 1 while 1e0 encodes to 0x1p+0. Nums are always encoded in C99 hexadecimal floating point notation, which is lossless; nan, inf and -inf are also supported. Rat and other Reals encode as Double.

String vs Data

A Str is text and a Blob is binary, so no heuristics are needed: Str encodes as a SION String while any Blob (including buf8) encodes as .Data("…") in Base64, and vice versa on decoding.

dates

.Date(n)n being seconds since epoch, possibly fractional — decodes to a DateTime, and DateTime, Instant and Date all encode as .Date(…). The fractional part survives the round trip: .Date(0x1p-1) is DateTime.new(Instant.from-posix(0.5)).

dictionaries

SION allows any value as a Dictionary key. When every key is a Str, from-sion returns an ordinary Hash; otherwise it returns an object hash, so from-sion('[1:"one"]'){1} works and the Int-ness of the key is preserved — no stringification.

FUNCTIONS

from-sion

my $data = from-sion($sion);                 # Str
my $data = from-sion($octets);               # utf-8 encoded Blob
my $data = from-sion($sion, :max-depth(64));

Decodes SION text to a Raku data structure. Dies on malformed input with the character offset of the error. :max-depth (default 512) bounds the nesting level.

to-sion

my $sion = to-sion($data);
my $sion = to-sion($data, :pretty);       # multi-line, indented by 4
my $sion = to-sion($data, :sorted-keys);  # deterministic dictionaries
my $sion = to-sion($data, :ascii);        # non-ASCII as \uXXXX escapes
my $sion = to-sion($data, :max-depth(64));

Encodes a Raku data structure to SION text. Compact by default; :sorted-keys sorts dictionary entries by their encoded keys so the output is deterministic (and a fixed point of to-sion(from-sion($_), :sorted-keys)).

HELPER CLASSES

SION::Ext

my $ext = SION::Ext.new($blob);   # encodes to .Ext("base64")
$ext.data;                        # the Blob payload

msgpack-style extension. It is a value type: two SION::Ext objects with the same payload are eqv.

HEXADECIMAL FLOATING POINT

SION serializes Double in C99 hexfloat notation (0x1.518f5c28f5c29p+5) because it is exact. Rakudo is gaining native support for it — sprintf '%a' landed for v6.e in rakudo/rakudo#6525 — but this module does not require it: it probes at load time and falls back to a pure-Raku encoder/decoder (exact Int/FatRat arithmetic, so the result is correctly rounded). Subnormals are emitted normalized (0x1p-1074), byte-compatible with js-sion and BSD printf %a.

SEE ALSO

AUTHOR

Dan Kogai

LICENSE AND COPYRIGHT

Copyright (c) 2026 by Dan Kogai.

This is free software, licensed under the Artistic License 2.0.