forked from fastn-stack/ftd.dev
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrecord.ftd
130 lines (83 loc) · 2.97 KB
/
record.ftd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
\-- ft-core.concept:
-- ft.page-with-toc: `record`
toc: $config.data-toc
sub-sections: $config.doc-header
-- ft.markdown:
`ftd` supports `record` types. These are also called `struct` in some languages.
-- ft.h1: Declaring a `record`
Before a record can be used it must be declared using the `record` syntax:
-- ft.code: declaring a record
lang: ftd
\-- record person:
name: caption
age: integer
bio: optional body
-- ft.markdown:
Here we are creating a record. The name of the record is `person`. It has three
fields: `name`, `age` and `bio`.
-- ft.h1: Field Types
Fields can be either one of the [built-in types](built-in-types/),
another type like a `record` or [`or-type`](or-type/).
-- ft.h1: Record Variable
A variable can be created with type `record`:
-- ft.code:
lang: ftd
\-- person amitu: Amit Upadhyay
age: 40
-- ft.markdown:
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.
-- ft.h1: Reading A Record From Rust
A `record` in `ftd` is equivalent of a `struct` in Rust.
-- ft.h2: 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:
-- ft.code:
lang: rs
#[derive(serde::Deserialize)]
struct Person {
name: String,
age: i32,
bio: Option<String>,
}
-- ft.markdown:
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 `ftd` `integer`
is converted to `JSON Number`.
-- ft.h2: 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:
-- ft.code:
lang: rs
let doc = ftd::p2::Document::from("some/id", source, lib)?;
let amitu: Person = doc.get("amitu")?;
-- ft.markdown:
You can read more details of reading `ftd` files ["Reading FTD
Files"](reading-data/) guide.
-- ft.h1: Record "Instances"
`ftd` also supports "anonymous" instances:
-- ft.code:
lang: ftd
\-- person: Amit Upadhyay
age: 40
This is the bio
\-- person: Shobhit Sharma
age: 30
-- ft.markdown:
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:
-- ft.code:
lang: rs
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")?;
-- ft.markdown:
This allows you an "ergonomic" way to declare data in `ftd` files.