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

feat: code generate instruction account structs #16

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
generated/
.idea/
24 changes: 24 additions & 0 deletions generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,30 @@ func genField(field IdlField, pointer bool) Code {
return st
}

func genAccountField(field IdlAccountItem) Code {
st := newStatement()
if field.IdlAccount != nil {
st.Id(ToCamel(field.IdlAccount.Name)).
Add(typeStringToType(IdlTypePublicKey)).
Add(func() Code {
if field.IdlAccount.Optional {
return Tag(map[string]string{
"bin": "optional",
})
}
return nil
}())
}
if field.IdlAccounts != nil {
st.Id(ToCamel(field.IdlAccounts.Name)).StructFunc(func(group *Group) {
for _, idlAccountItem := range field.IdlAccounts.Accounts {
group.Add(genAccountField(idlAccountItem))
}
})
}
return st
}

func genTypeName(idlTypeEnv IdlType) Code {
st := newStatement()
switch {
Expand Down
82 changes: 77 additions & 5 deletions generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@ import (

. "github.com/dave/jennifer/jen"
"github.com/davecgh/go-spew/spew"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

type jsonToSource struct {
from string
expected string
}

func Test_genTypeName(t *testing.T) {
type jsonToSource struct {
from string
Expand Down Expand Up @@ -155,10 +160,6 @@ func Test_genTypeName(t *testing.T) {
}

func Test_genField(t *testing.T) {
type jsonToSource struct {
from string
expected string
}

tests := []jsonToSource{
{
Expand Down Expand Up @@ -186,6 +187,77 @@ func Test_genField(t *testing.T) {
}
}

func Test_genAccountField(t *testing.T) {
basicTest := `{
"name": "authorityBefore",
"isMut": false,
"isSigner": true
}`
optionalTest := `{
"name": "authorityBefore",
"isMut": false,
"isSigner": true,
"optional": true
}`
compositeTest := `{
"name": "marketGroup",
"accounts": [
{
"name": "marketMarket",
"isMut": true,
"isSigner": false
},
{
"name": "foo",
"isMut": true,
"isSigner": false
},
{
"name": "subMarket",
"accounts": [
{
"name": "subMarketMarket",
"isMut": true,
"isSigner": false
},
{
"name": "openOrders",
"isMut": true,
"isSigner": false
}
]
}
]
}`

tests := []jsonToSource{
{
basicTest,
"var thing struct {\n\tAuthorityBefore solanago.PublicKey\n}",
},
{
optionalTest,
"var thing struct {\n\tAuthorityBefore solanago.PublicKey `bin:\"optional\"`\n}",
},
{
compositeTest,
"var thing struct {\n\tMarketGroup struct {\n\t\tMarketMarket solanago.PublicKey\n\t\tFoo solanago.PublicKey\n\t\tSubMarket struct {\n\t\t\tSubMarketMarket solanago.PublicKey\n\t\t\tOpenOrders solanago.PublicKey\n\t\t}\n\t}\n}",
},
}
{
for _, scenario := range tests {
var target IdlAccountItem
err := json.Unmarshal([]byte(scenario.from), &target)
require.NoError(t, err)
code := Var().Id("thing").Struct(
genAccountField(target),
)
got := codeToString(code)
require.Equal(t, scenario.expected, got)
}
}
}

func Test_IdlAccountItemSlice_Walk(t *testing.T) {
data := `[
{
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,6 @@ github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gagliardetto/binary v0.6.1/go.mod h1:aOfYkc20U0deHaHn/LVZXiqlkDbFAX0FpTlDhsXa0S0=
github.com/gagliardetto/binary v0.7.1 h1:6ggDQ26vR+4xEvl/S13NcdLK3MUCi4oSy73pS9aI1cI=
github.com/gagliardetto/binary v0.7.1/go.mod h1:aOfYkc20U0deHaHn/LVZXiqlkDbFAX0FpTlDhsXa0S0=
github.com/gagliardetto/binary v0.7.6 h1:8K3ZB9cEffv6XVqybOR7WxFTTsB1FDWHkv28Pg2tTPc=
github.com/gagliardetto/binary v0.7.6/go.mod h1:mUuay5LL8wFVnIlecHakSZMvcdqfs+CsotR5n77kyjM=
github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw=
Expand Down
39 changes: 38 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ func GenerateClientFromProgramIDL(idl IDL) ([]*FileWrapper, error) {
for _, instruction := range idl.Instructions {
file := NewGoFile(idl.Name, true)
insExportedName := ToCamel(instruction.Name)

insAccountsExportedName := ToCamel(fmt.Sprintf("%s_accounts", instruction.Name))
// fmt.Println(RedBG(instruction.Name))

{
Expand Down Expand Up @@ -398,6 +398,15 @@ func GenerateClientFromProgramIDL(idl IDL) ([]*FileWrapper, error) {
})
})

code.Line().Line()

// Generate Instruction Account Struct
code.Type().Id(insAccountsExportedName).StructFunc(func(fieldsGroup *Group) {
for _, accountItem := range instruction.Accounts {
fieldsGroup.Add(genAccountField(accountItem))
}
})

file.Add(code.Line())
}

Expand Down Expand Up @@ -447,6 +456,29 @@ func GenerateClientFromProgramIDL(idl IDL) ([]*FileWrapper, error) {
file.Add(code.Line())
}

{
// Declare method to get Account struct from AccountMetasSlice
code := Empty().Line().Line()
code.
Func().
Params(Id("inst").Op("*").Id(insExportedName)).
Id("Get" + insAccountsExportedName).Params().Op("*").Id(insAccountsExportedName).
BlockFunc(func(body *Group) {
body.Id("res").Op(":=").Op("&").Id(insAccountsExportedName).Block()
instruction.Accounts.Walk("", nil, nil, func(parentGroupPath string, index int, parentGroup *IdlAccounts, account *IdlAccount) bool {
field := body.Id("res")
if parentGroupPath != "" {
field = field.Dot(ToCamel(parentGroupPath))
}
field = field.Dot(ToCamel(account.Name)).Op("=").Add(Id("inst").Dot("AccountMetaSlice").Index(Lit(index)).Dot("PublicKey"))
return true
})
body.Return().Op("res")
})

file.Add(code.Line().Line())
sol-mocha marked this conversation as resolved.
Show resolved Hide resolved
}

{
// Declare methods that set the parameters of the instruction:
code := Empty()
Expand Down Expand Up @@ -490,6 +522,7 @@ func GenerateClientFromProgramIDL(idl IDL) ([]*FileWrapper, error) {

file.Add(code.Line())
}

{
// Declare methods that set/get accounts for the instruction:
code := Empty()
Expand Down Expand Up @@ -588,6 +621,7 @@ func GenerateClientFromProgramIDL(idl IDL) ([]*FileWrapper, error) {

file.Add(code.Line())
}

{
// Declare `Build` method on instruction:
code := Empty()
Expand Down Expand Up @@ -664,6 +698,7 @@ func GenerateClientFromProgramIDL(idl IDL) ([]*FileWrapper, error) {
})
file.Add(code.Line())
}

{
// Declare `ValidateAndBuild` method on instruction:
code := Empty()
Expand Down Expand Up @@ -701,6 +736,7 @@ func GenerateClientFromProgramIDL(idl IDL) ([]*FileWrapper, error) {
})
file.Add(code.Line())
}

{
// Declare `Validate` method on instruction:
code := Empty()
Expand Down Expand Up @@ -766,6 +802,7 @@ func GenerateClientFromProgramIDL(idl IDL) ([]*FileWrapper, error) {
})
file.Add(code.Line())
}

{
// Declare `EncodeToTree(parent treeout.Branches)` method in instruction:
code := Empty()
Expand Down