github.com/safing/portbase@v0.19.5/database/accessor/accessor-json-bytes.go (about) 1 package accessor 2 3 import ( 4 "github.com/tidwall/gjson" 5 "github.com/tidwall/sjson" 6 ) 7 8 // JSONBytesAccessor is a json string with get functions. 9 type JSONBytesAccessor struct { 10 json *[]byte 11 } 12 13 // NewJSONBytesAccessor adds the Accessor interface to a JSON bytes string. 14 func NewJSONBytesAccessor(json *[]byte) *JSONBytesAccessor { 15 return &JSONBytesAccessor{ 16 json: json, 17 } 18 } 19 20 // Set sets the value identified by key. 21 func (ja *JSONBytesAccessor) Set(key string, value interface{}) error { 22 result := gjson.GetBytes(*ja.json, key) 23 if result.Exists() { 24 err := checkJSONValueType(result, key, value) 25 if err != nil { 26 return err 27 } 28 } 29 30 newJSON, err := sjson.SetBytes(*ja.json, key, value) 31 if err != nil { 32 return err 33 } 34 *ja.json = newJSON 35 return nil 36 } 37 38 // Get returns the value found by the given json key and whether it could be successfully extracted. 39 func (ja *JSONBytesAccessor) Get(key string) (value interface{}, ok bool) { 40 result := gjson.GetBytes(*ja.json, key) 41 if !result.Exists() { 42 return nil, false 43 } 44 return result.Value(), true 45 } 46 47 // GetString returns the string found by the given json key and whether it could be successfully extracted. 48 func (ja *JSONBytesAccessor) GetString(key string) (value string, ok bool) { 49 result := gjson.GetBytes(*ja.json, key) 50 if !result.Exists() || result.Type != gjson.String { 51 return emptyString, false 52 } 53 return result.String(), true 54 } 55 56 // GetStringArray returns the []string found by the given json key and whether it could be successfully extracted. 57 func (ja *JSONBytesAccessor) GetStringArray(key string) (value []string, ok bool) { 58 result := gjson.GetBytes(*ja.json, key) 59 if !result.Exists() && !result.IsArray() { 60 return nil, false 61 } 62 slice := result.Array() 63 sliceCopy := make([]string, len(slice)) 64 for i, res := range slice { 65 if res.Type == gjson.String { 66 sliceCopy[i] = res.String() 67 } else { 68 return nil, false 69 } 70 } 71 return sliceCopy, true 72 } 73 74 // GetInt returns the int found by the given json key and whether it could be successfully extracted. 75 func (ja *JSONBytesAccessor) GetInt(key string) (value int64, ok bool) { 76 result := gjson.GetBytes(*ja.json, key) 77 if !result.Exists() || result.Type != gjson.Number { 78 return 0, false 79 } 80 return result.Int(), true 81 } 82 83 // GetFloat returns the float found by the given json key and whether it could be successfully extracted. 84 func (ja *JSONBytesAccessor) GetFloat(key string) (value float64, ok bool) { 85 result := gjson.GetBytes(*ja.json, key) 86 if !result.Exists() || result.Type != gjson.Number { 87 return 0, false 88 } 89 return result.Float(), true 90 } 91 92 // GetBool returns the bool found by the given json key and whether it could be successfully extracted. 93 func (ja *JSONBytesAccessor) GetBool(key string) (value bool, ok bool) { 94 result := gjson.GetBytes(*ja.json, key) 95 switch { 96 case !result.Exists(): 97 return false, false 98 case result.Type == gjson.True: 99 return true, true 100 case result.Type == gjson.False: 101 return false, true 102 default: 103 return false, false 104 } 105 } 106 107 // Exists returns the whether the given key exists. 108 func (ja *JSONBytesAccessor) Exists(key string) bool { 109 result := gjson.GetBytes(*ja.json, key) 110 return result.Exists() 111 } 112 113 // Type returns the accessor type as a string. 114 func (ja *JSONBytesAccessor) Type() string { 115 return "JSONBytesAccessor" 116 }