Skip to content

Commit

Permalink
Add 32bit numeric getters which do not panic
Browse files Browse the repository at this point in the history
Add GetInt32, GetUint32 and GetFloat32 which return the default value
when the key value is out of range just like their 64bit variants.

The generic GetInt, GetUint and GetFloat methods panic.

Closes #75
  • Loading branch information
magiconair committed Dec 8, 2024
1 parent d8bdba3 commit b148584
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 b148584

Please sign in to comment.