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)) } }
Output:
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)) } }
Output:
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)) } }
Output:
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