1
0
Fork 0
mirror of https://github.com/Luzifer/go_helpers.git synced 2024-10-18 06:14:21 +00:00

Add float64 field type support

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2024-05-04 23:02:54 +02:00
parent f86e8ab626
commit 0c39806be9
Signed by: luzifer
SSH key fingerprint: SHA256:/xtE5lCgiRDQr8SLxHMS92ZBlACmATUmF1crK16Ks4E
3 changed files with 136 additions and 1 deletions

View file

@ -37,6 +37,7 @@ const (
SchemaFieldTypeAny SchemaFieldType = iota
SchemaFieldTypeBool
SchemaFieldTypeDuration
SchemaFieldTypeFloat64
SchemaFieldTypeInt64
SchemaFieldTypeString
SchemaFieldTypeStringSlice
@ -110,7 +111,7 @@ func (f *FieldCollection) ValidateSchema(opts ...ValidateOpt) error {
return nil
}
//nolint:gocyclo // These are quite simple checks
//nolint:gocognit,gocyclo // These are quite simple checks
func validateFieldType(f *FieldCollection, field SchemaField) (err error) {
switch field.Type {
case SchemaFieldTypeAny:
@ -138,6 +139,16 @@ func validateFieldType(f *FieldCollection, field SchemaField) (err error) {
return fmt.Errorf("field %s is empty", field.Name)
}
case SchemaFieldTypeFloat64:
v, err := f.Float64(field.Name)
if err != nil {
return fmt.Errorf("field %s is not of type float64: %w", field.Name, err)
}
if field.NonEmpty && v == 0 {
return fmt.Errorf("field %s is empty", field.Name)
}
case SchemaFieldTypeInt64:
v, err := f.Int64(field.Name)
if err != nil {

View file

@ -0,0 +1,67 @@
package fieldcollection
import (
"fmt"
"strconv"
"github.com/pkg/errors"
)
// Float64 tries to read key name as float64
func (f *FieldCollection) Float64(name string) (float64, error) {
if f == nil || f.data == nil {
return 0, errors.New("uninitialized field collection")
}
f.lock.RLock()
defer f.lock.RUnlock()
v, ok := f.data[name]
if !ok {
return 0, ErrValueNotSet
}
switch v := v.(type) {
case int:
return float64(v), nil
case int16:
return float64(v), nil
case int32:
return float64(v), nil
case int64:
return float64(v), nil
case float64:
return v, nil
case string:
pv, err := strconv.ParseFloat(v, 64)
if err != nil {
return 0, fmt.Errorf("parsing value: %w", err)
}
return pv, nil
}
return 0, ErrValueMismatch
}
// CanFloat64 tries to read key name as float64 and checks whether error is nil
func (f *FieldCollection) CanFloat64(name string) bool {
_, err := f.Float64(name)
return err == nil
}
// MustFloat64 is a wrapper around Float64 and panics if an error was returned
func (f *FieldCollection) MustFloat64(name string, defVal *float64) float64 {
v, err := f.Float64(name)
if err != nil {
if defVal != nil {
return *defVal
}
panic(err)
}
return v
}

View file

@ -0,0 +1,57 @@
package fieldcollection
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestFloat64(t *testing.T) {
fc := FieldCollectionFromData(map[string]any{
"int": int(12),
"int16": int16(12),
"int32": int32(12),
"int64": int64(12),
"float64": float64(12),
"bool": true,
"invalidString": "I'm a string!",
"validString": "12",
})
_, err := fc.Float64("_")
assert.ErrorIs(t, err, ErrValueNotSet)
_, err = fc.Float64("bool")
assert.ErrorIs(t, err, ErrValueMismatch)
_, err = fc.Float64("invalidString")
assert.Error(t, err)
v, err := fc.Float64("int")
assert.NoError(t, err)
assert.Equal(t, float64(12), v)
v, err = fc.Float64("int16")
assert.NoError(t, err)
assert.Equal(t, float64(12), v)
v, err = fc.Float64("int32")
assert.NoError(t, err)
assert.Equal(t, float64(12), v)
v, err = fc.Float64("int64")
assert.NoError(t, err)
assert.Equal(t, float64(12), v)
v, err = fc.Float64("validString")
assert.NoError(t, err)
assert.Equal(t, float64(12), v)
assert.True(t, fc.CanFloat64("int"))
assert.False(t, fc.CanFloat64("bool"))
assert.NotPanics(t, func() { fc.MustFloat64("int32", nil) })
assert.Panics(t, func() { fc.MustFloat64("bool", nil) })
assert.Equal(t, float64(5), fc.MustFloat64("_", func(v float64) *float64 { return &v }(5)))
}