Skip to content

Commit

Permalink
allow export and import of path values, including JSON encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
turbolent committed Aug 14, 2020
1 parent 02b9078 commit a1e6124
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 3 deletions.
13 changes: 13 additions & 0 deletions encoding/json/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ const (
targetKeyKey = "targetKey"
targetPathKey = "targetPath"
borrowTypeKey = "borrowType"
domainKey = "domain"
identifierKey = "identifier"
)

var ErrInvalidJSONCadence = errors.New("invalid JSON Cadence structure")
Expand Down Expand Up @@ -186,6 +188,8 @@ func decodeJSON(v interface{}) cadence.Value {
return decodeStorageReference(valueJSON)
case linkTypeStr:
return decodeLink(valueJSON)
case pathTypeStr:
return decodePath(valueJSON)
}

panic(ErrInvalidJSONCadence)
Expand Down Expand Up @@ -581,6 +585,15 @@ func decodeLink(valueJSON interface{}) cadence.Link {
)
}

func decodePath(valueJSON interface{}) cadence.Path {
obj := toObject(valueJSON)

return cadence.Path{
Domain: obj.GetString(domainKey),
Identifier: obj.GetString(identifierKey),
}
}

// JSON types

type jsonObject map[string]interface{}
Expand Down
18 changes: 18 additions & 0 deletions encoding/json/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ type jsonLinkValue struct {
BorrowType string `json:"borrowType"`
}

type jsonPathValue struct {
Domain string `json:"domain"`
Identifier string `json:"identifier"`
}

const (
voidTypeStr = "Void"
optionalTypeStr = "Optional"
Expand Down Expand Up @@ -163,6 +168,7 @@ const (
contractTypeStr = "Contract"
storageReferenceTypeStr = "StorageReference"
linkTypeStr = "Link"
pathTypeStr = "Path"
)

// prepare traverses the object graph of the provided value and constructs
Expand Down Expand Up @@ -235,6 +241,8 @@ func (e *Encoder) prepare(v cadence.Value) jsonValue {
return e.prepareStorageReference(x)
case cadence.Link:
return e.prepareLink(x)
case cadence.Path:
return e.preparePath(x)
default:
panic(fmt.Errorf("unsupported value: %T, %v", v, v))
}
Expand Down Expand Up @@ -522,6 +530,16 @@ func (e *Encoder) prepareLink(x cadence.Link) jsonValue {
}
}

func (e *Encoder) preparePath(x cadence.Path) jsonValue {
return jsonValueObject{
Type: pathTypeStr,
Value: jsonPathValue{
Domain: x.Domain,
Identifier: x.Identifier,
},
}
}

func encodeBytes(v []byte) string {
return fmt.Sprintf("0x%x", v)
}
Expand Down
28 changes: 25 additions & 3 deletions encoding/json/encoding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1204,6 +1204,19 @@ func TestDecodeFixedPoints(t *testing.T) {
})
}

func TestEncodePath(t *testing.T) {

t.Parallel()

testAllEncodeAndDecode(t, []encodeTest{
{
"Simple",
cadence.Path{Domain: "storage", Identifier: "foo"},
`{"type":"Path","value":{"domain":"storage","identifier":"foo"}}`,
},
}...)
}

func convertValueFromScript(t *testing.T, script string) cadence.Value {
rt := runtime.NewInterpreterRuntime()

Expand All @@ -1220,11 +1233,20 @@ func convertValueFromScript(t *testing.T, script string) cadence.Value {
}

func testAllEncodeAndDecode(t *testing.T, tests ...encodeTest) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
testEncodeAndDecode(t, test.val, test.expected)

test := func(testCase encodeTest) {

t.Run(testCase.name, func(t *testing.T) {

t.Parallel()

testEncodeAndDecode(t, testCase.val, testCase.expected)
})
}

for _, testCase := range tests {
test(testCase)
}
}

func testEncodeAndDecode(t *testing.T, val cadence.Value, expectedJSON string) {
Expand Down
15 changes: 15 additions & 0 deletions runtime/common/pathdomain.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,18 @@ func (i PathDomain) Name() string {

panic(errors.NewUnreachableError())
}

func PathDomainFromName(name string) PathDomain {
switch name {
case "storage":
return PathDomainStorage

case "private":
return PathDomainPrivate

case "public":
return PathDomainPublic
}

panic(errors.NewUnreachableError())
}
14 changes: 14 additions & 0 deletions runtime/convertValues.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ func exportValueWithInterpreter(value interpreter.Value, inter *interpreter.Inte
return exportStorageReferenceValue(v)
case interpreter.LinkValue:
return exportLinkValue(v, inter)
case interpreter.PathValue:
return exportPathValue(v)
}

panic(fmt.Sprintf("cannot export value of type %T", value))
Expand Down Expand Up @@ -281,6 +283,11 @@ func importValue(value cadence.Value) interpreter.Value {
return importCompositeValue(common.CompositeKindResource, v.ResourceType.ID(), v.ResourceType.Fields, v.Fields)
case cadence.Event:
return importCompositeValue(common.CompositeKindEvent, v.EventType.ID(), v.EventType.Fields, v.Fields)
case cadence.Path:
return interpreter.PathValue{
Domain: common.PathDomainFromName(v.Domain),
Identifier: v.Identifier,
}
}

panic(fmt.Sprintf("cannot import value of type %T", value))
Expand Down Expand Up @@ -343,3 +350,10 @@ func importCompositeValue(
nil,
)
}

func exportPathValue(v interpreter.PathValue) cadence.Value {
return cadence.Path{
Domain: v.Domain.Name(),
Identifier: v.Identifier,
}
}
12 changes: 12 additions & 0 deletions runtime/convertValues_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/stretchr/testify/require"

"github.com/onflow/cadence"
"github.com/onflow/cadence/runtime/common"
"github.com/onflow/cadence/runtime/interpreter"
"github.com/onflow/cadence/runtime/sema"
"github.com/onflow/cadence/runtime/tests/utils"
Expand Down Expand Up @@ -193,6 +194,17 @@ var exportTests = []exportTest{
value: interpreter.UFix64Value(123000000),
expected: cadence.UFix64(123000000),
},
{
label: "Path",
value: interpreter.PathValue{
Domain: common.PathDomainStorage,
Identifier: "foo",
},
expected: cadence.Path{
Domain: "storage",
Identifier: "foo",
},
},
}

func TestExportValue(t *testing.T) {
Expand Down
17 changes: 17 additions & 0 deletions values.go
Original file line number Diff line number Diff line change
Expand Up @@ -1009,3 +1009,20 @@ func (v StorageReference) Type() Type {
func (v StorageReference) ToGoValue() interface{} {
return nil
}

// Path

type Path struct {
Domain string
Identifier string
}

func (Path) isValue() {}

func (Path) Type() Type {
return PathType{}
}

func (Path) ToGoValue() interface{} {
return nil
}

0 comments on commit a1e6124

Please sign in to comment.