Files
QSfera/Server/vendor/github.com/open-policy-agent/opa/internal/gojsonschema/utils.go
T
Курнат Андрей 2315f25754 Initial QSfera import
2026-06-07 10:20:04 +03:00

162 lines
3.5 KiB
Go

// Copyright 2015 xeipuuv ( https://github.com/xeipuuv )
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// author xeipuuv
// author-github https://github.com/xeipuuv
// author-mail xeipuuv@gmail.com
//
// repository-name gojsonschema
// repository-desc An implementation of JSON Schema, based on IETF's draft v4 - Go language.
//
// description Various utility functions.
//
// created 26-02-2013
// nolint:unused // Package in development (2021).
package gojsonschema
import (
"encoding/json"
"math/big"
"slices"
)
func isStringInSlice(s []string, what string) bool {
return slices.Contains(s, what)
}
func marshalToJSONString(value any) (*string, error) {
mBytes, err := json.Marshal(value)
if err != nil {
return nil, err
}
sBytes := string(mBytes)
return &sBytes, nil
}
func marshalWithoutNumber(value any) (*string, error) {
// The JSON is decoded using https://golang.org/pkg/encoding/json/#Decoder.UseNumber
// This means the numbers are internally still represented as strings and therefore 1.00 is unequal to 1
// One way to eliminate these differences is to decode and encode the JSON one more time without Decoder.UseNumber
// so that these differences in representation are removed
jsonString, err := marshalToJSONString(value)
if err != nil {
return nil, err
}
var document any
err = json.Unmarshal([]byte(*jsonString), &document)
if err != nil {
return nil, err
}
return marshalToJSONString(document)
}
func isJSONNumber(what any) bool {
switch what.(type) {
case json.Number:
return true
}
return false
}
func checkJSONInteger(what any) (isInt bool) {
jsonNumber := what.(json.Number)
bigFloat, isValidNumber := new(big.Rat).SetString(string(jsonNumber))
return isValidNumber && bigFloat.IsInt()
}
// same as ECMA Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER
const (
maxJSONFloat = float64(1<<53 - 1) // 9007199254740991.0 2^53 - 1
minJSONFloat = -float64(1<<53 - 1) //-9007199254740991.0 -2^53 - 1
)
func mustBeInteger(what any) *int {
number, ok := what.(json.Number)
if !ok {
return nil
}
isInt := checkJSONInteger(number)
if !isInt {
return nil
}
int64Value, err := number.Int64()
if err != nil {
return nil
}
// This doesn't actually convert to an int32 value; it converts to the
// system-specific default integer. Assuming this is a valid int32 could cause
// bugs.
int32Value := int(int64Value)
return &int32Value
}
func mustBeNumber(what any) *big.Rat {
number, ok := what.(json.Number)
if !ok {
return nil
}
float64Value, success := new(big.Rat).SetString(string(number))
if success {
return float64Value
}
return nil
}
func convertDocumentNode(val any) any {
if lval, ok := val.([]any); ok {
res := []any{}
for _, v := range lval {
res = append(res, convertDocumentNode(v))
}
return res
}
if mval, ok := val.(map[any]any); ok {
res := map[string]any{}
for k, v := range mval {
res[k.(string)] = convertDocumentNode(v)
}
return res
}
return val
}