Skip to content

Commit

Permalink
refactor: float
Browse files Browse the repository at this point in the history
  • Loading branch information
siyul-park committed Nov 29, 2023
1 parent 3d30ba5 commit ee7b30c
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 97 deletions.
162 changes: 84 additions & 78 deletions pkg/primitive/float.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,143 +8,149 @@ import (
)

type (
// Float is an interface representing a floating-point number.
Float interface {
Value
Float() float64
}
// Float32 is a representation of a float64.

// Float32 is a representation of a float32.
Float32 float32

// Float64 is a representation of a float64.
Float64 float64
)

var _ Float = (Float32)(0)
var _ Float = (Float64)(0)

// NewFloat64 returns a new Float64.
// NewFloat32 returns a new Float32.
func NewFloat32(value float32) Float32 {
return Float32(value)
}

// Float returns a raw representation.
func (o Float32) Float() float64 {
return float64(o)
// Float returns the raw representation.
func (f Float32) Float() float64 {
return float64(f)
}

func (o Float32) Kind() Kind {
// Kind returns the type of the float32 data.
func (f Float32) Kind() Kind {
return KindFloat32
}

func (o Float32) Equal(v Value) bool {
if r, ok := v.(Float); !ok {
if r, ok := v.(Integer); ok {
return o.Float() == float64(r.Int())
} else if r, ok := v.(Uinteger); ok {
return o.Float() == float64(r.Uint())
} else {
return false
}
} else {
return o.Float() == r.Float()
// Compare compares two Float32 values.
func (f Float32) Compare(v Value) int {
if r, ok := v.(Float); ok {
return compare[float64](f.Float(), r.Float())
}
}

func (o Float32) Compare(v Value) int {
if r, ok := v.(Float); !ok {
if r, ok := v.(Integer); ok {
return compare[float64](o.Float(), float64(r.Int()))
} else if r, ok := v.(Uinteger); ok {
return compare[float64](o.Float(), float64(r.Uint()))
} else if o.Kind() > v.Kind() {
return 1
} else {
return -1
}
} else {
return compare[float64](o.Float(), r.Float())
if r, ok := v.(Integer); ok {
return compare[float64](f.Float(), float64(r.Int()))
}
if r, ok := v.(Uinteger); ok {
return compare[float64](f.Float(), float64(r.Uint()))
}
if f.Kind() > v.Kind() {
return 1
}
return -1
}

func (o Float32) Interface() any {
return float32(o)
// Interface converts Float32 to a float32.
func (f Float32) Interface() any {
return float32(f)
}

// NewFloat64 returns a new Float64.
func NewFloat64(value float64) Float64 {
return Float64(value)
}

// Float returns a raw representation.
func (o Float64) Float() float64 {
return float64(o)
// Float returns the raw representation.
func (f Float64) Float() float64 {
return float64(f)
}

func (o Float64) Kind() Kind {
// Kind returns the type of the float64 data.
func (f Float64) Kind() Kind {
return KindFloat64
}

func (o Float64) Compare(v Value) int {
if r, ok := v.(Float); !ok {
if r, ok := v.(Integer); ok {
return compare[float64](o.Float(), float64(r.Int()))
} else if r, ok := v.(Uinteger); ok {
return compare[float64](o.Float(), float64(r.Uint()))
} else if o.Kind() > v.Kind() {
return 1
} else {
return -1
}
} else {
return compare[float64](o.Float(), r.Float())
// Compare compares two Float64 values.
func (f Float64) Compare(v Value) int {
if r, ok := v.(Float); ok {
return compare[float64](f.Float(), r.Float())
}
if r, ok := v.(Integer); ok {
return compare[float64](f.Float(), float64(r.Int()))
}
if r, ok := v.(Uinteger); ok {
return compare[float64](f.Float(), float64(r.Uint()))
}
if f.Kind() > v.Kind() {
return 1
}
return -1
}

func (o Float64) Interface() any {
return float64(o)
// Interface converts Float64 to a float64.
func (f Float64) Interface() any {
return float64(f)
}

// NewFloatEncoder is encode float to Float.
// NewFloatEncoder encodes float to Float.
func NewFloatEncoder() encoding.Encoder[any, Value] {
return encoding.EncoderFunc[any, Value](func(source any) (Value, error) {
if s := reflect.ValueOf(source); s.Kind() == reflect.Float32 {
switch s := reflect.ValueOf(source); s.Kind() {
case reflect.Float32:
return NewFloat32(float32(s.Float())), nil
} else if s := reflect.ValueOf(source); s.Kind() == reflect.Float64 {
return NewFloat64(float64(s.Float())), nil
case reflect.Float64:
return NewFloat64(s.Float()), nil
}
return nil, errors.WithStack(encoding.ErrUnsupportedValue)
})
}

// NewFloatDecoder is decode Float to float.
// NewFloatDecoder decodes Float to float.
func NewFloatDecoder() encoding.Decoder[Value, any] {
return encoding.DecoderFunc[Value, any](func(source Value, target any) error {
if s, ok := source.(Float); ok {
if t := reflect.ValueOf(target); t.Kind() == reflect.Pointer {
if t.Elem().Kind() == reflect.Float32 {
if t := reflect.ValueOf(target); t.Kind() == reflect.Ptr {
switch t.Elem().Kind() {
case reflect.Float32:
t.Elem().Set(reflect.ValueOf(float32(s.Float())))
return nil
} else if t.Elem().Kind() == reflect.Float64 {
t.Elem().Set(reflect.ValueOf(float64(s.Float())))
return nil
} else if t.Elem().Kind() == reflect.Int {
case reflect.Float64:
t.Elem().Set(reflect.ValueOf(s.Float()))
case reflect.Int:
t.Elem().Set(reflect.ValueOf(int(s.Float())))
return nil
} else if t.Elem().Kind() == reflect.Int8 {
case reflect.Int8:
t.Elem().Set(reflect.ValueOf(int8(s.Float())))
return nil
} else if t.Elem().Kind() == reflect.Int16 {
case reflect.Int16:
t.Elem().Set(reflect.ValueOf(int16(s.Float())))
return nil
} else if t.Elem().Kind() == reflect.Int32 {
case reflect.Int32:
t.Elem().Set(reflect.ValueOf(int32(s.Float())))
case reflect.Int64:
t.Elem().Set(reflect.ValueOf(int32(s.Float())))
return nil
} else if t.Elem().Kind() == reflect.Int64 {
t.Elem().Set(reflect.ValueOf(int64(s.Float())))
return nil
} else if t.Elem().Type() == typeAny {
t.Elem().Set(reflect.ValueOf(s.Interface()))
return nil
case reflect.Uint:
t.Elem().Set(reflect.ValueOf(uint(s.Float())))
case reflect.Uint8:
t.Elem().Set(reflect.ValueOf(uint8(s.Float())))
case reflect.Uint16:
t.Elem().Set(reflect.ValueOf(uint16(s.Float())))
case reflect.Uint32:
t.Elem().Set(reflect.ValueOf(uint32(s.Float())))
case reflect.Uint64:
t.Elem().Set(reflect.ValueOf(uint32(s.Float())))
case reflect.Bool:
t.Elem().Set(reflect.ValueOf(s.Float() != 0))
default:
if t.Type() == typeAny {
t.Elem().Set(reflect.ValueOf(s.Interface()))
} else {
return errors.WithStack(encoding.ErrUnsupportedValue)
}
}
return nil
}
}
return errors.WithStack(encoding.ErrUnsupportedValue)
Expand Down
37 changes: 18 additions & 19 deletions pkg/primitive/float_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,32 +39,31 @@ func TestFloat_Compare(t *testing.T) {

func TestFloat_Encode(t *testing.T) {
e := NewFloatEncoder()
d := NewFloatDecoder()

t.Run("32", func(t *testing.T) {
v, err := e.Encode(float32(1))
assert.NoError(t, err)
assert.Equal(t, NewFloat32(1), v)
})
t.Run("64", func(t *testing.T) {
v, err := e.Encode(float64(1))
assert.NoError(t, err)
assert.Equal(t, NewFloat64(1), v)
})
}
source := float32(1)

func TestFloat_Decode(t *testing.T) {
d := NewFloatDecoder()
encoded, err := e.Encode(source)
assert.NoError(t, err)
assert.Equal(t, Float32(1), encoded)

t.Run("32", func(t *testing.T) {
var v float32
err := d.Decode(NewFloat32(1), &v)
var decoded float32
err = d.Decode(encoded, &decoded)
assert.NoError(t, err)
assert.Equal(t, float32(1), v)
assert.Equal(t, source, decoded)

})
t.Run("64", func(t *testing.T) {
var v float64
err := d.Decode(NewFloat64(1), &v)
source := float64(1)

encoded, err := e.Encode(source)
assert.NoError(t, err)
assert.Equal(t, Float64(1), encoded)

var decoded float64
err = d.Decode(encoded, &decoded)
assert.NoError(t, err)
assert.Equal(t, float64(1), v)
assert.Equal(t, source, decoded)
})
}

0 comments on commit ee7b30c

Please sign in to comment.