Skip to content

Commit b148584

Browse files
committed
Add 32bit numeric getters which do not panic
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
1 parent d8bdba3 commit b148584

File tree

2 files changed

+232
-2
lines changed

2 files changed

+232
-2
lines changed

properties.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,40 @@ func (p *Properties) getFloat64(key string) (value float64, err error) {
306306

307307
// ----------------------------------------------------------------------------
308308

309+
// GetFloat32 parses the expanded value as a float32 if the key exists.
310+
// If key does not exist or the value cannot be parsed the default
311+
// value is returned.
312+
func (p *Properties) GetFloat32(key string, def float32) float32 {
313+
v, err := p.getFloat32(key)
314+
if err != nil {
315+
return def
316+
}
317+
return v
318+
}
319+
320+
// MustGetFloat32 parses the expanded value as a float32 if the key exists.
321+
// If key does not exist or the value cannot be parsed the function panics.
322+
func (p *Properties) MustGetFloat32(key string) float32 {
323+
v, err := p.getFloat32(key)
324+
if err != nil {
325+
ErrorHandler(err)
326+
}
327+
return v
328+
}
329+
330+
func (p *Properties) getFloat32(key string) (value float32, err error) {
331+
if v, ok := p.Get(key); ok {
332+
n, err := strconv.ParseFloat(v, 32)
333+
if err != nil {
334+
return 0, err
335+
}
336+
return float32(n), nil
337+
}
338+
return 0, invalidKeyError(key)
339+
}
340+
341+
// ----------------------------------------------------------------------------
342+
309343
// GetInt parses the expanded value as an int if the key exists.
310344
// If key does not exist or the value cannot be parsed the default
311345
// value is returned. If the value does not fit into an int the
@@ -366,6 +400,40 @@ func (p *Properties) getInt64(key string) (value int64, err error) {
366400

367401
// ----------------------------------------------------------------------------
368402

403+
// GetInt32 parses the expanded value as an int32 if the key exists.
404+
// If key does not exist or the value cannot be parsed the default
405+
// value is returned.
406+
func (p *Properties) GetInt32(key string, def int32) int32 {
407+
v, err := p.getInt32(key)
408+
if err != nil {
409+
return def
410+
}
411+
return v
412+
}
413+
414+
// MustGetInt32 parses the expanded value as an int if the key exists.
415+
// If key does not exist or the value cannot be parsed the function panics.
416+
func (p *Properties) MustGetInt32(key string) int32 {
417+
v, err := p.getInt32(key)
418+
if err != nil {
419+
ErrorHandler(err)
420+
}
421+
return v
422+
}
423+
424+
func (p *Properties) getInt32(key string) (value int32, err error) {
425+
if v, ok := p.Get(key); ok {
426+
n, err := strconv.ParseInt(v, 10, 32)
427+
if err != nil {
428+
return 0, err
429+
}
430+
return int32(n), nil
431+
}
432+
return 0, invalidKeyError(key)
433+
}
434+
435+
// ----------------------------------------------------------------------------
436+
369437
// GetUint parses the expanded value as an uint if the key exists.
370438
// If key does not exist or the value cannot be parsed the default
371439
// value is returned. If the value does not fit into an int the
@@ -426,6 +494,40 @@ func (p *Properties) getUint64(key string) (value uint64, err error) {
426494

427495
// ----------------------------------------------------------------------------
428496

497+
// GetUint32 parses the expanded value as an uint32 if the key exists.
498+
// If key does not exist or the value cannot be parsed the default
499+
// value is returned.
500+
func (p *Properties) GetUint32(key string, def uint32) uint32 {
501+
v, err := p.getUint32(key)
502+
if err != nil {
503+
return def
504+
}
505+
return v
506+
}
507+
508+
// MustGetUint32 parses the expanded value as an int if the key exists.
509+
// If key does not exist or the value cannot be parsed the function panics.
510+
func (p *Properties) MustGetUint32(key string) uint32 {
511+
v, err := p.getUint32(key)
512+
if err != nil {
513+
ErrorHandler(err)
514+
}
515+
return v
516+
}
517+
518+
func (p *Properties) getUint32(key string) (value uint32, err error) {
519+
if v, ok := p.Get(key); ok {
520+
n, err := strconv.ParseUint(v, 10, 32)
521+
if err != nil {
522+
return 0, err
523+
}
524+
return uint32(n), nil
525+
}
526+
return 0, invalidKeyError(key)
527+
}
528+
529+
// ----------------------------------------------------------------------------
530+
429531
// GetString returns the expanded value for the given key if exists or
430532
// the default value otherwise.
431533
func (p *Properties) GetString(key, def string) string {

properties_test.go

Lines changed: 130 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"os"
1212
"reflect"
1313
"regexp"
14+
"strconv"
1415
"strings"
1516
"testing"
1617
"time"
@@ -262,7 +263,7 @@ var parsedDurationTests = []struct {
262263

263264
// ----------------------------------------------------------------------------
264265

265-
var floatTests = []struct {
266+
var float64Tests = []struct {
266267
input, key string
267268
def, value float64
268269
}{
@@ -274,6 +275,8 @@ var floatTests = []struct {
274275
{"key = 0", "key", 999, 0},
275276
{"key = -1", "key", 999, -1},
276277
{"key = 0123", "key", 999, 123},
278+
{"key = " + strconv.FormatFloat(math.SmallestNonzeroFloat64, 'f', -1, 64), "key", 999, math.SmallestNonzeroFloat64},
279+
{"key = " + strconv.FormatFloat(math.MaxFloat64, 'f', -1, 64), "key", 999, math.MaxFloat64},
277280

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

286289
// ----------------------------------------------------------------------------
287290

291+
var float32Tests = []struct {
292+
input, key string
293+
def, value float32
294+
}{
295+
// valid values
296+
{"key = 1.0", "key", 999, 1.0},
297+
{"key = 0.0", "key", 999, 0.0},
298+
{"key = -1.0", "key", 999, -1.0},
299+
{"key = 1", "key", 999, 1},
300+
{"key = 0", "key", 999, 0},
301+
{"key = -1", "key", 999, -1},
302+
{"key = 0123", "key", 999, 123},
303+
{"key = " + strconv.FormatFloat(math.SmallestNonzeroFloat32, 'f', -1, 32), "key", 999, math.SmallestNonzeroFloat32},
304+
{"key = " + strconv.FormatFloat(math.MaxFloat32, 'f', -1, 32), "key", 999, math.MaxFloat32},
305+
306+
// invalid values
307+
{"key = 0xff", "key", 999, 999},
308+
{"key = a", "key", 999, 999},
309+
{"key = " + strconv.FormatFloat(math.MaxFloat32*10, 'f', -1, 64), "key", 999, 999},
310+
311+
// non existent key
312+
{"key = 1", "key2", 999, 999},
313+
}
314+
315+
// ----------------------------------------------------------------------------
316+
288317
var int64Tests = []struct {
289318
input, key string
290319
def, value int64
@@ -294,6 +323,8 @@ var int64Tests = []struct {
294323
{"key = 0", "key", 999, 0},
295324
{"key = -1", "key", 999, -1},
296325
{"key = 0123", "key", 999, 123},
326+
{"key = " + strconv.FormatInt(math.MinInt64, 10), "key", 999, math.MinInt64},
327+
{"key = " + strconv.FormatInt(math.MaxInt64, 10), "key", 999, math.MaxInt64},
297328

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

307338
// ----------------------------------------------------------------------------
308339

340+
var int32Tests = []struct {
341+
input, key string
342+
def, value int32
343+
}{
344+
// valid values
345+
{"key = 1", "key", 999, 1},
346+
{"key = 0", "key", 999, 0},
347+
{"key = -1", "key", 999, -1},
348+
{"key = 0123", "key", 999, 123},
349+
{"key = " + strconv.FormatInt(math.MinInt32, 10), "key", 999, math.MinInt32},
350+
{"key = " + strconv.FormatInt(math.MaxInt32, 10), "key", 999, math.MaxInt32},
351+
352+
// invalid values
353+
{"key = 0xff", "key", 999, 999},
354+
{"key = 1.0", "key", 999, 999},
355+
{"key = a", "key", 999, 999},
356+
{"key = " + strconv.FormatInt(math.MinInt32-1, 10), "key", 999, 999},
357+
{"key = " + strconv.FormatInt(math.MaxInt32+1, 10), "key", 999, 999},
358+
359+
// non existent key
360+
{"key = 1", "key2", 999, 999},
361+
}
362+
363+
// ----------------------------------------------------------------------------
364+
309365
var uint64Tests = []struct {
310366
input, key string
311367
def, value uint64
@@ -314,12 +370,36 @@ var uint64Tests = []struct {
314370
{"key = 1", "key", 999, 1},
315371
{"key = 0", "key", 999, 0},
316372
{"key = 0123", "key", 999, 123},
373+
{"key = " + strconv.FormatUint(math.MaxUint64, 10), "key", 999, math.MaxUint64},
374+
375+
// invalid values
376+
{"key = -1", "key", 999, 999},
377+
{"key = 0xff", "key", 999, 999},
378+
{"key = 1.0", "key", 999, 999},
379+
{"key = a", "key", 999, 999},
380+
381+
// non existent key
382+
{"key = 1", "key2", 999, 999},
383+
}
384+
385+
// ----------------------------------------------------------------------------
386+
387+
var uint32Tests = []struct {
388+
input, key string
389+
def, value uint32
390+
}{
391+
// valid values
392+
{"key = 1", "key", 999, 1},
393+
{"key = 0", "key", 999, 0},
394+
{"key = 0123", "key", 999, 123},
395+
{"key = " + strconv.FormatUint(math.MaxUint32, 10), "key", 999, math.MaxUint32},
317396

318397
// invalid values
319398
{"key = -1", "key", 999, 999},
320399
{"key = 0xff", "key", 999, 999},
321400
{"key = 1.0", "key", 999, 999},
322401
{"key = a", "key", 999, 999},
402+
{"key = " + strconv.FormatUint(math.MaxUint32+1, 10), "key", 999, 999},
323403

324404
// non existent key
325405
{"key = 1", "key2", 999, 999},
@@ -555,7 +635,7 @@ func TestGetParsedDuration(t *testing.T) {
555635
}
556636

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

653+
func TestGetFloat32(t *testing.T) {
654+
for _, test := range float32Tests {
655+
p := mustParse(t, test.input)
656+
assert.Equal(t, p.Len(), 1)
657+
assert.Equal(t, p.GetFloat32(test.key, test.def), test.value)
658+
}
659+
}
660+
661+
func TestMustGetFloat32(t *testing.T) {
662+
input := "key = 123\nkey2 = ghi"
663+
p := mustParse(t, input)
664+
assert.Equal(t, p.MustGetFloat32("key"), float32(123))
665+
assert.Panic(t, func() { p.MustGetFloat32("key2") }, "strconv.ParseFloat: parsing.*")
666+
assert.Panic(t, func() { p.MustGetFloat32("invalid") }, "unknown property: invalid")
667+
}
668+
573669
func TestGetInt(t *testing.T) {
574670
for _, test := range int64Tests {
575671
p := mustParse(t, test.input)
@@ -602,6 +698,22 @@ func TestMustGetInt64(t *testing.T) {
602698
assert.Panic(t, func() { p.MustGetInt64("invalid") }, "unknown property: invalid")
603699
}
604700

701+
func TestGetInt32(t *testing.T) {
702+
for _, test := range int32Tests {
703+
p := mustParse(t, test.input)
704+
assert.Equal(t, p.Len(), 1)
705+
assert.Equal(t, p.GetInt32(test.key, test.def), test.value)
706+
}
707+
}
708+
709+
func TestMustGetInt32(t *testing.T) {
710+
input := "key = 123\nkey2 = ghi"
711+
p := mustParse(t, input)
712+
assert.Equal(t, p.MustGetInt32("key"), int32(123))
713+
assert.Panic(t, func() { p.MustGetInt32("key2") }, "strconv.ParseInt: parsing.*")
714+
assert.Panic(t, func() { p.MustGetInt32("invalid") }, "unknown property: invalid")
715+
}
716+
605717
func TestGetUint(t *testing.T) {
606718
for _, test := range uint64Tests {
607719
p := mustParse(t, test.input)
@@ -634,6 +746,22 @@ func TestMustGetUint64(t *testing.T) {
634746
assert.Panic(t, func() { p.MustGetUint64("invalid") }, "unknown property: invalid")
635747
}
636748

749+
func TestGetUint32(t *testing.T) {
750+
for _, test := range uint32Tests {
751+
p := mustParse(t, test.input)
752+
assert.Equal(t, p.Len(), 1)
753+
assert.Equal(t, p.GetUint32(test.key, test.def), test.value)
754+
}
755+
}
756+
757+
func TestMustGetUint32(t *testing.T) {
758+
input := "key = 123\nkey2 = ghi"
759+
p := mustParse(t, input)
760+
assert.Equal(t, p.MustGetUint32("key"), uint32(123))
761+
assert.Panic(t, func() { p.MustGetUint32("key2") }, "strconv.ParseUint: parsing.*")
762+
assert.Panic(t, func() { p.MustGetUint32("invalid") }, "unknown property: invalid")
763+
}
764+
637765
func TestGetString(t *testing.T) {
638766
for _, test := range stringTests {
639767
p := mustParse(t, test.input)

0 commit comments

Comments
 (0)