Kyss -- "Keep Your Serialization Simple" is a serialization format designed for simplicity, unambiguity, and a pleasant experience for human reading and writing.
Kyss was designed with these criteria in mind:
- Maps, arrays, strings, ints: all the basics should be unsurprising.
- Nesting is indicated by indentation.
- Multi-line strings are syntactically useful.
- All values should be unambiguous.
- Canonical (think 'go fmt') formatting is defined.
- Comments are valuable.
Some of these criteria sound too simple and obvious to mention. For example, "All values should be unambiguous" -- duh, right? And yet, let's get more specific: "Whitespace at the beginning of a string written in multi-line format should be parsable" -- some formats (cough, yaml) cannot express this. Kyss can.
Furthermore, Kyss was designed for visual consistency, and simple parsing:
- All lines start with a sigil which states what container type this is.
- Each line contains a complete value; or, if it is the beginning of a new container value which has no content until the subsequent line, then a sigil is placed at the end of the line to indicate parsing continues below.
These visual consistency rules are a reaction to some of the more esoteric appearances possible in yaml documents (e.g. list-in-a-list-in-a-list). Kyss is intended to be as uncomplex and rapid-scannable to the human eye as possible, and that means for example that indentation should always be absolutely consistent in indicating object tree depth, and that a constant amount of data entries should exist on each line.
- "value1"
- "value2"
- 300
- "p.s. mixed types are okay"
Kyss arrays resemble YAML arrays.
% mapkey: "value"
% otherkey: "otherval"
Kyss map entries are prefixed with a %
sigil; this is for visual
consistency with Kyss array entries.
When nesting one container inside another, the nested container values will all be indented (similar to most formats, like YAML and pretty-printed JSON).
Since the nested container's entries will be indented, they will be on
a subsequent line. Since this would often leave an awkwardly empty visual
space, in Kyss we mark this space with a >>
: this indicates that we're
at the beginning of a container (e.g. a map or array), and the content
will continue on the next line.
% mapkey: "value"
% foobar: >>
- "listval"
- "moreval"
- >>
- "deeper list value"
- 14
% backtomap: 18
% moarkey: >>
% yarr: "matey"
These string values are equivalent:
"multi\nline\nstring"
| multi
| line
| string
Multi-line strings are also a container type, like maps and arrays.
Multi-line strings inside other containers follow the same >>
prefixing
pattern as any other container nesting:
% mapkey: >>
% longstr: >>
| heredoc
| am
| i
Comments in kiss are always at the end of a line, and are marked by a #
.
% mapkey: "value" # end-of-line comments
% otherkey: "otherval" # use them liberally
The canonical format of a Kyss document will align end-of-line comments
when they are on the adjacent lines and in same container.
(This rule resembles what you intuitively expect if you're familiar with
the behaviors of go fmt
.)
Comments can also be on their own line:
% mapkey: >>
# This comment is on its own line.
% longstr: >>
| heredoc
| am
| i
Empty maps and arrays require a slightly exceptional syntax in Kyss; we expect they are not very often used in practice.
% containsEmptyMap: {}
% containsEmptyArray: []
This example shows every possible feature of Kyss in one:
# Comments are your friends.
% mapkey: "value"
% foobar: >>
- "listval"
- "moreval"
- >>
- "deeper list value"
- 14
% backtomap: 18
% moarkey: >>
% yarr: "matey" # This is an end-of-line comment.
# This comment is on its own line.
% longstr: >>
| heredoc
| am
| i
% wildstr: >>
| did you know
| good multi-line strings
| might actually need to start
| with whitespace themselves
| haiku
% containsEmptyMap: {}
% containsEmptyArray: []
# 'silly' contains a list of lists of empty lists.
% silly: >>
- >>
- >>
- []
% primitives: >>
- true
- false
- null
# and that's all!
# happy hacking!