Skip to content

Commit

Permalink
implement MustFromHex, MustFromDecimal (#131)
Browse files Browse the repository at this point in the history
The PR #128 added MustFromBig, this PR adds two similar helpers: MustFromHex and MustFromDecimal.

	// MustFromHex is a convenience-constructor to create an Int from
	// a hexadecimal string.
	// Returns a new Int and panics if any error occurred.
	func MustFromHex(hex string) *Int
	
	// MustFromDecimal is a convenience-constructor to create an Int from a
	// decimal (base 10) string.
	// Returns a new Int and panics if any error occurred.
	func MustFromDecimal(decimal string) *Int
  • Loading branch information
holiman authored Mar 22, 2023
1 parent 01ef9cd commit 29b48c8
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 21 deletions.
11 changes: 11 additions & 0 deletions conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,17 @@ func FromHex(hex string) (*Int, error) {
return &z, nil
}

// MustFromHex is a convenience-constructor to create an Int from
// a hexadecimal string.
// Returns a new Int and panics if any error occurred.
func MustFromHex(hex string) *Int {
var z Int
if err := z.fromHex(hex); err != nil {
panic(err)
}
return &z
}

// UnmarshalText implements encoding.TextUnmarshaler
func (z *Int) UnmarshalText(input []byte) error {
z.Clear()
Expand Down
47 changes: 26 additions & 21 deletions conversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,19 +81,9 @@ func TestFromBig(t *testing.T) {
if !b.Eq(new(Int)) {
t.Fatalf("got %x exp 0", b.Bytes())
}
done := make(chan struct{})
go func() {
defer func() {
o = recover() != nil
done <- struct{}{}
}()
MustFromBig(a)
}()
<-done
if !o {
if !causesPanic(func() { MustFromBig(a) }) {
t.Fatalf("expected overflow")
}

a.Sub(a, big.NewInt(1))
b, o = FromBig(a)
if o {
Expand Down Expand Up @@ -199,16 +189,7 @@ func TestFromBigOverflow(t *testing.T) {
t.Errorf("expected overflow, got %v", o)
}
// Test overflow with panic (recovery is a bit unwieldy)
done := make(chan struct{})
go func() {
defer func() {
o = recover() != nil
done <- struct{}{}
}()
MustFromBig(b)
}()
<-done
if !o {
if !causesPanic(func() { MustFromBig(b) }) {
t.Fatalf("expected overflow")
}
// Test no overflow
Expand Down Expand Up @@ -1159,9 +1140,29 @@ func TestEncode(t *testing.T) {
}
}

// causesPanic returns true if panic occurred when executing fn.
func causesPanic(fn func()) bool {
done := make(chan struct{})
var ok bool
go func() {
defer func() {
ok = recover() != nil
done <- struct{}{}
}()
fn()
}()
<-done
return ok
}

func TestDecode(t *testing.T) {
for _, test := range decodeBigTests {
dec, err := FromHex(test.input)
if err != nil {
if !causesPanic(func() { MustFromHex(test.input) }) {
t.Fatalf("expected panic")
}
}
if !checkError(t, test.input, err, test.wantErr) {
continue
}
Expand All @@ -1170,6 +1171,10 @@ func TestDecode(t *testing.T) {
t.Errorf("input %s: value mismatch: got %x, want %x", test.input, dec, test.want)
continue
}
d2 := MustFromHex(test.input)
if !d2.Eq(dec) {
t.Errorf("input %s: value mismatch: got %x, want %x", test.input, d2, dec)
}
}
// Some remaining json-tests
type jsonStruct struct {
Expand Down
11 changes: 11 additions & 0 deletions decimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,17 @@ func FromDecimal(decimal string) (*Int, error) {
return &z, nil
}

// MustFromDecimal is a convenience-constructor to create an Int from a
// decimal (base 10) string.
// Returns a new Int and panics if any error occurred.
func MustFromDecimal(decimal string) *Int {
var z Int
if err := z.SetFromDecimal(decimal); err != nil {
panic(err)
}
return &z
}

// SetFromDecimal sets z from the given string, interpreted as a decimal number.
// OBS! This method is _not_ strictly identical to the (*big.Int).SetString(..., 10) method.
// Notable differences:
Expand Down
9 changes: 9 additions & 0 deletions decimal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package uint256

import (
"errors"
"fmt"
"math/big"
"testing"
Expand All @@ -19,6 +20,14 @@ func testSetFromDec(tc string) error {
if (err == nil) != (err2 == nil) {
return fmt.Errorf("err != err2: %v %v", err, err2)
}
// Test the MustFromDecimal too
if err != nil {
if !causesPanic(func() { MustFromDecimal(tc) }) {
return errors.New("expected panic")
}
} else {
MustFromDecimal(tc) // must not manic
}
if err == nil {
if a.Cmp(b) != 0 {
return fmt.Errorf("a != b: %v %v", a, b)
Expand Down

0 comments on commit 29b48c8

Please sign in to comment.