Skip to content

Commit 4357f15

Browse files
authored
Merge pull request #181 from mlabs-haskell/szg251/add-docs
Rust documentation
2 parents 4fd187d + 8d74c91 commit 4357f15

File tree

4 files changed

+133
-1
lines changed

4 files changed

+133
-1
lines changed

docs/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- [LambdaBuffers to Haskell](haskell.md)
66
- [LambdaBuffers to Purescript](purescript.md)
77
- [LambdaBuffers for Plutarch](plutarch.md)
8+
- [LambdaBuffers for Rust](rust.md)
89
- [Design](design.md)
910
- [API](api.md)
1011
- [LambdaBuffers Frontend (.lbf) syntax](syntax.md)

docs/examples/lb-pkgs.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"crate": [
3+
"Document"
4+
]
5+
}

docs/rust.md

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# LambdaBuffers to Rust
2+
3+
Let's take a look at how LambdaBuffers modules map into Rust modules and how
4+
LambdaBuffers type definitions map into Rust type definitions.
5+
6+
We'll use the `lbf-prelude-to-rust` CLI tool which is just a convenient wrapper over
7+
the raw `lbf` CLI. We can get this tool by either loading the LambdaBuffers Nix
8+
environment that comes packaged with all the CLI tools:
9+
10+
```shell
11+
$ nix develop github:mlabs-haskell/lambda-buffers#lb
12+
$ lbf<tab>
13+
lbf lbf-plutus-to-purescript lbf-prelude-to-haskell lbf-prelude-to-rust
14+
lbf-plutus-to-haskell lbf-plutus-to-rust lbf-prelude-to-purescript
15+
```
16+
17+
Or we can simply just refer directly to the `lbf-prelude-to-rust` CLI by `nix run
18+
github:mlabs-haskell/lambda-buffers#lbf-prelude-to-rust`.
19+
20+
In this chapter, we're going to use the latter option.
21+
22+
Let's now use `lbf-prelude-to-rust` to process the [Document.lbf](https://github.com/mlabs-haskell/lambda-buffers/tree/main/docs/examples/Document.lbf) schema.
23+
24+
```purescript
25+
module Document
26+
27+
-- Importing types
28+
import Prelude (Text, List, Set, Bytes)
29+
30+
-- Author
31+
sum Author = Ivan | Jovan | Savo
32+
33+
-- Reviewer
34+
sum Reviewer = Bob | Alice
35+
36+
-- Document
37+
record Document a = {
38+
author : Author,
39+
reviewers : Set Reviewer,
40+
content : Chapter a
41+
}
42+
43+
-- Chapter
44+
record Chapter a = {
45+
content : a,
46+
subChapters : List (Chapter a)
47+
}
48+
49+
-- Some actual content
50+
sum RichContent = Image Bytes | Gif Bytes | Text Text
51+
52+
-- Rich document
53+
prod RichDocument = (Document RichContent)
54+
```
55+
56+
```shell
57+
$ nix run github:mlabs-haskell/lambda-buffers#lbf-prelude-to-rust -- Document.lbf
58+
$ find autogen/
59+
autogen/
60+
autogen/LambdaBuffers
61+
autogen/LambdaBuffers/Document.hs
62+
autogen/build.json
63+
```
64+
65+
As we can see the `autogen` directory has been created that contains the generated Rust modules.
66+
Note the `autogen/build.json` file as it contains all the necessary Cargo dependencies the generated module needs in order to be properly compiled by Rust.
67+
68+
The outputted Rust module in `autogen/document.rs`:
69+
70+
```rust
71+
#![no_implicit_prelude]
72+
#![allow(warnings)]
73+
extern crate lbf_prelude;
74+
extern crate std;
75+
76+
77+
#[derive(std::fmt::Debug, std::clone::Clone)]
78+
pub enum Author{Ivan, Jovan, Savo}
79+
80+
#[derive(std::fmt::Debug, std::clone::Clone)]
81+
pub struct Chapter<A>{pub content: A,
82+
pub sub_chapters: std::boxed::Box<lbf_prelude::prelude::List<Chapter<A>>>}
83+
84+
#[derive(std::fmt::Debug, std::clone::Clone)]
85+
pub struct Document<A>{pub author: Author,
86+
pub reviewers: lbf_prelude::prelude::Set<Reviewer>,
87+
pub content: Chapter<A>}
88+
89+
#[derive(std::fmt::Debug, std::clone::Clone)]
90+
pub enum Reviewer{Bob, Alice}
91+
92+
#[derive(std::fmt::Debug, std::clone::Clone)]
93+
pub enum RichContent{Image(lbf_prelude::prelude::Bytes),
94+
Gif(lbf_prelude::prelude::Bytes),
95+
Text(lbf_prelude::prelude::Text)}
96+
97+
#[derive(std::fmt::Debug, std::clone::Clone)]
98+
pub struct RichDocument(pub Document<RichContent>);
99+
100+
```
101+
102+
## Sum types
103+
104+
The types `Author`, `Reviewer`, and `RichContent` have been declared as sum types in the LambdaBuffers schema using the `sum` keyword.
105+
106+
As we can see, nothing too surprising here, all the `sum` types become `enum`
107+
in Rust.
108+
109+
## Product types
110+
111+
The type `RichDocument` have been declared as a product type in the
112+
LambdaBuffers schema using the `prod` keyword.
113+
114+
They become Rust tuple `struct` (or named tuple)
115+
116+
## Record types
117+
118+
The types `Document` and `Chapter` have been declared as record types in the
119+
LambdaBuffers schema using the `record` keyword.
120+
121+
Like with product types, they become Rust `struct` with named fields.
122+
123+
All types and their fields are public, allowing to manipulate them without accessors.

lambda-buffers-frontend/build.nix

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,9 @@
195195
gen = "${config.packages.lbg-rust}/bin/lbg-rust";
196196
gen-classes = ["Prelude.Eq" "Prelude.Json"];
197197
gen-dir = "autogen";
198-
gen-opts = ["--config=${config.packages.codegen-configs}/rust-prelude-base.json"];
198+
gen-opts = [
199+
"--packages lb-pkgs.json"
200+
"--config=${config.packages.codegen-configs}/rust-prelude-base.json"];
199201
work-dir = ".work";
200202
}} "$@";
201203
'';
@@ -211,6 +213,7 @@
211213
gen-classes = ["Prelude.Eq" "Prelude.Json" "Plutus.V1.PlutusData" ];
212214
gen-dir = "autogen";
213215
gen-opts = [
216+
"--packages lb-pkgs.json"
214217
"--config=${config.packages.codegen-configs}/rust-prelude-base.json"
215218
"--config=${config.packages.codegen-configs}/rust-plutus-pla.json"
216219
];

0 commit comments

Comments
 (0)