mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-05-07 20:15:31 -05:00
51805e710d
Bumps [github.com/open-policy-agent/opa](https://github.com/open-policy-agent/opa) from 1.4.2 to 1.5.0. - [Release notes](https://github.com/open-policy-agent/opa/releases) - [Changelog](https://github.com/open-policy-agent/opa/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-policy-agent/opa/compare/v1.4.2...v1.5.0) --- updated-dependencies: - dependency-name: github.com/open-policy-agent/opa dependency-version: 1.5.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
170 lines
3.1 KiB
Go
170 lines
3.1 KiB
Go
// Copyright 2016 The OPA Authors. All rights reserved.
|
|
// Use of this source code is governed by an Apache2
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package util
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"math/big"
|
|
)
|
|
|
|
// Compare returns 0 if a equals b, -1 if a is less than b, and 1 if b is than a.
|
|
//
|
|
// For comparison between values of different types, the following ordering is used:
|
|
// nil < bool < int, float64 < string < []any < map[string]any. Slices and maps
|
|
// are compared recursively. If one slice or map is a subset of the other slice or map
|
|
// it is considered "less than". Nil is always equal to nil.
|
|
func Compare(a, b any) int {
|
|
aSortOrder := sortOrder(a)
|
|
bSortOrder := sortOrder(b)
|
|
if aSortOrder < bSortOrder {
|
|
return -1
|
|
} else if bSortOrder < aSortOrder {
|
|
return 1
|
|
}
|
|
switch a := a.(type) {
|
|
case nil:
|
|
return 0
|
|
case bool:
|
|
switch b := b.(type) {
|
|
case bool:
|
|
if a == b {
|
|
return 0
|
|
}
|
|
if !a {
|
|
return -1
|
|
}
|
|
return 1
|
|
}
|
|
case json.Number:
|
|
switch b := b.(type) {
|
|
case json.Number:
|
|
return compareJSONNumber(a, b)
|
|
}
|
|
case int:
|
|
switch b := b.(type) {
|
|
case int:
|
|
if a == b {
|
|
return 0
|
|
} else if a < b {
|
|
return -1
|
|
}
|
|
return 1
|
|
}
|
|
case float64:
|
|
switch b := b.(type) {
|
|
case float64:
|
|
if a == b {
|
|
return 0
|
|
} else if a < b {
|
|
return -1
|
|
}
|
|
return 1
|
|
}
|
|
case string:
|
|
switch b := b.(type) {
|
|
case string:
|
|
if a == b {
|
|
return 0
|
|
} else if a < b {
|
|
return -1
|
|
}
|
|
return 1
|
|
}
|
|
case []any:
|
|
switch b := b.(type) {
|
|
case []any:
|
|
bLen := len(b)
|
|
aLen := len(a)
|
|
minLen := min(bLen, aLen)
|
|
for i := range minLen {
|
|
cmp := Compare(a[i], b[i])
|
|
if cmp != 0 {
|
|
return cmp
|
|
}
|
|
}
|
|
if aLen == bLen {
|
|
return 0
|
|
} else if aLen < bLen {
|
|
return -1
|
|
}
|
|
return 1
|
|
}
|
|
case map[string]any:
|
|
switch b := b.(type) {
|
|
case map[string]any:
|
|
aKeys := KeysSorted(a)
|
|
bKeys := KeysSorted(b)
|
|
aLen := len(aKeys)
|
|
bLen := len(bKeys)
|
|
minLen := min(bLen, aLen)
|
|
for i := range minLen {
|
|
if aKeys[i] < bKeys[i] {
|
|
return -1
|
|
} else if bKeys[i] < aKeys[i] {
|
|
return 1
|
|
}
|
|
aVal := a[aKeys[i]]
|
|
bVal := b[bKeys[i]]
|
|
cmp := Compare(aVal, bVal)
|
|
if cmp != 0 {
|
|
return cmp
|
|
}
|
|
}
|
|
if aLen == bLen {
|
|
return 0
|
|
} else if aLen < bLen {
|
|
return -1
|
|
}
|
|
return 1
|
|
}
|
|
}
|
|
|
|
panic(fmt.Sprintf("illegal arguments of type %T and type %T", a, b))
|
|
}
|
|
|
|
const (
|
|
nilSort = iota
|
|
boolSort = iota
|
|
numberSort = iota
|
|
stringSort = iota
|
|
arraySort = iota
|
|
objectSort = iota
|
|
)
|
|
|
|
func compareJSONNumber(a, b json.Number) int {
|
|
bigA, ok := new(big.Float).SetString(string(a))
|
|
if !ok {
|
|
panic("illegal value")
|
|
}
|
|
bigB, ok := new(big.Float).SetString(string(b))
|
|
if !ok {
|
|
panic("illegal value")
|
|
}
|
|
return bigA.Cmp(bigB)
|
|
}
|
|
|
|
func sortOrder(v any) int {
|
|
switch v.(type) {
|
|
case nil:
|
|
return nilSort
|
|
case bool:
|
|
return boolSort
|
|
case json.Number:
|
|
return numberSort
|
|
case int:
|
|
return numberSort
|
|
case float64:
|
|
return numberSort
|
|
case string:
|
|
return stringSort
|
|
case []any:
|
|
return arraySort
|
|
case map[string]any:
|
|
return objectSort
|
|
}
|
|
panic(fmt.Sprintf("illegal argument of type %T", v))
|
|
}
|