Start Here
Data Modelling
Built-in Types
ftd supports record types. These are also called struct in some languages.
Declaring a record
Before a record can be used it must be declared using the record syntax:
declaring a record
-- record person:
name: caption
age: integer
bio: optional body
Here we are creating a record. The name of the record is person. It has three fields: name, age and bio.
Field Types
Fields can be either one of the built-in types, another type like a record or or-type.
Record Variable
A variable can be created with type record:
-- person amitu: Amit Upadhyay
age: 40

Here we have created a new variable of type person, called it amitu, and the value of name, since its declared as caption in the record definition, is read from the “caption” area, and age is read from the “header”.

Note that we have not passed bio, since bio is declared as optional body, so it’s not a problem. Had it been body the above would not have been valid.

Reading A Record From Rust
A record in ftd is equivalent of a struct in Rust.
Rust Type
To read the above ftd file from Rust you will have to first create a struct in Rust that is compatible with our person definition:
struct Person {
    name: String,
    age: i32,
    bio: Option<String>,

For each field in person record, we have a corresponding field in our Person struct.

Note that we used age as i32, but it could have been any type that can be deserialised from JSON Number since ftd integer is converted to JSON Number.

Getting Data From FTD File
Once the mapping is in place, we can use the ftd crate to parse an ftd file, and get data out of it:
let doc = ftd::p2::Document::from("some/id", source, lib)?;
let amitu: Person = doc.get("amitu")?;
You can read more details of reading ftd files “Reading FTD Files” guide.
Record “Instances”
ftd also supports “anonymous” instances:
-- person: Amit Upadhyay
age: 40

This is the bio

-- person: Shobhit Sharma
age: 30

Note that we have not assigned these instances to any variable using the var keyword. These are called “anonymous instances”.

These instances can be read from Rust using:

let doc = ftd::p2::Document::from("some/id", source, lib)?;
let instances: Vec<Person> = doc.instances("person")?;

// if you expect the document to contain only one instance:
let instance: Person = doc.only_instance("person")?;
This allows you an “ergonomic” way to declare data in ftd files.