diff --git a/README.md b/README.md index 294ec14c..079a90c6 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Go Reference](https://pkg.go.dev/badge/github.com/obalunenko/getenv.svg)](https://pkg.go.dev/github.com/obalunenko/getenv) [![Go Report Card](https://goreportcard.com/badge/github.com/obalunenko/getenv)](https://goreportcard.com/report/github.com/obalunenko/getenv) [![codecov](https://codecov.io/gh/obalunenko/getenv/branch/master/graph/badge.svg)](https://codecov.io/gh/obalunenko/getenv) -![coverbadger-tag-do-not-edit](https://img.shields.io/badge/coverage-96.45%25-brightgreen?longCache=true&style=flat) +![coverbadger-tag-do-not-edit](https://img.shields.io/badge/coverage-97.03%25-brightgreen?longCache=true&style=flat) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=obalunenko_getenv&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=obalunenko_getenv) # getenv @@ -30,6 +30,7 @@ Types supported: - []uint - uint32 - []uint32 +- float32 - float64 - []float64 - time.Time diff --git a/getenv.go b/getenv.go index f39b1463..ebd24395 100644 --- a/getenv.go +++ b/getenv.go @@ -19,6 +19,7 @@ // - []uint // - uint32 // - []uint32 +// - float32 // - float64 // - []float64 // - time.Time diff --git a/getenv_test.go b/getenv_test.go index a6bea22a..ab96753e 100644 --- a/getenv_test.go +++ b/getenv_test.go @@ -333,6 +333,82 @@ func TestInt32OrDefault(t *testing.T) { } } +func TestFloat32OrDefault(t *testing.T) { + type args struct { + key string + defaultVal float32 + } + + type expected struct { + val float32 + } + + var tests = []struct { + name string + precond precondition + args args + expected expected + }{ + { + name: "env not set - default returned", + precond: precondition{ + setenv: setenv{ + isSet: false, + val: "newval", + }, + }, + args: args{ + key: testEnvKey, + defaultVal: float32(956.02), + }, + expected: expected{ + val: float32(956.02), + }, + }, + { + name: "env set - env value returned", + precond: precondition{ + setenv: setenv{ + isSet: true, + val: "1024.123", + }, + }, + args: args{ + key: testEnvKey, + defaultVal: float32(42), + }, + expected: expected{ + val: float32(1024.123), + }, + }, + { + name: "invalid env value set - default returned", + precond: precondition{ + setenv: setenv{ + isSet: true, + val: "128s7", + }, + }, + args: args{ + key: testEnvKey, + defaultVal: float32(44), + }, + expected: expected{ + val: float32(44), + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.precond.maybeSetEnv(t, tt.args.key) + + got := getenv.EnvOrDefault(tt.args.key, tt.args.defaultVal) + assert.Equal(t, tt.expected.val, got) + }) + } +} + func TestFloat64OrDefault(t *testing.T) { type args struct { key string diff --git a/internal/constraint.go b/internal/constraint.go index 6f66b01e..58d9d066 100644 --- a/internal/constraint.go +++ b/internal/constraint.go @@ -27,7 +27,7 @@ type ( // Float is a constraint for floats and slice of floats. Float interface { - float64 | []float64 + float32 | float64 | []float64 } // Time is a constraint for time.Time and time.Duration. diff --git a/internal/iface.go b/internal/iface.go index 7044e97a..3ba8938e 100644 --- a/internal/iface.go +++ b/internal/iface.go @@ -19,7 +19,7 @@ func NewEnvParser(v any) EnvParser { p = newUintParser(t) case bool: p = boolParser(t) - case float64, []float64: + case float32, float64, []float64: p = newFloatParser(t) case time.Time: p = timeParser(t) @@ -97,6 +97,8 @@ func newUintParser(v any) EnvParser { func newFloatParser(v any) EnvParser { switch t := v.(type) { + case float32: + return float32Parser(t) case float64: return float64Parser(t) case []float64: @@ -229,6 +231,14 @@ func (i int64SliceParser) ParseEnv(key string, defaltVal any, options Parameters return val } +type float32Parser float32 + +func (f float32Parser) ParseEnv(key string, defaltVal any, _ Parameters) any { + val := float32OrDefault(key, defaltVal.(float32)) + + return val +} + type float64Parser float64 func (f float64Parser) ParseEnv(key string, defaltVal any, _ Parameters) any { diff --git a/internal/iface_test.go b/internal/iface_test.go index 5778b608..396816a4 100644 --- a/internal/iface_test.go +++ b/internal/iface_test.go @@ -170,6 +170,14 @@ func TestNewEnvParser(t *testing.T) { want: boolParser(true), wantPanic: assert.NotPanics, }, + { + name: "float32", + args: args{ + v: float32(1.1), + }, + want: float32Parser(float32(1.1)), + wantPanic: assert.NotPanics, + }, { name: "float64", args: args{ @@ -316,6 +324,22 @@ func Test_ParseEnv(t *testing.T) { }, want: -1.2, }, + { + name: "float32Parser", + s: float32Parser(0), + precond: precondition{ + setenv: setenv{ + isSet: true, + val: "-1.2", + }, + }, + args: args{ + key: testEnvKey, + defaltVal: float32(99), + in2: Parameters{}, + }, + want: float32(-1.2), + }, { name: "float64Parser", s: float64SliceParser(nil), diff --git a/internal/parsers.go b/internal/parsers.go index 5c95c3e8..a85ac4a1 100644 --- a/internal/parsers.go +++ b/internal/parsers.go @@ -378,6 +378,27 @@ func int32OrDefault(key string, defaultVal int32) int32 { return int32(val) } +// float32OrDefault retrieves the float32 value of the environment variable named +// by the key. +// If variable not set or value is empty - defaultVal will be returned. +func float32OrDefault(key string, defaultVal float32) float32 { + env := stringOrDefault(key, "") + if env == "" { + return defaultVal + } + + const ( + bitsize = 32 + ) + + val, err := strconv.ParseFloat(env, bitsize) + if err != nil { + return defaultVal + } + + return float32(val) +} + // float64OrDefault retrieves the float64 value of the environment variable named // by the key. // If variable not set or value is empty - defaultVal will be returned. diff --git a/internal/parsers_test.go b/internal/parsers_test.go index 584cc04a..aeecde17 100644 --- a/internal/parsers_test.go +++ b/internal/parsers_test.go @@ -465,6 +465,82 @@ func Test_int32OrDefault(t *testing.T) { } } +func Test_float32OrDefault(t *testing.T) { + type args struct { + key string + defaultVal float32 + } + + type expected struct { + val float32 + } + + var tests = []struct { + name string + precond precondition + args args + expected expected + }{ + { + name: "env not set - default returned", + precond: precondition{ + setenv: setenv{ + isSet: false, + val: "newval", + }, + }, + args: args{ + key: testEnvKey, + defaultVal: float32(956.02), + }, + expected: expected{ + val: float32(956.02), + }, + }, + { + name: "env set - env value returned", + precond: precondition{ + setenv: setenv{ + isSet: true, + val: "1024.123", + }, + }, + args: args{ + key: testEnvKey, + defaultVal: float32(42), + }, + expected: expected{ + val: float32(1024.123), + }, + }, + { + name: "invalid env value set - default returned", + precond: precondition{ + setenv: setenv{ + isSet: true, + val: "128s7", + }, + }, + args: args{ + key: testEnvKey, + defaultVal: float32(44), + }, + expected: expected{ + val: float32(44), + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.precond.maybeSetEnv(t, tt.args.key) + + got := float32OrDefault(tt.args.key, tt.args.defaultVal) + assert.Equal(t, tt.expected.val, got) + }) + } +} + func Test_float64OrDefault(t *testing.T) { type args struct { key string