Skip to content

Commit

Permalink
update doc
Browse files Browse the repository at this point in the history
  • Loading branch information
duke-git committed Dec 4, 2024
1 parent e1e1588 commit 4595a94
Show file tree
Hide file tree
Showing 14 changed files with 339 additions and 193 deletions.
239 changes: 100 additions & 139 deletions compare/compare_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package compare
import (
"bytes"
"encoding/json"
"math/big"
"reflect"
"time"

Expand Down Expand Up @@ -155,169 +156,129 @@ func compareBasicValue(operator string, leftValue, rightValue interface{}) bool
}

switch leftVal := leftValue.(type) {
case json.Number:
if left, err := leftVal.Float64(); err == nil {
switch rightVal := rightValue.(type) {
case json.Number:
if right, err := rightVal.Float64(); err == nil {
switch operator {
case equal:
if left == right {
return true
}
case lessThan:
if left < right {
return true
}
case greaterThan:
if left > right {
return true
}
case lessOrEqual:
if left <= right {
return true
}
case greaterOrEqual:
if left >= right {
return true
}
}

}

case float32, float64, int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64:
right, err := convertor.ToFloat(rightValue)
if err != nil {
return false
}
switch operator {
case equal:
if left == right {
return true
}
case lessThan:
if left < right {
return true
}
case greaterThan:
if left > right {
return true
}
case lessOrEqual:
if left <= right {
return true
}
case greaterOrEqual:
if left >= right {
return true
}
}
}
case int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64:
left, err := convertor.ToBigInt(leftValue)
if err != nil {
return false
}

right, err := convertor.ToBigInt(rightValue)
if err != nil {
return false
}

case float32, float64, int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64:
return compareBigInt(operator, left, right)

case float32, float64:
left, err := convertor.ToFloat(leftValue)
if err != nil {
return false
}
switch rightVal := rightValue.(type) {
case json.Number:
if right, err := rightVal.Float64(); err == nil {
switch operator {
case equal:
if left == right {
return true
}
case lessThan:
if left < right {
return true
}
case greaterThan:
if left > right {
return true
}
case lessOrEqual:
if left <= right {
return true
}
case greaterOrEqual:
if left >= right {
return true
}
}
}
case float32, float64, int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64:
right, err := convertor.ToFloat(rightValue)
if err != nil {
return false
}

switch operator {
case equal:
if left == right {
return true
}
case lessThan:
if left < right {
return true
}
case greaterThan:
if left > right {
return true
}
case lessOrEqual:
if left <= right {
return true
}
case greaterOrEqual:
if left >= right {
return true
}
}
right, err := convertor.ToFloat(rightValue)
if err != nil {
return false
}

return compareFloats(operator, left, right)

case string:
left := leftVal
switch right := rightValue.(type) {
case string:
switch operator {
case equal:
if left == right {
return true
}
case lessThan:
if left < right {
return true
}
case greaterThan:
if left > right {
return true
}
case lessOrEqual:
if left <= right {
return true
}
case greaterOrEqual:
if left >= right {
return true
}
}
return compareStrings(operator, left, right)
}

case bool:
left := leftVal
switch right := rightValue.(type) {
case bool:
switch operator {
case equal:
if left == right {
return true
return compareBools(operator, left, right)
}

case json.Number:
if left, err := leftVal.Float64(); err == nil {
switch rightVal := rightValue.(type) {
case json.Number:
if right, err := rightVal.Float64(); err == nil {
return compareFloats(operator, left, right)
}
case float32, float64:
right, err := convertor.ToFloat(rightValue)
if err != nil {
return false
}
return compareFloats(operator, left, right)

case int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64:
right, err := convertor.ToBigInt(rightValue)
if err != nil {
return false
}
left, err := convertor.ToBigInt(left)
return compareBigInt(operator, left, right)
}
}
}

return false
}

// compareBigInt compares two big.Int values based on the operator
func compareBigInt(operator string, left, right *big.Int) bool {
switch operator {
case equal:
return left.Cmp(right) == 0
case lessThan:
return left.Cmp(right) < 0
case greaterThan:
return left.Cmp(right) > 0
case lessOrEqual:
return left.Cmp(right) <= 0
case greaterOrEqual:
return left.Cmp(right) >= 0
}
return false
}

// compareFloats compares two float64 values based on the operator
func compareFloats(operator string, left, right float64) bool {
switch operator {
case equal:
return left == right
case lessThan:
return left < right
case greaterThan:
return left > right
case lessOrEqual:
return left <= right
case greaterOrEqual:
return left >= right
}
return false
}

// compareStrings compares two string values based on the operator
func compareStrings(operator string, left, right string) bool {
switch operator {
case equal:
return left == right
case lessThan:
return left < right
case greaterThan:
return left > right
case lessOrEqual:
return left <= right
case greaterOrEqual:
return left >= right
}
return false
}

// compareBools compares two boolean values based on the operator
func compareBools(operator string, left, right bool) bool {
switch operator {
case equal:
return left == right
}
return false
}
29 changes: 20 additions & 9 deletions compare/compare_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package compare

import (
"encoding/json"
"testing"
"time"

Expand Down Expand Up @@ -70,18 +71,28 @@ func TestEqualValue(t *testing.T) {
}

func TestLessThan(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestLessThan")

assert.Equal(true, LessThan(1, 2))
assert.Equal(true, LessThan(1.1, 2.2))
assert.Equal(true, LessThan("a", "b"))

time1 := time.Now()
time2 := time1.Add(time.Second)
assert.Equal(true, LessThan(time1, time2))
tests := []struct {
left interface{}
right interface{}
want bool
}{
{1, 2, true},
{1.1, 2.2, true},
{"a", "b", true},
{time.Now(), time.Now().Add(time.Second), true},
{[]byte("hello1"), []byte("hello2"), true},
{json.Number("123"), json.Number("124"), true},
{645680099112988673, 645680099112988675, true},
{1, 1, false},
{1, int64(1), false},
}

assert.Equal(false, LessThan(1, 1))
assert.Equal(false, LessThan(1, int64(1)))
for _, tt := range tests {
assert.Equal(tt.want, LessThan(tt.left, tt.right))
}
}

func TestGreaterThan(t *testing.T) {
Expand Down
34 changes: 34 additions & 0 deletions convertor/convertor.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"fmt"
"io"
"math"
"math/big"
"reflect"
"regexp"
"strconv"
Expand Down Expand Up @@ -460,3 +461,36 @@ func ToRawUrlBase64(value interface{}) string {
return base64.RawURLEncoding.EncodeToString(marshal)
}
}

// ToBigInt converts an integer of any supported type (int, int64, uint64, etc.) to *big.Int
// Play: todo
func ToBigInt(v interface{}) (*big.Int, error) {
result := new(big.Int)

switch v := (v).(type) {
case int:
result.SetInt64(int64(v))
case int8:
result.SetInt64(int64(v))
case int16:
result.SetInt64(int64(v))
case int32:
result.SetInt64(int64(v))
case int64:
result.SetInt64(v)
case uint:
result.SetUint64(uint64(v))
case uint8:
result.SetUint64(uint64(v))
case uint16:
result.SetUint64(uint64(v))
case uint32:
result.SetUint64(uint64(v))
case uint64:
result.SetUint64(v)
default:
return nil, fmt.Errorf("unsupported type: %T", v)
}

return result, nil
}
Loading

0 comments on commit 4595a94

Please sign in to comment.