`fastn` 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 Person record
-- record person:
caption name:
integer age:
optional body bio:
Here we are creating a record. The name of the record is `person`. It has three
fields: `name`, `age` and `bio`.
Declaring a Company record
-- record company:
caption name:
person list employees:
In this case, the name of the record is `company`. It has two fields:
caption `name` and list of `employees` of `person` type.
Declaring a `record` with default values
Sometimes, the programmer might want to provide default values to the record
fields, in case if he/she doesn't specify those during initialization.
Declaring a Person record with default field values
-- record person:
caption name: Undefined
integer age:
optional body bio: Not specified
;; << Alternative way >>
-- record person:
caption name: Undefined
integer age:
-- optional body person.bio:
No bio is specified for this person.
Declaring a Company record with default field values
-- record company:
string name: FifthTry
-- person list company.employees:
-- person:
name: Arpita
age: 22
-- person:
name: Abrar
age: 24
-- end: company.employees
Field Types
Fields can be either one of the [built-in types](ftd/built-in-types/),
another type like a [`record`](ftd/record/) or [`or-type`](ftd/or-type/).
Record Variable
A [variable](ftd/variables/) can be created with type `record`:
-- person john-snow: John Snow
age: 14
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 just `body` the above would not have been
valid.
Record Field Update Syntax
The field which needs to be updated has to be mutable before updating its value.
An individual field of a record can be updated using a syntax like this:
-- $john-snow.age: 15
-- person $john-snow: John Snow
$age: 14
Here we have used `-- $john-snow.age: 15` to update a single field of a record.
This also works if the field is a list:
-- record person:
caption name:
string list alias:
-- person $john-snow: John Snow
-- $john-snow.alias:
-- string: Aegon Targaryen
-- string: Lord Crow
-- string: The White Wolf
-- string: The Prince That Was Promised
-- end: $john-snow.alias
Reading A Record From Rust
A `record` in `fastn` 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:
#[derive(serde::Deserialize)]
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](https://docs.serde.rs/serde_json/struct.Number.html) since
`fastn` integer is converted to `JSON Number`.