Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/xieyuschen/astjson
https://github.com/xieyuschen/astjson
Last synced: about 1 month ago
JSON representation
- Host: GitHub
- URL: https://github.com/xieyuschen/astjson
- Owner: xieyuschen
- License: bsd-3-clause
- Created: 2023-10-10T10:43:06.000Z (over 1 year ago)
- Default Branch: master
- Last Pushed: 2023-10-19T04:39:13.000Z (about 1 year ago)
- Last Synced: 2023-10-19T10:27:04.751Z (about 1 year ago)
- Language: Go
- Homepage:
- Size: 18.6 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# astjson
[![codecov](https://codecov.io/gh/xieyuschen/astjson/graph/badge.svg?token=FFXVZQYUWF)](https://codecov.io/gh/xieyuschen/astjson)## Requirement
Astjson requires at least `go1.18` as it uses some features from reflect library.```shell
go get github.com/xieyuschen/astjson
```## Example
```go
package mainimport (
"errors"
"fmt""github.com/xieyuschen/astjson"
)const (
jsonStr = `
{
"num": 999,
"str": "helloworld",
"enabled": true ,
"sub1": {
"sub2": {
"key": 999
}
},
"name": "astjson"
}`
)type (
Sub1 struct {
Sub2 Sub2 `json:"sub2"`
}
Sub2 struct {
Key int `json:"key"`
}
demo struct {
Num int `json:"num"`
Str string `json:"str"`
Enabled bool `json:"enabled"`
Sub Sub1 `json:"sub1"`
}
)func main() {
astValue := astjson.NewParser([]byte(jsonStr)).Parse()
val, err := astjson.NewWalker(astValue).
// field "str" is required
Field("str").
// field "num" is optional, but if it exists the validator will be triggered
Optional("num", equal999).
Field("enabled").Validate(isTrue).
Path("sub1").Path("sub2").Validate(equal999).EndPath().
ValidateKey("name", hasAstjsonName).
Walk()if err != nil {
panic(err)
}
var d demo
_ = astjson.NewDecoder().Unmarshal(val, &d)
fmt.Println(d)
}func equal999(value *astjson.Value) error {
actual := value.AstValue.(astjson.NumberAst).GetInt64()
if actual == 999 {
return nil
}
return errors.New("num should be 999")
}func isTrue(value *astjson.Value) error {
if bool(value.AstValue.(astjson.BoolAst)) {
return nil
}
return errors.New("bool should be true")
}
func hasAstjsonName(value *astjson.Value) error {
if value.AstValue.(astjson.StringAst) == "astjson" {
return nil
}
return errors.New("name should be astjson")
}
```See more [examples here](astjson_example_test.go).
## Motivation
Haskell json library [aeson](https://github.com/haskell/aeson) parsed AST first in its early version as a default way.
However, it skips to convert AST first to speed up parsing as a new default way.Parsing AST first is slower than directly parsing json, however, it provides more flexibilities.
Hence, inspired by aeson, I wrote a ast json to help parsing json to AST.- [json tokens](https://www.json.org/json-en.html)
- [aeson](https://hackage.haskell.org/package/aeson-2.2.1.0/docs/Data-Aeson.html)