Types and Layouts

A TreeLDR document is a collection of types and layouts.

Types

A type, sometimes called class, sort, or schema in other languages, is an object that describes the properties associated with a value instance of this type. In TreeLDR, types are simply declared using the type keyword:

type MyType; // Declares that `MyType` is a type.

In the example above, MyType is an empty type, and it doesn't say anything about the instances of MyType. We can extend this definition by listing all the properties of this type between braces:

type MyType {
	property1: Type1,
	// ...
	propertyN: TypeN
}

This specifies that each instance of MyType can have the above properties. By default those properties are optional. This can be changed using the required keyword:

type MyType {
	property1: required Type1,
	// ...
	propertyN: TypeN
}

Now each instance of MyType must have the property1 property. In this context, required is an attributes to the property1 property. Another useful attribute is multiple that states that a property can be associated with more than one value at once. Without attributes, properties are all optional and can take at most a single value.

Here is an example defining the Person type taking advantage of property attributes:

Layouts

When writing an application, one may need to represent the same data into multiple formats (one format inside the database, another in memory, transmission, etc.). In TreeLDR, those formats are called layouts. A layout is a particular representation for a type. It is sometimes called a view in other languages.

A layout defines a list of properties to include, how to name them (each property can have different name in different layouts), how to order them, and more. A layout is defined using the layout keyword. A single type can have multiple layouts.

The as keyword is used to rename the considered property inside the layout. Without it, a default name is extracted from the identifier of the property. Here is a layout definition for the Person type defined above:

Layouts are used to define a common representation for a given type that can be shared between applications. TreeLDR can export a layout definition into type definitions in different programming languages, and schema definitions for data exchange formats. For instance using the TreeLDR compiler, the PersonLayout schema definition above can be translated into the following:

  • A Rust type

  • A TypeScript type

  • A JSON Schema

These define a common representation that can be used to exchange instances of Person between a Rust application and a TypeScript application using JSON as the intermediate format. TreeLDR will also take care of generating the JSON serialization/deserialization routines in both languages, matching the above JSON Schema.

Default Layout

Each type definition is always also an implicit layout definition. If you consider again the previous Person type definition:

This definition implicitly embeds the following layout definition:

It is possible to use layout-specific keywords (such as the as keyword to rename properties inside a layout) to affect the default layout definition. It is also possible to replace the default layout definition using the with keyword:

Last updated

Was this helpful?