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  }