-
Notifications
You must be signed in to change notification settings - Fork 374
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(p/json): Update JSON package with new validators and functions #1869
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -71,23 +71,28 @@ Decoding (or Unmarshaling) is the functionality that converts an input byte slic | |
|
||
The converted `Node` type allows you to modify the JSON data or search and extract data that meets specific conditions. | ||
|
||
Below is an example of converting a `Node` type into a JSON string, and retrieving all the keys in the JSON data with `json.UniqueKeyLists()`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's a little bit confusing that you're calling a whole JSON string a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have any metrics on the package? What about adding a few classic test cases to see the performance (with |
||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"gno.land/p/demo/json" | ||
"gno.land/p/demo/ufmt" | ||
) | ||
|
||
func main() { | ||
node, err := json.Unmarshal([]byte(`{"foo": "var"}`)) | ||
data := []byte(`{"foo": "var", "bar": 123, "baz": [1, 2, 3]}`) | ||
node, err := json.Unmarshal(data) | ||
if err != nil { | ||
ufmt.Errorf("error: %v", err) | ||
} | ||
|
||
ufmt.Sprintf("node: %v", node) | ||
ufmt.Println(node.UniqueKeyLists()) | ||
} | ||
|
||
// Output: | ||
// slice[("foo" string),("bar" string),("baz" string)] | ||
``` | ||
|
||
### Encoding | ||
|
@@ -96,29 +101,33 @@ Encoding (or Marshaling) is the functionality that converts JSON data represente | |
|
||
> ⚠️ Caution: Converting a large `Node` type into a JSON string may _impact performance_. or might be cause _unexpected behavior_. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo: |
||
|
||
You can use the `json.Marshal()` method to convert a `Node` type into a JSON string. Below is an example of converting a `Node` type into a JSON string. | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"gno.land/p/demo/json" | ||
"gno.land/p/demo/ufmt" | ||
) | ||
|
||
func main() { | ||
node := ObjectNode("", map[string]*Node{ | ||
"foo": StringNode("foo", "bar"), | ||
"baz": NumberNode("baz", 100500), | ||
"qux": NullNode("qux"), | ||
node := json.ObjectNode("", map[string]*json.Node{ | ||
"foo": json.StringNode("foo", "bar"), | ||
"baz": json.NumberNode("baz", 100500), | ||
"qux": json.NullNode("qux"), | ||
}) | ||
|
||
b, err := json.Marshal(node) | ||
if err != nil { | ||
ufmt.Errorf("error: %v", err) | ||
} | ||
|
||
ufmt.Sprintf("json: %s", string(b)) | ||
ufmt.Println(string(b)) | ||
} | ||
|
||
// Output: | ||
// {"foo":"bar","baz":100500,"qux":null} | ||
``` | ||
|
||
### Searching | ||
|
@@ -133,13 +142,12 @@ Here is an example of finding data with a specific key. For more examples, pleas | |
package main | ||
|
||
import ( | ||
"fmt" | ||
"gno.land/p/demo/json" | ||
"gno.land/p/demo/ufmt" | ||
) | ||
|
||
func main() { | ||
root, err := Unmarshal([]byte(`{"foo": true, "bar": null}`)) | ||
root, err := json.Unmarshal([]byte(`{"foo": true, "bar": null}`)) | ||
if err != nil { | ||
ufmt.Errorf("error: %v", err) | ||
} | ||
|
@@ -149,20 +157,63 @@ func main() { | |
ufmt.Errorf("error occurred while getting key, %s", err) | ||
} | ||
|
||
ufmt.Println(value) | ||
|
||
if value.MustBool() != true { | ||
ufmt.Errorf("value is not true") | ||
} | ||
|
||
value, err = root.GetKey("bar") | ||
if err != nil { | ||
t.Errorf("error occurred while getting key, %s", err) | ||
ufmt.Errorf("error occurred while getting key, %s", err) | ||
} | ||
|
||
_, err = root.GetKey("baz") | ||
if err == nil { | ||
t.Errorf("key baz is not exist. must be failed") | ||
ufmt.Println(value) | ||
} | ||
|
||
// Output: | ||
// true | ||
// null | ||
``` | ||
|
||
### Modifying | ||
|
||
It is not possible to directly modify a JSON string with this package. However, you can modify the data in the desired form using the Node type and then convert it back into a JSON string. | ||
|
||
Currently, this package provides basic functionality for creating and deleting specific types of nodes. For example, to change the value of a specific key or to add a new key, you can use the Update method. | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"gno.land/p/demo/json" | ||
"gno.land/p/demo/ufmt" | ||
) | ||
|
||
func main() { | ||
root, err := json.Unmarshal([]byte(`{"foo": true, "bar": null}`)) | ||
|
||
ufmt.Println("previous: ", root.String()) | ||
|
||
err = root.Update("bar", json.StringNode("bar", "hello")) | ||
if err != nil { | ||
ufmt.Errorf("error occurred while updating, %s", err) | ||
} | ||
|
||
ufmt.Println("updated: ", root.String()) | ||
|
||
err = root.Update("baz", json.StringNode("baz", "hello")) | ||
if err != nil { | ||
ufmt.Errorf("error occurred while updating, %s", err) | ||
} | ||
|
||
ufmt.Println("add new field: ", root.String()) | ||
} | ||
|
||
// Output: | ||
// previous: {"foo": true, "bar": null} | ||
// updated: {"foo":true,"bar":"hello"} | ||
// add new field: {"foo":true,"bar":"hello","baz":"hello"} | ||
``` | ||
|
||
## Contributing | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest you break lines in .md files at 80 chars for easier readability in raw mode ;)