Add JSON unmarshallers for numeric types from util (#83)
Uint160, Uint256, Fixed8 now have UnmarshalJSON method.
This commit is contained in:
parent
35551282b0
commit
1d9045877c
8 changed files with 110 additions and 4 deletions
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
0.44.2
|
0.44.3
|
||||||
|
|
|
@ -2,6 +2,7 @@ package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -49,7 +50,8 @@ func NewFixed8(val int) Fixed8 {
|
||||||
return Fixed8(decimals * val)
|
return Fixed8(decimals * val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fixed8DecodeString
|
// Fixed8DecodeString parses s which must be a fixed point number
|
||||||
|
// with precision up to 10^-8
|
||||||
func Fixed8DecodeString(s string) (Fixed8, error) {
|
func Fixed8DecodeString(s string) (Fixed8, error) {
|
||||||
parts := strings.SplitN(s, ".", 2)
|
parts := strings.SplitN(s, ".", 2)
|
||||||
ip, err := strconv.Atoi(parts[0])
|
ip, err := strconv.Atoi(parts[0])
|
||||||
|
@ -68,3 +70,24 @@ func Fixed8DecodeString(s string) (Fixed8, error) {
|
||||||
}
|
}
|
||||||
return Fixed8(ip*decimals + fp), nil
|
return Fixed8(ip*decimals + fp), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements the json unmarshaller interface.
|
||||||
|
func (f *Fixed8) UnmarshalJSON(data []byte) error {
|
||||||
|
var s string
|
||||||
|
if err := json.Unmarshal(data, &s); err == nil {
|
||||||
|
p, err := Fixed8DecodeString(s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*f = p
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var fl float64
|
||||||
|
if err := json.Unmarshal(data, &fl); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*f = Fixed8(decimals * fl)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
@ -18,7 +19,7 @@ func TestNewFixed8(t *testing.T) {
|
||||||
func TestFixed8DecodeString(t *testing.T) {
|
func TestFixed8DecodeString(t *testing.T) {
|
||||||
// Fixed8DecodeString works correctly with integers
|
// Fixed8DecodeString works correctly with integers
|
||||||
ivalues := []string{"9000", "100000000", "5", "10945"}
|
ivalues := []string{"9000", "100000000", "5", "10945"}
|
||||||
for _, val:= range ivalues {
|
for _, val := range ivalues {
|
||||||
n, err := Fixed8DecodeString(val)
|
n, err := Fixed8DecodeString(val)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, val, n.String())
|
assert.Equal(t, val, n.String())
|
||||||
|
@ -36,3 +37,21 @@ func TestFixed8DecodeString(t *testing.T) {
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, Fixed8(90123410000), n)
|
assert.Equal(t, Fixed8(90123410000), n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFixed8UnmarshalJSON(t *testing.T) {
|
||||||
|
fl := float64(123.45)
|
||||||
|
str := "123.45"
|
||||||
|
expected, _ := Fixed8DecodeString(str)
|
||||||
|
|
||||||
|
// UnmarshalJSON should decode floats
|
||||||
|
var u1 Fixed8
|
||||||
|
s, _ := json.Marshal(fl)
|
||||||
|
assert.Nil(t, json.Unmarshal(s, &u1))
|
||||||
|
assert.Equal(t, expected, u1)
|
||||||
|
|
||||||
|
// UnmarshalJSON should decode strings
|
||||||
|
var u2 Fixed8
|
||||||
|
s, _ = json.Marshal(str)
|
||||||
|
assert.Nil(t, json.Unmarshal(s, &u2))
|
||||||
|
assert.Equal(t, expected, u2)
|
||||||
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ func RandomString(n int) string {
|
||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RamdomInt returns a ramdom integer betweeen min and max.
|
// RandomInt returns a ramdom integer betweeen min and max.
|
||||||
func RandomInt(min, max int) int {
|
func RandomInt(min, max int) int {
|
||||||
return min + rand.Intn(max-min)
|
return min + rand.Intn(max-min)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"golang.org/x/crypto/ripemd160"
|
"golang.org/x/crypto/ripemd160"
|
||||||
)
|
)
|
||||||
|
@ -77,6 +78,19 @@ func (u Uint160) Equals(other Uint160) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements the json unmarshaller interface.
|
||||||
|
func (u *Uint160) UnmarshalJSON(data []byte) (err error) {
|
||||||
|
var js string
|
||||||
|
if err = json.Unmarshal(data, &js); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(js, "0x") {
|
||||||
|
js = js[2:]
|
||||||
|
}
|
||||||
|
*u, err = Uint160DecodeString(js)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// MarshalJSON implements the json marshaller interface.
|
// MarshalJSON implements the json marshaller interface.
|
||||||
func (u Uint160) MarshalJSON() ([]byte, error) {
|
func (u Uint160) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(
|
return json.Marshal(
|
||||||
|
|
|
@ -2,11 +2,29 @@ package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestUint160UnmarshalJSON(t *testing.T) {
|
||||||
|
str := "2d3b96ae1bcc5a585e075e3b81920210dec16302"
|
||||||
|
expected, _ := Uint160DecodeString(str)
|
||||||
|
|
||||||
|
// UnmarshalJSON should decode hex-strings
|
||||||
|
var u1 Uint160
|
||||||
|
s, _ := json.Marshal(str)
|
||||||
|
assert.Nil(t, json.Unmarshal(s, &u1))
|
||||||
|
assert.True(t, expected.Equals(u1))
|
||||||
|
|
||||||
|
// UnmarshalJSON should decode hex-strings prefixed by 0x
|
||||||
|
var u2 Uint160
|
||||||
|
s, _ = json.Marshal("0x" + str)
|
||||||
|
assert.Nil(t, json.Unmarshal(s, &u2))
|
||||||
|
assert.True(t, expected.Equals(u2))
|
||||||
|
}
|
||||||
|
|
||||||
func TestUInt160DecodeString(t *testing.T) {
|
func TestUInt160DecodeString(t *testing.T) {
|
||||||
hexStr := "2d3b96ae1bcc5a585e075e3b81920210dec16302"
|
hexStr := "2d3b96ae1bcc5a585e075e3b81920210dec16302"
|
||||||
val, err := Uint160DecodeString(hexStr)
|
val, err := Uint160DecodeString(hexStr)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const uint256Size = 32
|
const uint256Size = 32
|
||||||
|
@ -59,6 +60,19 @@ func (u Uint256) String() string {
|
||||||
return hex.EncodeToString(ArrayReverse(u.Bytes()))
|
return hex.EncodeToString(ArrayReverse(u.Bytes()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements the json unmarshaller interface.
|
||||||
|
func (u *Uint256) UnmarshalJSON(data []byte) (err error) {
|
||||||
|
var js string
|
||||||
|
if err = json.Unmarshal(data, &js); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(js, "0x") {
|
||||||
|
js = js[2:]
|
||||||
|
}
|
||||||
|
*u, err = Uint256DecodeString(js)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// MarshalJSON implements the json marshaller interface.
|
// MarshalJSON implements the json marshaller interface.
|
||||||
func (u Uint256) MarshalJSON() ([]byte, error) {
|
func (u Uint256) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(fmt.Sprintf("0x%s", u.String()))
|
return json.Marshal(fmt.Sprintf("0x%s", u.String()))
|
||||||
|
|
|
@ -2,11 +2,29 @@ package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestUint256UnmarshalJSON(t *testing.T) {
|
||||||
|
str := "f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d"
|
||||||
|
expected, _ := Uint256DecodeString(str)
|
||||||
|
|
||||||
|
// UnmarshalJSON should decode hex-strings
|
||||||
|
var u1 Uint256
|
||||||
|
s, _ := json.Marshal(str)
|
||||||
|
assert.Nil(t, json.Unmarshal(s, &u1))
|
||||||
|
assert.True(t, expected.Equals(u1))
|
||||||
|
|
||||||
|
// UnmarshalJSON should decode hex-strings prefixed by 0x
|
||||||
|
var u2 Uint256
|
||||||
|
s, _ = json.Marshal("0x" + str)
|
||||||
|
assert.Nil(t, json.Unmarshal(s, &u2))
|
||||||
|
assert.True(t, expected.Equals(u2))
|
||||||
|
}
|
||||||
|
|
||||||
func TestUint256DecodeString(t *testing.T) {
|
func TestUint256DecodeString(t *testing.T) {
|
||||||
hexStr := "f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d"
|
hexStr := "f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d"
|
||||||
val, err := Uint256DecodeString(hexStr)
|
val, err := Uint256DecodeString(hexStr)
|
||||||
|
|
Loading…
Reference in a new issue