dt_automate/vendor/github.com/Andrew-M-C/go.jsonvalue/compare.go
2025-02-27 10:48:32 +08:00

137 lines
3.2 KiB
Go

package jsonvalue
import (
"bytes"
"github.com/shopspring/decimal"
)
// GreaterThan returns whether v is greater than another value.
//
// Both values should be number type, otherwise false will be returned.
func (v *V) GreaterThan(another *V) bool {
res, _ := greaterThan(v, another)
return res
}
// GreaterThanOrEqual returns whether v is greater than or equal to another value.
//
// Both values should be number type, otherwise false will be returned.
func (v *V) GreaterThanOrEqual(another *V) bool {
res, _ := greaterOrEqualThan(v, another)
return res
}
// LessThan returns whether v is less than another value.
//
// Both values should be number type, otherwise false will be returned.
func (v *V) LessThan(another *V) bool {
res, ok := greaterOrEqualThan(v, another)
if !ok {
return false
}
return !res
}
// LessThanOrEqual returns whether v is less than or equal to another value.
//
// Both values should be number type, otherwise false will be returned.
func (v *V) LessThanOrEqual(another *V) bool {
res, ok := greaterThan(v, another)
if !ok {
return false
}
return !res
}
func greaterThan(left, right *V) (result, ok bool) {
if left.valueType != Number || right.valueType != Number {
return false, false
}
a1, _ := decimal.NewFromString(string(left.srcByte))
a2, _ := decimal.NewFromString(string(right.srcByte))
return a1.GreaterThan(a2), true
}
func greaterOrEqualThan(left, right *V) (result, ok bool) {
if left.valueType != Number || right.valueType != Number {
return false, false
}
if bytes.Equal(left.srcByte, right.srcByte) {
return true, true
}
a1, _ := decimal.NewFromString(string(left.srcByte))
a2, _ := decimal.NewFromString(string(right.srcByte))
return a1.GreaterThanOrEqual(a2), true
}
// Equal shows whether the content of two JSON values equal to each other.
//
// Equal 判断两个 JSON 的内容是否相等
func (v *V) Equal(another *V) bool {
if v == nil || another == nil {
return false
}
if v.valueType != another.valueType {
return false
}
switch v.valueType {
default: // including NotExist, Unknown
return false
case String:
return v.valueStr == another.valueStr
case Number:
return numberEqual(v, another)
case Object:
return objectEqual(v, another)
case Array:
return arrayEqual(v, another)
case Boolean:
return v.valueBool == another.valueBool
case Null:
return true
}
}
func numberEqual(left, right *V) bool {
if bytes.Equal(left.srcByte, right.srcByte) {
return true
}
d1, _ := decimal.NewFromString(string(left.srcByte))
d2, _ := decimal.NewFromString(string(right.srcByte))
return d1.Equal(d2)
}
func objectEqual(left, right *V) bool {
if len(left.children.object) != len(right.children.object) {
return false
}
for k, leftChild := range left.children.object {
rightChild, exist := right.children.object[k]
if !exist {
return false
}
if !leftChild.v.Equal(rightChild.v) {
return false
}
}
return true
}
func arrayEqual(left, right *V) bool {
if len(left.children.arr) != len(right.children.arr) {
return false
}
for i, leftChild := range left.children.arr {
rightChild := right.children.arr[i]
if !leftChild.Equal(rightChild) {
return false
}
}
return true
}