https://mattermost.atlassian.net/browse/MM-40676

```release-note
NONE
```
Этот коммит содержится в:
Agniva De Sarker
2022-02-09 23:05:16 +05:30
коммит произвёл GitHub
родитель 440790dad6
Коммит 57eafbc6ca
322 изменённых файлов: 24889 добавлений и 14797 удалений

9
vendor/github.com/tidwall/gjson/README.md сгенерированный поставляемый
Просмотреть файл

@@ -4,7 +4,9 @@
width="240" height="78" border="0" alt="GJSON">
<br>
<a href="https://godoc.org/github.com/tidwall/gjson"><img src="https://img.shields.io/badge/api-reference-blue.svg?style=flat-square" alt="GoDoc"></a>
<a href="http://tidwall.com/gjson-play"><img src="https://img.shields.io/badge/%F0%9F%8F%90-playground-9900cc.svg?style=flat-square" alt="GJSON Playground"></a>
<a href="https://tidwall.com/gjson-play"><img src="https://img.shields.io/badge/%F0%9F%8F%90-playground-9900cc.svg?style=flat-square" alt="GJSON Playground"></a>
<a href="SYNTAX.md"><img src="https://img.shields.io/badge/{}-syntax-33aa33.svg?style=flat-square" alt="GJSON Syntax"></a>
</p>
<p align="center">get json values quickly</a></p>
@@ -14,6 +16,8 @@ It has features such as [one line retrieval](#get-a-value), [dot notation paths]
Also check out [SJSON](https://github.com/tidwall/sjson) for modifying json, and the [JJ](https://github.com/tidwall/jj) command line tool.
This README is a quick overview of how to use GJSON, for more information check out [GJSON Syntax](SYNTAX.md).
Getting Started
===============
@@ -202,6 +206,9 @@ There are currently the following built-in modifiers:
- `@join`: Joins multiple objects into a single object.
- `@keys`: Returns an array of keys for an object.
- `@values`: Returns an array of values for an object.
- `@tostr`: Converts json to a string. Wraps a json string.
- `@fromstr`: Converts a string from json. Unwraps a json string.
- `@group`: Groups arrays of objects. See [e4fc67c](https://github.com/tidwall/gjson/commit/e4fc67c92aeebf2089fabc7872f010e340d105db).
### Modifier arguments

33
vendor/github.com/tidwall/gjson/SYNTAX.md сгенерированный поставляемый
Просмотреть файл

@@ -13,16 +13,16 @@ This document is designed to explain the structure of a GJSON Path through examp
- [Dot vs Pipe](#dot-vs-pipe)
- [Modifiers](#modifiers)
- [Multipaths](#multipaths)
- [Literals](#literals)
The definitive implemenation is [github.com/tidwall/gjson](https://github.com/tidwall/gjson).
Use the [GJSON Playground](https://gjson.dev) to experiment with the syntax online.
## Path structure
A GJSON Path is intended to be easily expressed as a series of components seperated by a `.` character.
Along with `.` character, there are a few more that have special meaning, including `|`, `#`, `@`, `\`, `*`, and `?`.
Along with `.` character, there are a few more that have special meaning, including `|`, `#`, `@`, `\`, `*`, `!`, and `?`.
## Example
@@ -77,7 +77,7 @@ Special purpose characters, such as `.`, `*`, and `?` can be escaped with `\`.
fav\.movie "Deer Hunter"
```
You'll also need to make sure that the `\` character is correctly escaped when hardcoding a path in you source code.
You'll also need to make sure that the `\` character is correctly escaped when hardcoding a path in your source code.
```go
// Go
@@ -238,6 +238,9 @@ There are currently the following built-in modifiers:
- `@join`: Joins multiple objects into a single object.
- `@keys`: Returns an array of keys for an object.
- `@values`: Returns an array of values for an object.
- `@tostr`: Converts json to a string. Wraps a json string.
- `@fromstr`: Converts a string from json. Unwraps a json string.
- `@group`: Groups arrays of objects. See [e4fc67c](https://github.com/tidwall/gjson/commit/e4fc67c92aeebf2089fabc7872f010e340d105db).
#### Modifier arguments
@@ -296,7 +299,7 @@ Starting with v1.3.0, GJSON added the ability to join multiple paths together
to form new documents. Wrapping comma-separated paths between `[...]` or
`{...}` will result in a new array or object, respectively.
For example, using the given multipath
For example, using the given multipath:
```
{name.first,age,"the_murphys":friends.#(last="Murphy")#.first}
@@ -312,8 +315,28 @@ determined, then "_" is used.
This results in
```
```json
{"first":"Tom","age":37,"the_murphys":["Dale","Jane"]}
```
### Literals
Starting with v1.12.0, GJSON added support of json literals, which provides a way for constructing static blocks of json. This is can be particularly useful when constructing a new json document using [multipaths](#multipaths).
A json literal begins with the '!' declaration character.
For example, using the given multipath:
```
{name.first,age,"company":!"Happysoft","employed":!true}
```
Here we selected the first name and age. Then add two new fields, "company" and "employed".
This results in
```json
{"first":"Tom","age":37,"company":"Happysoft","employed":true}
```
*See issue [#249](https://github.com/tidwall/gjson/issues/249) for additional context on JSON Literals.*

146
vendor/github.com/tidwall/gjson/gjson.go сгенерированный поставляемый
Просмотреть файл

@@ -214,6 +214,11 @@ func (t Result) IsArray() bool {
return t.Type == JSON && len(t.Raw) > 0 && t.Raw[0] == '['
}
// IsBool returns true if the result value is a JSON boolean.
func (t Result) IsBool() bool {
return t.Type == True || t.Type == False
}
// ForEach iterates through values.
// If the result represents a non-existent value, then no values will be
// iterated. If the result is an Object, the iterator will pass the key and
@@ -229,17 +234,19 @@ func (t Result) ForEach(iterator func(key, value Result) bool) {
return
}
json := t.Raw
var keys bool
var obj bool
var i int
var key, value Result
for ; i < len(json); i++ {
if json[i] == '{' {
i++
key.Type = String
keys = true
obj = true
break
} else if json[i] == '[' {
i++
key.Type = Number
key.Num = -1
break
}
if json[i] > ' ' {
@@ -251,7 +258,7 @@ func (t Result) ForEach(iterator func(key, value Result) bool) {
var ok bool
var idx int
for ; i < len(json); i++ {
if keys {
if obj {
if json[i] != '"' {
continue
}
@@ -267,6 +274,8 @@ func (t Result) ForEach(iterator func(key, value Result) bool) {
}
key.Raw = str
key.Index = s + t.Index
} else {
key.Num += 1
}
for ; i < len(json); i++ {
if json[i] <= ' ' || json[i] == ',' || json[i] == ':' {
@@ -1728,7 +1737,7 @@ type subSelector struct {
// first character in path is either '[' or '{', and has already been checked
// prior to calling this function.
func parseSubSelectors(path string) (sels []subSelector, out string, ok bool) {
modifer := 0
modifier := 0
depth := 1
colon := 0
start := 1
@@ -1743,6 +1752,7 @@ func parseSubSelectors(path string) (sels []subSelector, out string, ok bool) {
}
sels = append(sels, sel)
colon = 0
modifier = 0
start = i + 1
}
for ; i < len(path); i++ {
@@ -1750,11 +1760,11 @@ func parseSubSelectors(path string) (sels []subSelector, out string, ok bool) {
case '\\':
i++
case '@':
if modifer == 0 && i > 0 && (path[i-1] == '.' || path[i-1] == '|') {
modifer = i
if modifier == 0 && i > 0 && (path[i-1] == '.' || path[i-1] == '|') {
modifier = i
}
case ':':
if modifer == 0 && colon == 0 && depth == 1 {
if modifier == 0 && colon == 0 && depth == 1 {
colon = i
}
case ',':
@@ -1807,7 +1817,7 @@ func isSimpleName(component string) bool {
return false
}
switch component[i] {
case '[', ']', '{', '}', '(', ')', '#', '|':
case '[', ']', '{', '}', '(', ')', '#', '|', '!':
return false
}
}
@@ -1871,23 +1881,25 @@ type parseContext struct {
// use the Valid function first.
func Get(json, path string) Result {
if len(path) > 1 {
if !DisableModifiers {
if path[0] == '@' {
// possible modifier
var ok bool
var npath string
var rjson string
if (path[0] == '@' && !DisableModifiers) || path[0] == '!' {
// possible modifier
var ok bool
var npath string
var rjson string
if path[0] == '@' && !DisableModifiers {
npath, rjson, ok = execModifier(json, path)
if ok {
path = npath
if len(path) > 0 && (path[0] == '|' || path[0] == '.') {
res := Get(rjson, path[1:])
res.Index = 0
res.Indexes = nil
return res
}
return Parse(rjson)
} else if path[0] == '!' {
npath, rjson, ok = execStatic(json, path)
}
if ok {
path = npath
if len(path) > 0 && (path[0] == '|' || path[0] == '.') {
res := Get(rjson, path[1:])
res.Index = 0
res.Indexes = nil
return res
}
return Parse(rjson)
}
}
if path[0] == '[' || path[0] == '{' {
@@ -2556,8 +2568,40 @@ func safeInt(f float64) (n int64, ok bool) {
return int64(f), true
}
// execStatic parses the path to find a static value.
// The input expects that the path already starts with a '!'
func execStatic(json, path string) (pathOut, res string, ok bool) {
name := path[1:]
if len(name) > 0 {
switch name[0] {
case '{', '[', '"', '+', '-', '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9':
_, res = parseSquash(name, 0)
pathOut = name[len(res):]
return pathOut, res, true
}
}
for i := 1; i < len(path); i++ {
if path[i] == '|' {
pathOut = path[i:]
name = path[1:i]
break
}
if path[i] == '.' {
pathOut = path[i:]
name = path[1:i]
break
}
}
switch strings.ToLower(name) {
case "true", "false", "null", "nan", "inf":
return pathOut, name, true
}
return pathOut, res, false
}
// execModifier parses the path to find a matching modifier function.
// then input expects that the path already starts with a '@'
// The input expects that the path already starts with a '@'
func execModifier(json, path string) (pathOut, res string, ok bool) {
name := path[1:]
var hasArgs bool
@@ -2630,6 +2674,9 @@ var modifiers = map[string]func(json, arg string) string{
"valid": modValid,
"keys": modKeys,
"values": modValues,
"tostr": modToStr,
"fromstr": modFromStr,
"group": modGroup,
}
// AddModifier binds a custom modifier command to the GJSON syntax.
@@ -2915,6 +2962,57 @@ func modValid(json, arg string) string {
return json
}
// @fromstr converts a string to json
// "{\"id\":1023,\"name\":\"alert\"}" -> {"id":1023,"name":"alert"}
func modFromStr(json, arg string) string {
if !Valid(json) {
return ""
}
return Parse(json).String()
}
// @tostr converts a string to json
// {"id":1023,"name":"alert"} -> "{\"id\":1023,\"name\":\"alert\"}"
func modToStr(str, arg string) string {
data, _ := json.Marshal(str)
return string(data)
}
func modGroup(json, arg string) string {
res := Parse(json)
if !res.IsObject() {
return ""
}
var all [][]byte
res.ForEach(func(key, value Result) bool {
if !value.IsArray() {
return true
}
var idx int
value.ForEach(func(_, value Result) bool {
if idx == len(all) {
all = append(all, []byte{})
}
all[idx] = append(all[idx], ("," + key.Raw + ":" + value.Raw)...)
idx++
return true
})
return true
})
var data []byte
data = append(data, '[')
for i, item := range all {
if i > 0 {
data = append(data, ',')
}
data = append(data, '{')
data = append(data, item[1:]...)
data = append(data, '}')
}
data = append(data, ']')
return string(data)
}
// stringHeader instead of reflect.StringHeader
type stringHeader struct {
data unsafe.Pointer