Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rust code generation #66

Draft
wants to merge 31 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .github/workflows/rs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Rust - Build and test

on: [ push ]

jobs:
build-test:
name: Build and test
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
- name: Install rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version-file: "go.mod"
cache: false
- name: Make sure generated files are updated
run: |
if go generate ./rs | grep -q 'rust: no changes detected'; then
exit 0;
fi
exit 1;
- name: cargo fmt
working-directory: rs/chainselectors
run: cargo fmt --all -- --check
- name: cargo clippy
working-directory: rs/chainselectors
run: cargo clippy --all-targets --all-features -- -D warnings
- name: cargo test
working-directory: rs/chainselectors
run: cargo test
timeout-minutes: 1
- name: cargo build
working-directory: rs/chainselectors
run: cargo build
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Any new chains and selectors should be always added to [selectors.yml](selectors
details from this file. This ensures that all client libraries are in sync and use the same mapping.
To add a new chain, please add new entry to the `selectors.yml` file and use the following format:

Make sure to run `go generate` after making any changes.
Make sure to run `go generate ./...` after making any changes.

```yaml
$chain_id:
Expand Down
35 changes: 5 additions & 30 deletions genchains.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,15 @@
package main

import (
"bytes"
"fmt"
"go/format"
"html/template"
"os"
"sort"
"strconv"
"strings"
"text/template"
"unicode"

chain_selectors "github.com/smartcontractkit/chain-selectors"
"github.com/smartcontractkit/chain-selectors/internal/gotmpl"
)

const filename = "generated_chains.go"
Expand Down Expand Up @@ -48,7 +46,7 @@ var ALL = []Chain{
`)

func main() {
src, err := genChainsSourceCode()
src, err := gotmpl.Run(chainTemplate, &goNameEncoder{})
if err != nil {
panic(err)
}
Expand All @@ -74,32 +72,9 @@ func main() {
}
}

func genChainsSourceCode() (string, error) {
var wr = new(bytes.Buffer)
chains := make([]chain, 0)

for evmChainID, chainSel := range chain_selectors.EvmChainIdToChainSelector() {
name, err := chain_selectors.NameFromChainId(evmChainID)
if err != nil {
return "", err
}

chains = append(chains, chain{
EvmChainID: evmChainID,
Selector: chainSel,
Name: name,
VarName: toVarName(name, chainSel),
})
}

sort.Slice(chains, func(i, j int) bool { return chains[i].VarName < chains[j].VarName })
if err := chainTemplate.ExecuteTemplate(wr, "", chains); err != nil {
return "", err
}
return wr.String(), nil
}
type goNameEncoder struct{}

func toVarName(name string, chainSel uint64) string {
func (*goNameEncoder) VarName(name string, chainSel uint64) string {
const unnamed = "TEST"
x := strings.ReplaceAll(name, "-", "_")
x = strings.ToUpper(x)
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ require (
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/text v0.19.0 // indirect
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
47 changes: 47 additions & 0 deletions internal/gotmpl/run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package gotmpl

import (
"bytes"
"sort"
"text/template"

chain_selectors "github.com/smartcontractkit/chain-selectors"
)

type NameEncoder interface {
VarName(name string, chainSel uint64) string
}

type chain struct {
EvmChainID uint64
Selector uint64
Name string
VarName string
}

func Run(tmpl *template.Template, enc NameEncoder) (string, error) {
var wr = new(bytes.Buffer)
chains := make([]chain, 0)

for evmChainID, chainSel := range chain_selectors.EvmChainIdToChainSelector() {
name, err := chain_selectors.NameFromChainId(evmChainID)
if err != nil {
return "", err
}

chains = append(chains, chain{
EvmChainID: evmChainID,
Selector: chainSel,
Name: name,
VarName: enc.VarName(name, chainSel),
})
}

sort.Slice(chains, func(i, j int) bool { return chains[i].VarName < chains[j].VarName })

if err := tmpl.Execute(wr, chains); err != nil {
return "", err
}

return wr.String(), nil
}
42 changes: 42 additions & 0 deletions rs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Chain Selectors (Rust)

This folder contains the Rust implementation of the Chain Selectors module.

## User Guide

### Installation

```shell
cargo add --git https://github.com/smartcontractkit/chain-selectors --tag <TAG>
```

### Usage

```rust
use std::str::FromStr;
use chainselectors::generated_chains::{ChainName, ChainSelector, ChainId};

fn main() {
let chain = ChainName::try_from(ChainId(420)).unwrap();
assert_eq!(chain, ChainName::EthereumTestnetGoerliOptimism1);

let selector = ChainSelector::from(ChainName::EthereumTestnetGoerliOptimism1);
assert_eq!(
selector,
ChainSelector(2664363617261496610),
);

let chain_from_str = ChainName::from_str("ethereum-testnet-goerli-optimism-1").unwrap();
assert_eq!(chain_from_str, ChainName::EthereumTestnetGoerliOptimism1);
}
```

## Dev Guide

### Pre-requisites

As part of the code generation, `rustfmt` is used to format the generated code. If you don't have rust toolchain installed, it will run in docker.

### Build

To build the Chain Selectors module, run the `go generate ./rs` from the root of the project, or `go generate ./...` to generate all modules (not just rust).
1 change: 1 addition & 0 deletions rs/chainselectors/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target/
93 changes: 93 additions & 0 deletions rs/chainselectors/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions rs/chainselectors/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "chainselectors"
version = "0.1.0"
edition = "2021"

[dependencies]
anyhow = "1.0"
serde = {version="1", features = ["derive"]}
thiserror = "1"
Loading
Loading