github.com/wangyougui/gf/v2@v2.6.5/encoding/gjson/gjson_api.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/wangyougui/gf. 6 7 package gjson 8 9 import ( 10 "fmt" 11 12 "github.com/wangyougui/gf/v2/container/gvar" 13 "github.com/wangyougui/gf/v2/errors/gcode" 14 "github.com/wangyougui/gf/v2/errors/gerror" 15 "github.com/wangyougui/gf/v2/util/gutil" 16 ) 17 18 // Interface returns the json value. 19 func (j *Json) Interface() interface{} { 20 if j == nil { 21 return nil 22 } 23 j.mu.RLock() 24 defer j.mu.RUnlock() 25 if j.p == nil { 26 return nil 27 } 28 return *(j.p) 29 } 30 31 // Var returns the json value as *gvar.Var. 32 func (j *Json) Var() *gvar.Var { 33 return gvar.New(j.Interface()) 34 } 35 36 // IsNil checks whether the value pointed by `j` is nil. 37 func (j *Json) IsNil() bool { 38 if j == nil { 39 return true 40 } 41 j.mu.RLock() 42 defer j.mu.RUnlock() 43 return j.p == nil || *(j.p) == nil 44 } 45 46 // Get retrieves and returns value by specified `pattern`. 47 // It returns all values of current Json object if `pattern` is given ".". 48 // It returns nil if no value found by `pattern`. 49 // 50 // We can also access slice item by its index number in `pattern` like: 51 // "list.10", "array.0.name", "array.0.1.id". 52 // 53 // It returns a default value specified by `def` if value for `pattern` is not found. 54 func (j *Json) Get(pattern string, def ...interface{}) *gvar.Var { 55 if j == nil { 56 return nil 57 } 58 j.mu.RLock() 59 defer j.mu.RUnlock() 60 61 // It returns nil if pattern is empty. 62 if pattern == "" { 63 return nil 64 } 65 66 result := j.getPointerByPattern(pattern) 67 if result != nil { 68 return gvar.New(*result) 69 } 70 if len(def) > 0 { 71 return gvar.New(def[0]) 72 } 73 return nil 74 } 75 76 // GetJson gets the value by specified `pattern`, 77 // and converts it to an un-concurrent-safe Json object. 78 func (j *Json) GetJson(pattern string, def ...interface{}) *Json { 79 return New(j.Get(pattern, def...).Val()) 80 } 81 82 // GetJsons gets the value by specified `pattern`, 83 // and converts it to a slice of un-concurrent-safe Json object. 84 func (j *Json) GetJsons(pattern string, def ...interface{}) []*Json { 85 array := j.Get(pattern, def...).Array() 86 if len(array) > 0 { 87 jsonSlice := make([]*Json, len(array)) 88 for i := 0; i < len(array); i++ { 89 jsonSlice[i] = New(array[i]) 90 } 91 return jsonSlice 92 } 93 return nil 94 } 95 96 // GetJsonMap gets the value by specified `pattern`, 97 // and converts it to a map of un-concurrent-safe Json object. 98 func (j *Json) GetJsonMap(pattern string, def ...interface{}) map[string]*Json { 99 m := j.Get(pattern, def...).Map() 100 if len(m) > 0 { 101 jsonMap := make(map[string]*Json, len(m)) 102 for k, v := range m { 103 jsonMap[k] = New(v) 104 } 105 return jsonMap 106 } 107 return nil 108 } 109 110 // Set sets value with specified `pattern`. 111 // It supports hierarchical data access by char separator, which is '.' in default. 112 func (j *Json) Set(pattern string, value interface{}) error { 113 return j.setValue(pattern, value, false) 114 } 115 116 // MustSet performs as Set, but it panics if any error occurs. 117 func (j *Json) MustSet(pattern string, value interface{}) { 118 if err := j.Set(pattern, value); err != nil { 119 panic(err) 120 } 121 } 122 123 // Remove deletes value with specified `pattern`. 124 // It supports hierarchical data access by char separator, which is '.' in default. 125 func (j *Json) Remove(pattern string) error { 126 return j.setValue(pattern, nil, true) 127 } 128 129 // MustRemove performs as Remove, but it panics if any error occurs. 130 func (j *Json) MustRemove(pattern string) { 131 if err := j.Remove(pattern); err != nil { 132 panic(err) 133 } 134 } 135 136 // Contains checks whether the value by specified `pattern` exist. 137 func (j *Json) Contains(pattern string) bool { 138 return j.Get(pattern) != nil 139 } 140 141 // Len returns the length/size of the value by specified `pattern`. 142 // The target value by `pattern` should be type of slice or map. 143 // It returns -1 if the target value is not found, or its type is invalid. 144 func (j *Json) Len(pattern string) int { 145 p := j.getPointerByPattern(pattern) 146 if p != nil { 147 switch (*p).(type) { 148 case map[string]interface{}: 149 return len((*p).(map[string]interface{})) 150 case []interface{}: 151 return len((*p).([]interface{})) 152 default: 153 return -1 154 } 155 } 156 return -1 157 } 158 159 // Append appends value to the value by specified `pattern`. 160 // The target value by `pattern` should be type of slice. 161 func (j *Json) Append(pattern string, value interface{}) error { 162 p := j.getPointerByPattern(pattern) 163 if p == nil || *p == nil { 164 if pattern == "." { 165 return j.Set("0", value) 166 } 167 return j.Set(fmt.Sprintf("%s.0", pattern), value) 168 } 169 switch (*p).(type) { 170 case []interface{}: 171 if pattern == "." { 172 return j.Set(fmt.Sprintf("%d", len((*p).([]interface{}))), value) 173 } 174 return j.Set(fmt.Sprintf("%s.%d", pattern, len((*p).([]interface{}))), value) 175 } 176 return gerror.NewCodef(gcode.CodeInvalidParameter, "invalid variable type of %s", pattern) 177 } 178 179 // MustAppend performs as Append, but it panics if any error occurs. 180 func (j *Json) MustAppend(pattern string, value interface{}) { 181 if err := j.Append(pattern, value); err != nil { 182 panic(err) 183 } 184 } 185 186 // Map converts current Json object to map[string]interface{}. 187 // It returns nil if fails. 188 func (j *Json) Map() map[string]interface{} { 189 return j.Var().Map() 190 } 191 192 // Array converts current Json object to []interface{}. 193 // It returns nil if fails. 194 func (j *Json) Array() []interface{} { 195 return j.Var().Array() 196 } 197 198 // Scan automatically calls Struct or Structs function according to the type of parameter 199 // `pointer` to implement the converting. 200 func (j *Json) Scan(pointer interface{}, mapping ...map[string]string) error { 201 return j.Var().Scan(pointer, mapping...) 202 } 203 204 // Dump prints current Json object with more manually readable. 205 func (j *Json) Dump() { 206 if j == nil { 207 return 208 } 209 j.mu.RLock() 210 defer j.mu.RUnlock() 211 if j.p == nil { 212 return 213 } 214 gutil.Dump(*j.p) 215 }