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  }