forked from mirror/sjson
fix repos
This commit is contained in:
parent
b279807a1b
commit
a57b12847a
10
README.md
10
README.md
|
@ -3,13 +3,13 @@
|
|||
src="logo.png"
|
||||
width="240" height="78" border="0" alt="SJSON">
|
||||
<br>
|
||||
<a href="https://godoc.org/github.com/tidwall/sjson"><img src="https://img.shields.io/badge/api-reference-blue.svg?style=flat-square" alt="GoDoc"></a>
|
||||
<a href="https://godoc.org/git.internal/re/sjson"><img src="https://img.shields.io/badge/api-reference-blue.svg?style=flat-square" alt="GoDoc"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">set a json value quickly</p>
|
||||
|
||||
SJSON is a Go package that provides a [very fast](#performance) and simple way to set a value in a json document.
|
||||
For quickly retrieving json values check out [GJSON](https://github.com/tidwall/gjson).
|
||||
For quickly retrieving json values check out [GJSON](https://git.internal/re/gjson).
|
||||
|
||||
For a command line interface check out [JJ](https://github.com/tidwall/jj).
|
||||
|
||||
|
@ -22,7 +22,7 @@ Installing
|
|||
To start using SJSON, install Go and run `go get`:
|
||||
|
||||
```sh
|
||||
$ go get -u github.com/tidwall/sjson
|
||||
$ go get -u git.internal/re/sjson
|
||||
```
|
||||
|
||||
This will retrieve the library.
|
||||
|
@ -38,7 +38,7 @@ Invalid paths may return an error.
|
|||
```go
|
||||
package main
|
||||
|
||||
import "github.com/tidwall/sjson"
|
||||
import "git.internal/re/sjson"
|
||||
|
||||
const json = `{"name":{"first":"Janet","last":"Prichard"},"age":47}`
|
||||
|
||||
|
@ -268,7 +268,7 @@ widget.image.hOffset
|
|||
widget.text.onMouseUp
|
||||
```
|
||||
|
||||
*These benchmarks were run on a MacBook Pro 15" 2.8 GHz Intel Core i7 using Go 1.7 and can be be found [here](https://github.com/tidwall/sjson-benchmarks)*.
|
||||
*These benchmarks were run on a MacBook Pro 15" 2.8 GHz Intel Core i7 using Go 1.7 and can be be found [here](https://git.internal/re/sjson-benchmarks)*.
|
||||
|
||||
## Contact
|
||||
Josh Baker [@tidwall](http://twitter.com/tidwall)
|
||||
|
|
4
go.mod
4
go.mod
|
@ -1,8 +1,8 @@
|
|||
module github.com/tidwall/sjson
|
||||
module git.internal/re/sjson
|
||||
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/tidwall/gjson v1.14.2
|
||||
git.internal/re/gjson v1.14.4
|
||||
github.com/tidwall/pretty v1.2.0
|
||||
)
|
||||
|
|
4
go.sum
4
go.sum
|
@ -1,5 +1,5 @@
|
|||
github.com/tidwall/gjson v1.14.2 h1:6BBkirS0rAHjumnjHF6qgy5d2YAJ1TLIaFE2lzfOLqo=
|
||||
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
git.internal/re/gjson v1.14.4 h1:h247IjFbi0EbPbaP9uhmjF4d4BBZdzp3IqVdPbOfNlQ=
|
||||
git.internal/re/gjson v1.14.4/go.mod h1:nWhPHhrw7k8ssdzMTMcw6ButkZOJV9xeqauMiGbDEmo=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
|
|
51
sjson.go
51
sjson.go
|
@ -7,7 +7,7 @@ import (
|
|||
"strconv"
|
||||
"unsafe"
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
"git.internal/re/gjson"
|
||||
)
|
||||
|
||||
type errorType struct {
|
||||
|
@ -134,7 +134,8 @@ func appendStringify(buf []byte, s string) []byte {
|
|||
|
||||
// appendBuild builds a json block from a json path.
|
||||
func appendBuild(buf []byte, array bool, paths []pathResult, raw string,
|
||||
stringify bool) []byte {
|
||||
stringify bool,
|
||||
) []byte {
|
||||
if !array {
|
||||
buf = appendStringify(buf, paths[0].part)
|
||||
buf = append(buf, ':')
|
||||
|
@ -248,7 +249,8 @@ loop:
|
|||
var errNoChange = &errorType{"no change"}
|
||||
|
||||
func appendRawPaths(buf []byte, jstr string, paths []pathResult, raw string,
|
||||
stringify, del bool) ([]byte, error) {
|
||||
stringify, del bool,
|
||||
) ([]byte, error) {
|
||||
var err error
|
||||
var res gjson.Result
|
||||
var found bool
|
||||
|
@ -365,7 +367,8 @@ func appendRawPaths(buf []byte, jstr string, paths []pathResult, raw string,
|
|||
} else {
|
||||
return nil, &errorType{
|
||||
"cannot set array element for non-numeric key '" +
|
||||
paths[0].part + "'"}
|
||||
paths[0].part + "'",
|
||||
}
|
||||
}
|
||||
}
|
||||
if appendit {
|
||||
|
@ -427,19 +430,18 @@ func isOptimisticPath(path string) bool {
|
|||
//
|
||||
// A path is a series of keys separated by a dot.
|
||||
//
|
||||
// {
|
||||
// "name": {"first": "Tom", "last": "Anderson"},
|
||||
// "age":37,
|
||||
// "children": ["Sara","Alex","Jack"],
|
||||
// "friends": [
|
||||
// {"first": "James", "last": "Murphy"},
|
||||
// {"first": "Roger", "last": "Craig"}
|
||||
// ]
|
||||
// }
|
||||
// "name.last" >> "Anderson"
|
||||
// "age" >> 37
|
||||
// "children.1" >> "Alex"
|
||||
//
|
||||
// {
|
||||
// "name": {"first": "Tom", "last": "Anderson"},
|
||||
// "age":37,
|
||||
// "children": ["Sara","Alex","Jack"],
|
||||
// "friends": [
|
||||
// {"first": "James", "last": "Murphy"},
|
||||
// {"first": "Roger", "last": "Craig"}
|
||||
// ]
|
||||
// }
|
||||
// "name.last" >> "Anderson"
|
||||
// "age" >> 37
|
||||
// "children.1" >> "Alex"
|
||||
func Set(json, path string, value interface{}) (string, error) {
|
||||
return SetOptions(json, path, value, nil)
|
||||
}
|
||||
|
@ -504,7 +506,8 @@ type sliceHeader struct {
|
|||
}
|
||||
|
||||
func set(jstr, path, raw string,
|
||||
stringify, del, optimistic, inplace bool) ([]byte, error) {
|
||||
stringify, del, optimistic, inplace bool,
|
||||
) ([]byte, error) {
|
||||
if path == "" {
|
||||
return []byte(jstr), &errorType{"path cannot be empty"}
|
||||
}
|
||||
|
@ -519,7 +522,8 @@ func set(jstr, path, raw string,
|
|||
if !stringify || !mustMarshalString(raw) {
|
||||
jsonh := *(*stringHeader)(unsafe.Pointer(&jstr))
|
||||
jsonbh := sliceHeader{
|
||||
data: jsonh.data, len: jsonh.len, cap: jsonh.len}
|
||||
data: jsonh.data, len: jsonh.len, cap: jsonh.len,
|
||||
}
|
||||
jbytes := *(*[]byte)(unsafe.Pointer(&jsonbh))
|
||||
if stringify {
|
||||
jbytes[res.Index] = '"'
|
||||
|
@ -629,7 +633,8 @@ func setComplexPath(jstr, path, raw string, stringify bool) ([]byte, error) {
|
|||
// Invalid json will not panic, but it may return back unexpected results.
|
||||
// An error is returned if the path is not valid.
|
||||
func SetOptions(json, path string, value interface{},
|
||||
opts *Options) (string, error) {
|
||||
opts *Options,
|
||||
) (string, error) {
|
||||
if opts != nil {
|
||||
if opts.ReplaceInPlace {
|
||||
// it's not safe to replace bytes in-place for strings
|
||||
|
@ -650,7 +655,8 @@ func SetOptions(json, path string, value interface{},
|
|||
// If working with bytes, this method preferred over
|
||||
// SetOptions(string(data), path, value)
|
||||
func SetBytesOptions(json []byte, path string, value interface{},
|
||||
opts *Options) ([]byte, error) {
|
||||
opts *Options,
|
||||
) ([]byte, error) {
|
||||
var optimistic, inplace bool
|
||||
if opts != nil {
|
||||
optimistic = opts.Optimistic
|
||||
|
@ -721,7 +727,8 @@ func SetBytesOptions(json []byte, path string, value interface{},
|
|||
// If working with bytes, this method preferred over
|
||||
// SetRawOptions(string(data), path, value, opts)
|
||||
func SetRawBytesOptions(json []byte, path string, value []byte,
|
||||
opts *Options) ([]byte, error) {
|
||||
opts *Options,
|
||||
) ([]byte, error) {
|
||||
jstr := *(*string)(unsafe.Pointer(&json))
|
||||
vstr := *(*string)(unsafe.Pointer(&value))
|
||||
var optimistic, inplace bool
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
"git.internal/re/gjson"
|
||||
"github.com/tidwall/pretty"
|
||||
)
|
||||
|
||||
|
@ -62,6 +62,7 @@ func testRaw(t *testing.T, kind int, expect, json, path string, value interface{
|
|||
t.Fatalf("expected '%v', got '%v'", expect, string(json3))
|
||||
}
|
||||
}
|
||||
|
||||
func TestBasic(t *testing.T) {
|
||||
testRaw(t, setRaw, `[{"hiw":"planet","hi":"world"}]`, `[{"hi":"world"}]`, "0.hiw", `"planet"`)
|
||||
testRaw(t, setRaw, `[true]`, ``, "0", `true`)
|
||||
|
@ -190,7 +191,7 @@ func TestDeleteIssue21(t *testing.T) {
|
|||
expectedForLenBefore309AsBytes := `{"1":"","0":"01234567890123456789012345678901234567890123456789012345678901234567890123456","2":""}`
|
||||
//---------------------------
|
||||
|
||||
var data = []struct {
|
||||
data := []struct {
|
||||
desc string
|
||||
input string
|
||||
expected string
|
||||
|
@ -214,7 +215,6 @@ func TestDeleteIssue21(t *testing.T) {
|
|||
|
||||
for i, d := range data {
|
||||
result, err := Delete(d.input, "to_delete")
|
||||
|
||||
if err != nil {
|
||||
t.Error(fmtErrorf(testError{
|
||||
unexpected: "error",
|
||||
|
@ -270,6 +270,7 @@ func TestSetDotKeyIssue10(t *testing.T) {
|
|||
t.Fatalf("expected '%v', got '%v'", `{"app.token":"cde"}`, json)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteDotKeyIssue19(t *testing.T) {
|
||||
json := []byte(`{"data":{"key1":"value1","key2.something":"value2"}}`)
|
||||
json, _ = DeleteBytes(json, `data.key2\.something`)
|
||||
|
@ -279,12 +280,12 @@ func TestDeleteDotKeyIssue19(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestIssue36(t *testing.T) {
|
||||
var json = `
|
||||
json := `
|
||||
{
|
||||
"size": 1000
|
||||
}
|
||||
`
|
||||
var raw = `
|
||||
raw := `
|
||||
{
|
||||
"sample": "hello"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue