Skip to content

Commit

Permalink
Merge pull request #77 from magiconair/get32bit
Browse files Browse the repository at this point in the history
Add 32bit numeric getters which do not panic
  • Loading branch information
magiconair authored Dec 8, 2024
2 parents d8bdba3 + b148584 commit 3dfc3b5
Show file tree
Hide file tree
Showing 2 changed files with 232 additions and 2 deletions.
102 changes: 102 additions & 0 deletions properties.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,40 @@ func (p *Properties) getFloat64(key string) (value float64, err error) {

// ----------------------------------------------------------------------------

// GetFloat32 parses the expanded value as a float32 if the key exists.
// If key does not exist or the value cannot be parsed the default
// value is returned.
func (p *Properties) GetFloat32(key string, def float32) float32 {
v, err := p.getFloat32(key)
if err != nil {
return def
}
return v
}

// MustGetFloat32 parses the expanded value as a float32 if the key exists.
// If key does not exist or the value cannot be parsed the function panics.
func (p *Properties) MustGetFloat32(key string) float32 {
v, err := p.getFloat32(key)
if err != nil {
ErrorHandler(err)
}
return v
}

func (p *Properties) getFloat32(key string) (value float32, err error) {
if v, ok := p.Get(key); ok {
n, err := strconv.ParseFloat(v, 32)
if err != nil {
return 0, err
}
return float32(n), nil
}
return 0, invalidKeyError(key)
}

// ----------------------------------------------------------------------------

// GetInt parses the expanded value as an int if the key exists.
// If key does not exist or the value cannot be parsed the default
// value is returned. If the value does not fit into an int the
Expand Down Expand Up @@ -366,6 +400,40 @@ func (p *Properties) getInt64(key string) (value int64, err error) {

// ----------------------------------------------------------------------------

// GetInt32 parses the expanded value as an int32 if the key exists.
// If key does not exist or the value cannot be parsed the default
// value is returned.
func (p *Properties) GetInt32(key string, def int32) int32 {
v, err := p.getInt32(key)
if err != nil {
return def
}
return v
}

// MustGetInt32 parses the expanded value as an int if the key exists.
// If key does not exist or the value cannot be parsed the function panics.
func (p *Properties) MustGetInt32(key string) int32 {
v, err := p.getInt32(key)
if err != nil {
ErrorHandler(err)
}
return v
}

func (p *Properties) getInt32(key string) (value int32, err error) {
if v, ok := p.Get(key); ok {
n, err := strconv.ParseInt(v, 10, 32)
if err != nil {
return 0, err
}
return int32(n), nil
}
return 0, invalidKeyError(key)
}

// ----------------------------------------------------------------------------

// GetUint parses the expanded value as an uint if the key exists.
// If key does not exist or the value cannot be parsed the default
// value is returned. If the value does not fit into an int the
Expand Down Expand Up @@ -426,6 +494,40 @@ func (p *Properties) getUint64(key string) (value uint64, err error) {

// ----------------------------------------------------------------------------

// GetUint32 parses the expanded value as an uint32 if the key exists.
// If key does not exist or the value cannot be parsed the default
// value is returned.
func (p *Properties) GetUint32(key string, def uint32) uint32 {
v, err := p.getUint32(key)
if err != nil {
return def
}
return v
}

// MustGetUint32 parses the expanded value as an int if the key exists.
// If key does not exist or the value cannot be parsed the function panics.
func (p *Properties) MustGetUint32(key string) uint32 {
v, err := p.getUint32(key)
if err != nil {
ErrorHandler(err)
}
return v
}

func (p *Properties) getUint32(key string) (value uint32, err error) {
if v, ok := p.Get(key); ok {
n, err := strconv.ParseUint(v, 10, 32)
if err != nil {
return 0, err
}
return uint32(n), nil
}
return 0, invalidKeyError(key)
}

// ----------------------------------------------------------------------------

// GetString returns the expanded value for the given key if exists or
// the default value otherwise.
func (p *Properties) GetString(key, def string) string {
Expand Down
132 changes: 130 additions & 2 deletions properties_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"os"
"reflect"
"regexp"
"strconv"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -262,7 +263,7 @@ var parsedDurationTests = []struct {

// ----------------------------------------------------------------------------

var floatTests = []struct {
var float64Tests = []struct {
input, key string
def, value float64
}{
Expand All @@ -274,6 +275,8 @@ var floatTests = []struct {
{"key = 0", "key", 999, 0},
{"key = -1", "key", 999, -1},
{"key = 0123", "key", 999, 123},
{"key = " + strconv.FormatFloat(math.SmallestNonzeroFloat64, 'f', -1, 64), "key", 999, math.SmallestNonzeroFloat64},
{"key = " + strconv.FormatFloat(math.MaxFloat64, 'f', -1, 64), "key", 999, math.MaxFloat64},

// invalid values
{"key = 0xff", "key", 999, 999},
Expand All @@ -285,6 +288,32 @@ var floatTests = []struct {

// ----------------------------------------------------------------------------

var float32Tests = []struct {
input, key string
def, value float32
}{
// valid values
{"key = 1.0", "key", 999, 1.0},
{"key = 0.0", "key", 999, 0.0},
{"key = -1.0", "key", 999, -1.0},
{"key = 1", "key", 999, 1},
{"key = 0", "key", 999, 0},
{"key = -1", "key", 999, -1},
{"key = 0123", "key", 999, 123},
{"key = " + strconv.FormatFloat(math.SmallestNonzeroFloat32, 'f', -1, 32), "key", 999, math.SmallestNonzeroFloat32},
{"key = " + strconv.FormatFloat(math.MaxFloat32, 'f', -1, 32), "key", 999, math.MaxFloat32},

// invalid values
{"key = 0xff", "key", 999, 999},
{"key = a", "key", 999, 999},
{"key = " + strconv.FormatFloat(math.MaxFloat32*10, 'f', -1, 64), "key", 999, 999},

// non existent key
{"key = 1", "key2", 999, 999},
}

// ----------------------------------------------------------------------------

var int64Tests = []struct {
input, key string
def, value int64
Expand All @@ -294,6 +323,8 @@ var int64Tests = []struct {
{"key = 0", "key", 999, 0},
{"key = -1", "key", 999, -1},
{"key = 0123", "key", 999, 123},
{"key = " + strconv.FormatInt(math.MinInt64, 10), "key", 999, math.MinInt64},
{"key = " + strconv.FormatInt(math.MaxInt64, 10), "key", 999, math.MaxInt64},

// invalid values
{"key = 0xff", "key", 999, 999},
Expand All @@ -306,6 +337,31 @@ var int64Tests = []struct {

// ----------------------------------------------------------------------------

var int32Tests = []struct {
input, key string
def, value int32
}{
// valid values
{"key = 1", "key", 999, 1},
{"key = 0", "key", 999, 0},
{"key = -1", "key", 999, -1},
{"key = 0123", "key", 999, 123},
{"key = " + strconv.FormatInt(math.MinInt32, 10), "key", 999, math.MinInt32},
{"key = " + strconv.FormatInt(math.MaxInt32, 10), "key", 999, math.MaxInt32},

// invalid values
{"key = 0xff", "key", 999, 999},
{"key = 1.0", "key", 999, 999},
{"key = a", "key", 999, 999},
{"key = " + strconv.FormatInt(math.MinInt32-1, 10), "key", 999, 999},
{"key = " + strconv.FormatInt(math.MaxInt32+1, 10), "key", 999, 999},

// non existent key
{"key = 1", "key2", 999, 999},
}

// ----------------------------------------------------------------------------

var uint64Tests = []struct {
input, key string
def, value uint64
Expand All @@ -314,12 +370,36 @@ var uint64Tests = []struct {
{"key = 1", "key", 999, 1},
{"key = 0", "key", 999, 0},
{"key = 0123", "key", 999, 123},
{"key = " + strconv.FormatUint(math.MaxUint64, 10), "key", 999, math.MaxUint64},

// invalid values
{"key = -1", "key", 999, 999},
{"key = 0xff", "key", 999, 999},
{"key = 1.0", "key", 999, 999},
{"key = a", "key", 999, 999},

// non existent key
{"key = 1", "key2", 999, 999},
}

// ----------------------------------------------------------------------------

var uint32Tests = []struct {
input, key string
def, value uint32
}{
// valid values
{"key = 1", "key", 999, 1},
{"key = 0", "key", 999, 0},
{"key = 0123", "key", 999, 123},
{"key = " + strconv.FormatUint(math.MaxUint32, 10), "key", 999, math.MaxUint32},

// invalid values
{"key = -1", "key", 999, 999},
{"key = 0xff", "key", 999, 999},
{"key = 1.0", "key", 999, 999},
{"key = a", "key", 999, 999},
{"key = " + strconv.FormatUint(math.MaxUint32+1, 10), "key", 999, 999},

// non existent key
{"key = 1", "key2", 999, 999},
Expand Down Expand Up @@ -555,7 +635,7 @@ func TestGetParsedDuration(t *testing.T) {
}

func TestGetFloat64(t *testing.T) {
for _, test := range floatTests {
for _, test := range float64Tests {
p := mustParse(t, test.input)
assert.Equal(t, p.Len(), 1)
assert.Equal(t, p.GetFloat64(test.key, test.def), test.value)
Expand All @@ -570,6 +650,22 @@ func TestMustGetFloat64(t *testing.T) {
assert.Panic(t, func() { p.MustGetFloat64("invalid") }, "unknown property: invalid")
}

func TestGetFloat32(t *testing.T) {
for _, test := range float32Tests {
p := mustParse(t, test.input)
assert.Equal(t, p.Len(), 1)
assert.Equal(t, p.GetFloat32(test.key, test.def), test.value)
}
}

func TestMustGetFloat32(t *testing.T) {
input := "key = 123\nkey2 = ghi"
p := mustParse(t, input)
assert.Equal(t, p.MustGetFloat32("key"), float32(123))
assert.Panic(t, func() { p.MustGetFloat32("key2") }, "strconv.ParseFloat: parsing.*")
assert.Panic(t, func() { p.MustGetFloat32("invalid") }, "unknown property: invalid")
}

func TestGetInt(t *testing.T) {
for _, test := range int64Tests {
p := mustParse(t, test.input)
Expand Down Expand Up @@ -602,6 +698,22 @@ func TestMustGetInt64(t *testing.T) {
assert.Panic(t, func() { p.MustGetInt64("invalid") }, "unknown property: invalid")
}

func TestGetInt32(t *testing.T) {
for _, test := range int32Tests {
p := mustParse(t, test.input)
assert.Equal(t, p.Len(), 1)
assert.Equal(t, p.GetInt32(test.key, test.def), test.value)
}
}

func TestMustGetInt32(t *testing.T) {
input := "key = 123\nkey2 = ghi"
p := mustParse(t, input)
assert.Equal(t, p.MustGetInt32("key"), int32(123))
assert.Panic(t, func() { p.MustGetInt32("key2") }, "strconv.ParseInt: parsing.*")
assert.Panic(t, func() { p.MustGetInt32("invalid") }, "unknown property: invalid")
}

func TestGetUint(t *testing.T) {
for _, test := range uint64Tests {
p := mustParse(t, test.input)
Expand Down Expand Up @@ -634,6 +746,22 @@ func TestMustGetUint64(t *testing.T) {
assert.Panic(t, func() { p.MustGetUint64("invalid") }, "unknown property: invalid")
}

func TestGetUint32(t *testing.T) {
for _, test := range uint32Tests {
p := mustParse(t, test.input)
assert.Equal(t, p.Len(), 1)
assert.Equal(t, p.GetUint32(test.key, test.def), test.value)
}
}

func TestMustGetUint32(t *testing.T) {
input := "key = 123\nkey2 = ghi"
p := mustParse(t, input)
assert.Equal(t, p.MustGetUint32("key"), uint32(123))
assert.Panic(t, func() { p.MustGetUint32("key2") }, "strconv.ParseUint: parsing.*")
assert.Panic(t, func() { p.MustGetUint32("invalid") }, "unknown property: invalid")
}

func TestGetString(t *testing.T) {
for _, test := range stringTests {
p := mustParse(t, test.input)
Expand Down

0 comments on commit 3dfc3b5

Please sign in to comment.