From 7b15ae469ca2e713fd842f1d17e410bbb6e2e4b2 Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Thu, 1 Feb 2024 17:48:54 +0100 Subject: [PATCH 1/4] Fix Rust codegen using 'lbf-prelude-rust' --- docs/examples/lb-pkgs.json | 5 +++++ lambda-buffers-frontend/build.nix | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 docs/examples/lb-pkgs.json diff --git a/docs/examples/lb-pkgs.json b/docs/examples/lb-pkgs.json new file mode 100644 index 00000000..51086663 --- /dev/null +++ b/docs/examples/lb-pkgs.json @@ -0,0 +1,5 @@ +{ + "crate": [ + "Document" + ] +} diff --git a/lambda-buffers-frontend/build.nix b/lambda-buffers-frontend/build.nix index f79e73b5..dae55669 100644 --- a/lambda-buffers-frontend/build.nix +++ b/lambda-buffers-frontend/build.nix @@ -195,7 +195,9 @@ _: gen = "${config.packages.lbg-rust}/bin/lbg-rust"; gen-classes = ["Prelude.Eq" "Prelude.Json"]; gen-dir = "autogen"; - gen-opts = ["--config=${config.packages.codegen-configs}/rust-prelude-base.json"]; + gen-opts = [ + "--packages lb-pkgs.json" + "--config=${config.packages.codegen-configs}/rust-prelude-base.json"]; work-dir = ".work"; }} "$@"; ''; @@ -211,6 +213,7 @@ _: gen-classes = ["Prelude.Eq" "Prelude.Json" "Plutus.V1.PlutusData" ]; gen-dir = "autogen"; gen-opts = [ + "--packages lb-pkgs.json" "--config=${config.packages.codegen-configs}/rust-prelude-base.json" "--config=${config.packages.codegen-configs}/rust-plutus-pla.json" ]; From 1ff2a4f4e0331b050ddeea7504b5afe5e36712d8 Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Thu, 1 Feb 2024 17:49:16 +0100 Subject: [PATCH 2/4] Add Rust documentation --- docs/rust.md | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 docs/rust.md diff --git a/docs/rust.md b/docs/rust.md new file mode 100644 index 00000000..a95d2acb --- /dev/null +++ b/docs/rust.md @@ -0,0 +1,123 @@ +# LambdaBuffers to Rust + +Let's take a look at how LambdaBuffers modules map into Rust modules and how +LambdaBuffers type definitions map into Rust type definitions. + +We'll use the `lbf-prelude-to-rust` CLI tool which is just a convenient wrapper over +the raw `lbf` CLI. We can get this tool by either loading the LambdaBuffers Nix +environment that comes packaged with all the CLI tools: + +```shell +$ nix develop github:mlabs-haskell/lambda-buffers#lb +$ lbf +lbf lbf-plutus-to-purescript lbf-prelude-to-haskell lbf-prelude-to-rust +lbf-plutus-to-haskell lbf-plutus-to-rust lbf-prelude-to-purescript +``` + +Or we can simply just refer directly to the `lbf-prelude-to-rust` CLI by `nix run +github:mlabs-haskell/lambda-buffers#lbf-prelude-to-rust`. + +In this chapter, we're going to use the latter option. + +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. + +```purescript +module Document + +-- Importing types +import Prelude (Text, List, Set, Bytes) + +-- Author +sum Author = Ivan | Jovan | Savo + +-- Reviewer +sum Reviewer = Bob | Alice + +-- Document +record Document a = { + author : Author, + reviewers : Set Reviewer, + content : Chapter a + } + +-- Chapter +record Chapter a = { + content : a, + subChapters : List (Chapter a) + } + +-- Some actual content +sum RichContent = Image Bytes | Gif Bytes | Text Text + +-- Rich document +prod RichDocument = (Document RichContent) +``` + +```shell +$ nix run github:mlabs-haskell/lambda-buffers#lbf-prelude-to-rust -- Document.lbf +$ find autogen/ +autogen/ +autogen/LambdaBuffers +autogen/LambdaBuffers/Document.hs +autogen/build.json +``` + +As we can see the `autogen` directory has been created that contains the generated Haskell modules. +Note the `autogen/build.json` file as it contains all the necessary Hackage dependencies the generated module needs in order to be properly compiled by GHC. + +The outputted Haskell module in `autogen/document.rs`: + +```rust +#![no_implicit_prelude] +#![allow(warnings)] +extern crate lbf_prelude; +extern crate std; + + +#[derive(std::fmt::Debug, std::clone::Clone)] +pub enum Author{Ivan, Jovan, Savo} + +#[derive(std::fmt::Debug, std::clone::Clone)] +pub struct Chapter{pub content: A, + pub sub_chapters: std::boxed::Box>>} + +#[derive(std::fmt::Debug, std::clone::Clone)] +pub struct Document{pub author: Author, + pub reviewers: lbf_prelude::prelude::Set, + pub content: Chapter} + +#[derive(std::fmt::Debug, std::clone::Clone)] +pub enum Reviewer{Bob, Alice} + +#[derive(std::fmt::Debug, std::clone::Clone)] +pub enum RichContent{Image(lbf_prelude::prelude::Bytes), + Gif(lbf_prelude::prelude::Bytes), + Text(lbf_prelude::prelude::Text)} + +#[derive(std::fmt::Debug, std::clone::Clone)] +pub struct RichDocument(pub Document); + +``` + +## Sum types + +The types `Author`, `Reviewer`, and `RichContent` have been declared as sum types in the LambdaBuffers schema using the `sum` keyword. + +As we can see, nothing too surprising here, all the `sum` types become `enum` +in Rust. + +## Product types + +The type `RichDocument` have been declared as a product type in the +LambdaBuffers schema using the `prod` keyword. + +They become Rust tuple `struct` (or named tuple) + +## Record types + +The types `Document` and `Chapter` have been declared as record types in the +LambdaBuffers schema using the `record` keyword. + +Like with product types, they become Rust `struct` with named fields. + +All types and their fields are public, allowing to manipulate them without accessors. From bbe3dbfa0ce59cb9a455e3c05d17152e8fbf1a74 Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Mon, 5 Feb 2024 12:31:14 +0100 Subject: [PATCH 3/4] Add Rust doc to summary --- docs/SUMMARY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 31a3e7e3..6a99e91f 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -5,6 +5,7 @@ - [LambdaBuffers to Haskell](haskell.md) - [LambdaBuffers to Purescript](purescript.md) - [LambdaBuffers for Plutarch](plutarch.md) +- [LambdaBuffers for Rust](rust.md) - [Design](design.md) - [API](api.md) - [LambdaBuffers Frontend (.lbf) syntax](syntax.md) From c305fd877ca87e85a77e19d63683d4b918a9f70a Mon Sep 17 00:00:00 2001 From: Szabo Gergely Date: Mon, 5 Feb 2024 16:04:36 +0100 Subject: [PATCH 4/4] Fix Rust doc --- docs/rust.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/rust.md b/docs/rust.md index a95d2acb..145fdb06 100644 --- a/docs/rust.md +++ b/docs/rust.md @@ -62,10 +62,10 @@ autogen/LambdaBuffers/Document.hs autogen/build.json ``` -As we can see the `autogen` directory has been created that contains the generated Haskell modules. -Note the `autogen/build.json` file as it contains all the necessary Hackage dependencies the generated module needs in order to be properly compiled by GHC. +As we can see the `autogen` directory has been created that contains the generated Rust modules. +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. -The outputted Haskell module in `autogen/document.rs`: +The outputted Rust module in `autogen/document.rs`: ```rust #![no_implicit_prelude]