Ziggy Schema File Structure

File Extension

A Ziggy Schema file has a .ziggy-schema file extension.

File structure

Here’s an example Ziggy Schema:

$ = Foo

struct Foo {
   /// Fields can have doc comments.
   foo: Bar,
   bar: Baz,

   /// Type definitions too can have doc comments.
   struct Bar {
      baz: any,
   }
}

union Baz {
   qux: int,
   qax: bytes,
   qix,
}

A Ziggy schema is comprised of two main sections:

  • the $ definition
  • a series of custom type definitions

The $ definition

The first line of a Ziggy Schema defines the type of the top-level value of matching Ziggy Documents.

In Ziggy lingo, $ represents the top-level value (a concept shared with Scripty and other tooling in the Zine ecosystem), to which we assign a type expression.

The $ definition accepts a type expression because Ziggy Documents are allowed to have non-struct values at the top level. For comparison, while this is technically true also for JSON, in practice many JSON parsers expect the top-level value to be a JSON object, something that we want to avoid for Ziggy Documents.

For example the following are all valid Ziggy Schemas:

/// This matches the following Ziggy Document:
/// `"banana"`
$ = bytes
/// This matches the following Ziggy Document:
/// `[1,2,3]`
$ = []int
/// This matches the following Ziggy Document:
/// `{"foo": null, "bar": [true]}`
$ = {:}?[]bool

Type definitions

The main section of a Ziggy Schema is a list of type definitions.

Ziggy Schemas allow you to specify struct and union types. See the Custom Types page for more information.

Schema - Document pairing

This is how Ziggy tooling decides which Ziggy Schema should be used for a given Ziggy Document.

1. Same name

When a Ziggy Document and a Ziggy Schema share the same name and are located in the same directory.

Example: path/to/foo.ziggy -> path/to/foo.ziggy-schema

2. Dot schema

When a directory contains a .ziggy-schema file, it will be used for all Ziggy Documents in the entire directory subtree that do not have a Schema with the same name (as explained above).

For example, given this directory structure:

foo
├── .ziggy-schema
├── bar.ziggy
├── baz.ziggy
├── baz.ziggy-schema
├── fruits
│   ├── apple.ziggy
│   └── banana.ziggy
└── qux
    ├── .ziggy-schema
    ├── qax.ziggy
    └── qix.ziggy

Results in the following pairings:

foo/bar.ziggy           -> foo/.ziggy-schema 
foo/baz.ziggy           -> foo/baz.ziggy-schema 
foo/fruits/apple.ziggy  -> foo/.ziggy-schema
foo/fruits/banana.ziggy -> foo/.ziggy-schema
foo/qux/qax.ziggy       -> foo/qux/.ziggy-schema 
foo/qux/qix.ziggy       -> foo/qux/.ziggy-schema