Documentation
¶
Overview ¶
Example ¶
package main
import (
"fmt"
"reflect"
"github.com/ChainSafe/gossamer/pkg/scale"
)
// ParentVDT is a VaryingDataType that consists of multiple nested VaryingDataType
// instances (aka. a rust enum containing multiple enum options)
type ParentVDT scale.VaryingDataType
// Set will set a VaryingDataTypeValue using the underlying VaryingDataType
func (pvdt *ParentVDT) Set(val scale.VaryingDataTypeValue) (err error) {
// cast to VaryingDataType to use VaryingDataType.Set method
vdt := scale.VaryingDataType(*pvdt)
err = vdt.Set(val)
if err != nil {
return
}
// store original ParentVDT with VaryingDataType that has been set
*pvdt = ParentVDT(vdt)
return
}
// Value will return value from underying VaryingDataType
func (pvdt *ParentVDT) Value() (val scale.VaryingDataTypeValue, err error) {
vdt := scale.VaryingDataType(*pvdt)
return vdt.Value()
}
// NewParentVDT is constructor for ParentVDT
func NewParentVDT() ParentVDT {
// use standard VaryingDataType constructor to construct a VaryingDataType
vdt, err := scale.NewVaryingDataType(NewChildVDT(), NewOtherChildVDT())
if err != nil {
panic(err)
}
// cast to ParentVDT
return ParentVDT(vdt)
}
// ChildVDT type is used as a VaryingDataTypeValue for ParentVDT
type ChildVDT scale.VaryingDataType
// Index fulfils the VaryingDataTypeValue interface. T
func (ChildVDT) Index() uint { //skipcq: GO-W1029
return 1
}
func (cvdt ChildVDT) String() string { //skipcq: GO-W1029
value, err := cvdt.Value()
if err != nil {
return "ChildVDT()"
}
return fmt.Sprintf("ChildVDT(%s)", value)
}
// Set will set a VaryingDataTypeValue using the underlying VaryingDataType
func (cvdt *ChildVDT) Set(val scale.VaryingDataTypeValue) (err error) { //skipcq: GO-W1029
// cast to VaryingDataType to use VaryingDataType.Set method
vdt := scale.VaryingDataType(*cvdt)
err = vdt.Set(val)
if err != nil {
return
}
// store original ParentVDT with VaryingDataType that has been set
*cvdt = ChildVDT(vdt)
return
}
// Value will return value from underying VaryingDataType
func (cvdt *ChildVDT) Value() (val scale.VaryingDataTypeValue, err error) { //skipcq: GO-W1029
vdt := scale.VaryingDataType(*cvdt)
return vdt.Value()
}
// NewChildVDT is constructor for ChildVDT
func NewChildVDT() ChildVDT {
// use standard VaryingDataType constructor to construct a VaryingDataType
// constarined to types ChildInt16, ChildStruct, and ChildString
vdt, err := scale.NewVaryingDataType(ChildInt16(0), ChildStruct{}, ChildString(""))
if err != nil {
panic(err)
}
// cast to ParentVDT
return ChildVDT(vdt)
}
// OtherChildVDT type is used as a VaryingDataTypeValue for ParentVDT
type OtherChildVDT scale.VaryingDataType
// Index fulfils the VaryingDataTypeValue interface.
func (OtherChildVDT) Index() uint { //skipcq: GO-W1029
return 2
}
func (cvdt OtherChildVDT) String() string { //skipcq: GO-W1029
vdt := scale.VaryingDataType(cvdt)
vdtPtr := &vdt
value, err := vdtPtr.Value()
if err != nil {
return "OtherChildVDT()"
}
return fmt.Sprintf("OtherChildVDT(%s)", value)
}
// Set will set a VaryingDataTypeValue using the underlying VaryingDataType
func (cvdt *OtherChildVDT) Set(val scale.VaryingDataTypeValue) (err error) { //skipcq: GO-W1029
// cast to VaryingDataType to use VaryingDataType.Set method
vdt := scale.VaryingDataType(*cvdt)
err = vdt.Set(val)
if err != nil {
return
}
// store original ParentVDT with VaryingDataType that has been set
*cvdt = OtherChildVDT(vdt)
return
}
// NewOtherChildVDT is constructor for OtherChildVDT
func NewOtherChildVDT() OtherChildVDT {
// use standard VaryingDataType constructor to construct a VaryingDataType
// constarined to types ChildInt16 and ChildStruct
vdt, err := scale.NewVaryingDataType(ChildInt16(0), ChildStruct{}, ChildString(""))
if err != nil {
panic(err)
}
// cast to ParentVDT
return OtherChildVDT(vdt)
}
// ChildInt16 is used as a VaryingDataTypeValue for ChildVDT and OtherChildVDT
type ChildInt16 int16
// Index fulfils the VaryingDataTypeValue interface. The ChildVDT type is used as a
// VaryingDataTypeValue for ParentVDT
func (ChildInt16) Index() uint {
return 1
}
func (c ChildInt16) String() string { return fmt.Sprintf("ChildInt16(%d)", c) }
// ChildStruct is used as a VaryingDataTypeValue for ChildVDT and OtherChildVDT
type ChildStruct struct {
A string
B bool
}
// Index fulfils the VaryingDataTypeValue interface
func (ChildStruct) Index() uint {
return 2
}
func (c ChildStruct) String() string {
return fmt.Sprintf("ChildStruct{A=%s, B=%t}", c.A, c.B)
}
// ChildString is used as a VaryingDataTypeValue for ChildVDT and OtherChildVDT
type ChildString string
// Index fulfils the VaryingDataTypeValue interface
func (ChildString) Index() uint {
return 3
}
func (c ChildString) String() string { return fmt.Sprintf("ChildString(%s)", string(c)) }
func main() {
parent := NewParentVDT()
// populate parent with ChildVDT
child := NewChildVDT()
child.Set(ChildInt16(888))
err := parent.Set(child)
if err != nil {
panic(err)
}
// validate ParentVDT.Value()
parentVal, err := parent.Value()
if err != nil {
panic(err)
}
fmt.Printf("parent.Value(): %+v\n", parentVal)
// should cast to ChildVDT, since that was set earlier
valChildVDT := parentVal.(ChildVDT)
// validate ChildVDT.Value() as ChildInt16(888)
childVdtValue, err := valChildVDT.Value()
if err != nil {
panic(err)
}
fmt.Printf("child.Value(): %+v\n", childVdtValue)
// marshal into scale encoded bytes
bytes, err := scale.Marshal(parent)
if err != nil {
panic(err)
}
fmt.Printf("bytes: % x\n", bytes)
// unmarshal into another ParentVDT
dstParent := NewParentVDT()
err = scale.Unmarshal(bytes, &dstParent)
if err != nil {
panic(err)
}
// assert both ParentVDT instances are the same
fmt.Println(reflect.DeepEqual(parent, dstParent))
}
Output: parent.Value(): ChildVDT(ChildInt16(888)) child.Value(): ChildInt16(888) bytes: 01 01 78 03 true
Index ¶
- Variables
- func Marshal(v interface{}) (b []byte, err error)
- func MustMarshal(v interface{}) (b []byte)
- func Unmarshal(data []byte, dst interface{}) (err error)
- type Decoder
- type Encoder
- type Marshaler
- type Result
- type ResultMode
- type Uint128
- type Unmarshaler
- type UnsetResult
- type VaryingDataType
- type VaryingDataTypeSlice
- type VaryingDataTypeValue
- type WrappedErr
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrU16OutOfRange = errors.New("uint16 out of range") ErrU32OutOfRange = errors.New("uint32 out of range") ErrU64OutOfRange = errors.New("uint64 out of range") ErrU64NotSupported = errors.New("uint64 is not supported") ErrCompactUintPrefixUnknown = errors.New("unknown prefix for compact uint") )
var ( ErrUnsupportedDestination = errors.New("must be a non-nil pointer to a destination") ErrUnsupportedType = errors.New("unsupported type") ErrUnsupportedResult = errors.New("unsupported result") ErrResultNotSet = errors.New("result not set") ErrResultAlreadySet = errors.New("result already has an assigned value") ErrUnsupportedVaryingDataTypeValue = errors.New("unsupported VaryingDataTypeValue") ErrMustProvideVaryingDataTypeValue = errors.New("must provide at least one VaryingDataTypeValue") ErrVaryingDataTypeNotSet = errors.New("varying data type not set") ErrUnsupportedCustomPrimitive = errors.New("unsupported type for custom primitive") ErrInvalidScaleIndex = errors.New("invalid scale index") )
var MaxUint128 = &Uint128{ Upper: ^uint64(0), Lower: ^uint64(0), }
MaxUint128 is the maximum uint128 value
Functions ¶
func MustMarshal ¶ added in v0.8.0
func MustMarshal(v interface{}) (b []byte)
MustMarshal runs Marshal and panics on error.
Types ¶
type Decoder ¶
type Decoder struct {
// contains filtered or unexported fields
}
Decoder is used to decode from an io.Reader
type Encoder ¶
type Encoder struct {
// contains filtered or unexported fields
}
Encoder scale encodes to a given io.Writer.
func NewEncoder ¶
NewEncoder creates a new encoder with the given writer.
type Marshaler ¶ added in v0.8.0
Marshaler is the interface for custom SCALE marshalling for a given type
type Result ¶
type Result struct {
// contains filtered or unexported fields
}
Result encapsulates an Ok or an Err case
Example ¶
package main
import (
"fmt"
"github.com/ChainSafe/gossamer/pkg/scale"
)
func main() {
// pass in zero or non-zero values of the types for Ok and Err cases
res := scale.NewResult(bool(false), string(""))
// set the OK case with a value of true, any values for OK that are not bool will return an error
err := res.Set(scale.OK, true)
if err != nil {
panic(err)
}
bytes, err := scale.Marshal(res)
if err != nil {
panic(err)
}
// [0x00, 0x01]
fmt.Printf("%v\n", bytes)
res1 := scale.NewResult(bool(false), string(""))
err = scale.Unmarshal(bytes, &res1)
if err != nil {
panic(err)
}
// res1 should be Set with OK mode and value of true
ok, err := res1.Unwrap()
if err != nil {
panic(err)
}
switch ok := ok.(type) {
case bool:
if !ok {
panic(fmt.Errorf("unexpected ok value: %v", ok))
}
default:
panic(fmt.Errorf("unexpected type: %T", ok))
}
}
func NewResult ¶
func NewResult(okIn, errIn interface{}) (res Result)
NewResult is constructor for Result. Use nil to represent empty tuple () in Rust.
func (*Result) Set ¶
func (r *Result) Set(mode ResultMode, in interface{}) (err error)
Set takes in a mode (OK/Err) and the associated interface and sets the Result value
type ResultMode ¶
type ResultMode int
ResultMode is the mode the Result is set to
const ( // Unset ResultMode is zero value mode Unset ResultMode = iota // OK case OK // Err case Err )
type Uint128 ¶
Uint128 represents an unsigned 128 bit integer
func MustNewUint128 ¶
MustNewUint128 will panic if NewUint128 returns an error
func NewUint128 ¶
NewUint128 is constructor for Uint128 that accepts an option binary.ByteOrder option is only used when inputted interface{} is of type []byte by default binary.LittleEndian is used for []byte since this is SCALE
func (*Uint128) Bytes ¶
Bytes returns the Uint128 in little endian format by default. A variadic parameter order can be used to specify the binary.ByteOrder used
func (*Uint128) Compare ¶
Compare returns 1 if the receiver is greater than other, 0 if they are equal, and -1 otherwise.
func (Uint128) MarshalJSON ¶ added in v0.8.0
MarshalJSON converts Uint128 to []byte.
func (*Uint128) UnmarshalJSON ¶
UnmarshalJSON converts data to Uint128.
type Unmarshaler ¶ added in v0.8.0
Unmarshaler is the interface for custom SCALE unmarshalling for a given type
type VaryingDataType ¶
type VaryingDataType struct {
// contains filtered or unexported fields
}
VaryingDataType is analogous to a rust enum. Name is taken from polkadot spec.
Example ¶
package main
import (
"fmt"
"reflect"
"github.com/ChainSafe/gossamer/pkg/scale"
)
type MyStruct struct {
Baz bool
Bar uint32
Foo []byte
}
func (MyStruct) Index() uint {
return 1
}
func (m MyStruct) String() string {
return fmt.Sprintf("MyStruct{Baz: %t, Bar: %d, Foo: %x}", m.Baz, m.Bar, m.Foo)
}
type MyOtherStruct struct {
Foo string
Bar uint64
Baz uint
}
func (MyOtherStruct) Index() uint {
return 2
}
func (m MyOtherStruct) String() string {
return fmt.Sprintf("MyOtherStruct{Foo: %s, Bar: %d, Baz: %d}", m.Foo, m.Bar, m.Baz)
}
type MyInt16 int16
func (MyInt16) Index() uint {
return 3
}
func (m MyInt16) String() string { return fmt.Sprintf("MyInt16(%d)", m) }
func main() {
vdt, err := scale.NewVaryingDataType(MyStruct{}, MyOtherStruct{}, MyInt16(0))
if err != nil {
panic(err)
}
err = vdt.Set(MyStruct{
Baz: true,
Bar: 999,
Foo: []byte{1, 2},
})
if err != nil {
panic(err)
}
bytes, err := scale.Marshal(vdt)
if err != nil {
panic(err)
}
vdt1, err := scale.NewVaryingDataType(MyStruct{}, MyOtherStruct{}, MyInt16(0))
if err != nil {
panic(err)
}
err = scale.Unmarshal(bytes, &vdt1)
if err != nil {
panic(err)
}
if !reflect.DeepEqual(vdt, vdt1) {
panic(fmt.Errorf("uh oh: %+v %+v", vdt, vdt1))
}
}
func MustNewVaryingDataType ¶
func MustNewVaryingDataType(values ...VaryingDataTypeValue) (vdt VaryingDataType)
MustNewVaryingDataType is constructor for VaryingDataType
func NewVaryingDataType ¶
func NewVaryingDataType(values ...VaryingDataTypeValue) (vdt VaryingDataType, err error)
NewVaryingDataType is constructor for VaryingDataType
func (*VaryingDataType) Set ¶
func (vdt *VaryingDataType) Set(value VaryingDataTypeValue) (err error)
Set will set the VaryingDataType value
func (*VaryingDataType) String ¶ added in v0.8.0
func (vdt *VaryingDataType) String() string
func (*VaryingDataType) Value ¶
func (vdt *VaryingDataType) Value() (VaryingDataTypeValue, error)
Value returns value stored in vdt
type VaryingDataTypeSlice ¶
type VaryingDataTypeSlice struct {
VaryingDataType
Types []VaryingDataType
}
VaryingDataTypeSlice is used to represent []VaryingDataType. SCALE requires knowledge of the underlying data, so it is required to have the VaryingDataType required for decoding
Example ¶
package main
import (
"fmt"
"reflect"
"github.com/ChainSafe/gossamer/pkg/scale"
)
type MyStruct struct {
Baz bool
Bar uint32
Foo []byte
}
func (MyStruct) Index() uint {
return 1
}
func (m MyStruct) String() string {
return fmt.Sprintf("MyStruct{Baz: %t, Bar: %d, Foo: %x}", m.Baz, m.Bar, m.Foo)
}
type MyOtherStruct struct {
Foo string
Bar uint64
Baz uint
}
func (MyOtherStruct) Index() uint {
return 2
}
func (m MyOtherStruct) String() string {
return fmt.Sprintf("MyOtherStruct{Foo: %s, Bar: %d, Baz: %d}", m.Foo, m.Bar, m.Baz)
}
type MyInt16 int16
func (MyInt16) Index() uint {
return 3
}
func (m MyInt16) String() string { return fmt.Sprintf("MyInt16(%d)", m) }
func main() {
vdt, err := scale.NewVaryingDataType(MyStruct{}, MyOtherStruct{}, MyInt16(0))
if err != nil {
panic(err)
}
vdts := scale.NewVaryingDataTypeSlice(vdt)
err = vdts.Add(
MyStruct{
Baz: true,
Bar: 999,
Foo: []byte{1, 2},
},
MyInt16(1),
)
if err != nil {
panic(err)
}
bytes, err := scale.Marshal(vdts)
if err != nil {
panic(err)
}
vdts1 := scale.NewVaryingDataTypeSlice(vdt)
if err != nil {
panic(err)
}
err = scale.Unmarshal(bytes, &vdts1)
if err != nil {
panic(err)
}
if !reflect.DeepEqual(vdts, vdts1) {
panic(fmt.Errorf("uh oh: %+v %+v", vdts, vdts1))
}
}
func NewVaryingDataTypeSlice ¶
func NewVaryingDataTypeSlice(vdt VaryingDataType) (vdts VaryingDataTypeSlice)
NewVaryingDataTypeSlice is constructor for VaryingDataTypeSlice
func (*VaryingDataTypeSlice) Add ¶
func (vdts *VaryingDataTypeSlice) Add(values ...VaryingDataTypeValue) (err error)
Add takes variadic parameter values to add VaryingDataTypeValue(s)
func (VaryingDataTypeSlice) String ¶ added in v0.8.0
func (vdts VaryingDataTypeSlice) String() string
type VaryingDataTypeValue ¶
type VaryingDataTypeValue interface {
Index() uint
}
VaryingDataTypeValue is used to represent scale encodable types of an associated VaryingDataType
type WrappedErr ¶
type WrappedErr struct {
Err interface{}
}
WrappedErr is returned by Result.Unwrap(). The underlying Err value is wrapped and stored in Err attribute