#data #format #compact #web-apps #codec #robots #fields

no-std pact

Compact and streamable data format that works anywhere--from web apps to robots

4 releases (2 breaking)

0.2.0 Mar 15, 2024
0.1.1 Mar 7, 2024
0.1.0 Jan 2, 2024
0.0.0 Oct 16, 2023

#290 in Data structures

33 downloads per month
Used in 2 crates

AGPL-3.0-only

86KB
1.5K SLoC

Compact and streamable data format that works anywhere--from web apps to robots.

What's a Pact?

Pacts describe the structure of related types of data, each containing one or more fields. Pact data can encode to and decode from raw binary data streams, which means pacts are extra-helpful for making distributed or embedded apps that speak different languages or rely on low-level networking.

Note: For those familiar with other data interchange formats, pacts have a lot in common with things like the proto schemas used by gRPC and the capnp schemas used by Cap'n Proto.

Each data type in a pact can have the following kinds of fields:

  1. Unsigned integers from 8 to 64 bits (u8, u16, u32, and u64).
  2. Signed integers from 8 to 64 bits (i8, i16, i32, and i64).
  3. Signed floating-point integers from 32 to 64 bits (f32 and f64).
  4. Booleans (bool).
  5. UTF-8 encoded strings, AKA text (string).
  6. Other user-defined data types ("nested" data)
  7. Lists of any of the things listed above.

For information on how pact data is coded to and from binary data, refer to the codec docs.

How do I make a Pact?

Pacts are made with TOML:

## An example pact.
pact = 'MyGreeter'

## Data type in this pact
## named "Request".
[data.1. Request]
message = 'string'

## Another data type in this
## pact named "Response".
[data.2. Response]
message = 'string'

## This field of a Response is a
## list of strings, instead of just
## a single string, because it is
## surrounded by `[]`.
friends = ['string']

## This field of a Response is a
## copy of the request that the
## response is for, showing how
## we can nest other data types
## within data types.
request = 'Request'

This example describes a MyGreeter pact with two kinds of data: Request and Response. Both of these data contain a message string, while the Response data contains a list of strings called friends and a copy of the original Request.

Every data description starts with a number called an Ordinal. Ordinals uniquely identify the different kinds of data in the same pact. The first data described by a pact always has ordinal 1, and each additional data type in the same pact has an ordinal that is one higher than the previous data.

Comments that start with ## and come immediately before the pact name, a data name, or a field name, will be parsed as documentation for the item they precede.

The easiest way to get started with TOML pacts in your own projects is via the pact-derive crate.

Can I change or "evolve" a Pact?

Yes! Pact data is designed to evolve as a system's needs change:

  • New data types can be added to any pact.
  • New fields can be added to any data type.
  • Existing fields and data types can be renamed.

If a system receives data of a new type it doesn't support, or containing new fields it doesn't support, the new information will be gracefully ignored.

Conversely, if a system receives data that's missing newly-added fields, the missing fields will be gracefully populated with default values.

License

Copyright 2024 Alicorn Systems, Inc.

Licensed under the GNU Affero General Public License version 3, as published by the Free Software Foundation. Refer to the license file for more information.

If you have any questions, please reach out to [hello@alicorn.systems].

Dependencies

~1.4–2.2MB
~48K SLoC