-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
yangyile
committed
Dec 24, 2024
1 parent
f6fbc6c
commit 3dc0458
Showing
9 changed files
with
549 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
name: create-release | ||
|
||
on: | ||
push: | ||
branches: | ||
- main # 监听 main 分支的 push 操作(编译和测试/代码检查) | ||
tags: | ||
- 'v*' # 监听以 'v' 开头的标签的 push 操作(发布 Release) | ||
|
||
jobs: | ||
lint: | ||
name: lint | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/setup-go@v5 | ||
with: | ||
go-version: "1.23.x" | ||
- uses: actions/checkout@v4 | ||
- name: golangci-lint | ||
uses: golangci/golangci-lint-action@v6 | ||
with: | ||
version: latest | ||
|
||
test: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
go: [ "1.22.x", "1.23.x" ] | ||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- uses: actions/setup-go@v5 | ||
with: | ||
go-version: ${{ matrix.go }} | ||
|
||
- name: Run test | ||
run: make test COVERAGE_DIR=/tmp/coverage | ||
|
||
- name: Send goveralls coverage | ||
uses: shogo82148/actions-goveralls@v1 | ||
with: | ||
path-to-profile: /tmp/coverage/combined.txt | ||
flag-name: Go-${{ matrix.go }} | ||
parallel: true | ||
if: ${{ github.event.repository.fork == false }} # 仅在非 fork 时上传覆盖率 | ||
|
||
check-coverage: | ||
name: Check coverage | ||
needs: [ test ] | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: shogo82148/actions-goveralls@v1 | ||
with: | ||
parallel-finished: true | ||
if: ${{ github.event.repository.fork == false }} # 仅在非 fork 时检查覆盖率 | ||
|
||
# 发布 Release | ||
release: | ||
name: Release a new version | ||
needs: [ lint, test ] | ||
runs-on: ubuntu-latest | ||
# 仅在推送标签时执行 - && - 仅在非 fork 时执行发布 | ||
if: ${{ github.event.repository.fork == false && success() && startsWith(github.ref, 'refs/tags/v') }} | ||
steps: | ||
# 1. 检出代码 | ||
- name: Checkout code | ||
uses: actions/checkout@v4 | ||
|
||
# 2. 创建 Release 和上传源码包 | ||
- name: Create Release | ||
uses: softprops/action-gh-release@v2 | ||
with: | ||
generate_release_notes: true | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
COVERAGE_DIR ?= .coverage | ||
|
||
# cp from: https://github.com/yyle88/gormcngen/blob/5f75d814c71ec306b276a804c134de6655913951/Makefile#L4 | ||
test: | ||
@-rm -r $(COVERAGE_DIR) | ||
@mkdir $(COVERAGE_DIR) | ||
make test-with-flags TEST_FLAGS='-v -race -covermode atomic -coverprofile $$(COVERAGE_DIR)/combined.txt -bench=. -benchmem -timeout 20m' | ||
|
||
test-with-flags: | ||
@go test $(TEST_FLAGS) ./... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,9 @@ | ||
# xjson | ||
xjson is a generic JSON parser that depends on `github.com/bitly/go-simplejson`, enhancing type safety and flexibility in JSON processing, while requiring at least Go 1.22 (with generics). | ||
[![GitHub Workflow Status (branch)](https://img.shields.io/github/actions/workflow/status/yyle88/simplejsonx/release.yml?branch=main&label=BUILD)](https://github.com/yyle88/simplejsonx/actions/workflows/release.yml?query=branch%3Amain) | ||
[![GoDoc](https://pkg.go.dev/badge/github.com/yyle88/simplejsonx)](https://pkg.go.dev/github.com/yyle88/simplejsonx) | ||
[![Coverage Status](https://img.shields.io/coveralls/github/yyle88/simplejsonx/master.svg)](https://coveralls.io/github/yyle88/simplejsonx?branch=main) | ||
![Supported Go Versions](https://img.shields.io/badge/Go-1.22%2C%201.23-lightgrey.svg) | ||
[![GitHub Release](https://img.shields.io/github/release/yyle88/simplejsonx.svg)](https://github.com/yyle88/simplejsonx/releases) | ||
[![Go Report Card](https://goreportcard.com/badge/github.com/yyle88/simplejsonx)](https://goreportcard.com/report/github.com/yyle88/simplejsonx) | ||
|
||
# simplejsonx | ||
simplejsonx is a generic JSON parser that depends on `github.com/bitly/go-simplejson`, enhancing type safety and flexibility in JSON processing, while requiring at least Go 1.22 (with generics). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
module github.com/yyle88/simplejsonx | ||
|
||
go 1.22.8 | ||
|
||
require ( | ||
github.com/bitly/go-simplejson v0.5.1 | ||
github.com/pkg/errors v0.9.1 | ||
github.com/stretchr/testify v1.10.0 | ||
github.com/yyle88/tern v0.0.4 | ||
) | ||
|
||
require ( | ||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect | ||
github.com/kr/pretty v0.3.1 // indirect | ||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect | ||
github.com/rogpeppe/go-internal v1.13.1 // indirect | ||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect | ||
gopkg.in/yaml.v3 v3.0.1 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
github.com/bitly/go-simplejson v0.5.1 h1:xgwPbetQScXt1gh9BmoJ6j9JMr3TElvuIyjR8pgdoow= | ||
github.com/bitly/go-simplejson v0.5.1/go.mod h1:YOPVLzCfwK14b4Sff3oP1AmGhI9T9Vsg84etUnlyp+Q= | ||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= | ||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= | ||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= | ||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= | ||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= | ||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | ||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | ||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | ||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= | ||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= | ||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= | ||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= | ||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= | ||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= | ||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= | ||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= | ||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= | ||
github.com/yyle88/tern v0.0.4 h1:PFirncRmdzpMZl6G41Z0Ihmx/XB6PdSQWAHa4a1+PQk= | ||
github.com/yyle88/tern v0.0.4/go.mod h1:g9weyOMLtXYyt37EAshZPUTTHdH7WFauuxDi4oPr7/8= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= | ||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package simplejsonx | ||
|
||
import ( | ||
"github.com/bitly/go-simplejson" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
// Load creates a simplejson.Json instance from bytes, same as simplejson.NewJson(data). | ||
func Load(data []byte) (simpleJson *simplejson.Json, err error) { | ||
simpleJson, err = simplejson.NewJson(data) | ||
if err != nil { | ||
return nil, errors.WithMessage(err, "unable to parse JSON") | ||
} | ||
return simpleJson, nil | ||
} | ||
|
||
// Wrap creates a simplejson.Json instance with the provided value as the root element. | ||
func Wrap(value interface{}) (simpleJson *simplejson.Json) { | ||
simpleJson = simplejson.New() | ||
simpleJson.SetPath([]string{}, value) | ||
return simpleJson | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package simplejsonx_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
"github.com/yyle88/simplejsonx" | ||
) | ||
|
||
func TestLoad_ValidJSON(t *testing.T) { | ||
data := []byte(`{"key": "value"}`) | ||
|
||
simpleJson, err := simplejsonx.Load(data) | ||
require.NoError(t, err) | ||
|
||
res, err := simpleJson.Get("key").String() | ||
require.NoError(t, err) | ||
require.Equal(t, "value", res) | ||
} | ||
|
||
func TestLoad_InvalidJSON(t *testing.T) { | ||
data := []byte(`invalid message`) | ||
|
||
simpleJson, err := simplejsonx.Load(data) | ||
require.Error(t, err) | ||
require.Nil(t, simpleJson) | ||
} | ||
|
||
func TestLoad_EmptyInput(t *testing.T) { | ||
data := []byte(``) | ||
|
||
simpleJson, err := simplejsonx.Load(data) | ||
require.Error(t, err) | ||
require.Nil(t, simpleJson) | ||
} | ||
|
||
func TestWrap(t *testing.T) { | ||
value := map[string]interface{}{ | ||
"key": "abc", | ||
} | ||
|
||
simpleJson := simplejsonx.Wrap(value) | ||
require.NotNil(t, simpleJson) | ||
|
||
res, err := simpleJson.Get("key").String() | ||
require.NoError(t, err) | ||
require.Equal(t, "abc", res) | ||
} | ||
|
||
func TestWrap_WithPrimitiveValue(t *testing.T) { | ||
value := 88 | ||
|
||
simpleJson := simplejsonx.Wrap(value) | ||
require.NotNil(t, simpleJson) | ||
|
||
res, err := simpleJson.Int() | ||
require.NoError(t, err) | ||
require.Equal(t, 88, res) | ||
} | ||
|
||
func TestWrap_InvalidNone(t *testing.T) { | ||
simpleJson := simplejsonx.Wrap(nil) | ||
require.NotNil(t, simpleJson) | ||
|
||
{ | ||
res, err := simpleJson.Int() | ||
require.Error(t, err) | ||
require.Equal(t, 0, res) | ||
} | ||
|
||
{ | ||
res, err := simpleJson.Get("abc").String() | ||
require.Error(t, err) | ||
require.Equal(t, "", res) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package simplejsonx | ||
|
||
import ( | ||
"github.com/bitly/go-simplejson" | ||
"github.com/pkg/errors" | ||
"github.com/yyle88/tern" | ||
) | ||
|
||
// Extract retrieves the value associated with the given key in the JSON object. | ||
func Extract[T any](simpleJson *simplejson.Json, key string) (T, error) { | ||
if simpleJson == nil { | ||
return tern.Zero[T](), errors.New("parameter simpleJson is missing") | ||
} | ||
return Resolve[T](simpleJson.Get(key)) | ||
} | ||
|
||
/* | ||
Resolve extracts the value from the provided JSON and convert it to typed value. | ||
Supports the following functions: | ||
func (j *Json) Int() (int, error) | ||
func (j *Json) Int64() (int64, error) | ||
func (j *Json) Float64() (float64, error) | ||
func (j *Json) String() (string, error) | ||
func (j *Json) Uint64() (uint64, error) | ||
func (j *Json) Bool() (bool, error) | ||
func (j *Json) StringArray() ([]string, error) | ||
func (j *Json) Array() ([]interface{}, error) | ||
func (j *Json) Map() (map[string]interface{}, error) | ||
func (j *Json) Bytes() ([]byte, error) | ||
*/ | ||
|
||
func Resolve[T any](simpleJson *simplejson.Json) (T, error) { | ||
if simpleJson == nil { | ||
return tern.Zero[T](), errors.New("parameter simpleJson is missing") | ||
} | ||
switch zero := tern.Zero[T](); any(zero).(type) { | ||
case int: | ||
res, err := simpleJson.Int() | ||
if err != nil { | ||
return zero, errors.WithMessage(err, "unable to resolve JSON value to int") | ||
} | ||
return any(res).(T), nil | ||
case int64: | ||
res, err := simpleJson.Int64() | ||
if err != nil { | ||
return zero, errors.WithMessage(err, "unable to resolve JSON value to int64") | ||
} | ||
return any(res).(T), nil | ||
case float64: | ||
res, err := simpleJson.Float64() | ||
if err != nil { | ||
return zero, errors.WithMessage(err, "unable to resolve JSON value to float64") | ||
} | ||
return any(res).(T), nil | ||
case string: | ||
res, err := simpleJson.String() | ||
if err != nil { | ||
return zero, errors.WithMessage(err, "unable to resolve JSON value to string") | ||
} | ||
return any(res).(T), nil | ||
case uint64: | ||
res, err := simpleJson.Uint64() | ||
if err != nil { | ||
return zero, errors.WithMessage(err, "unable to resolve JSON value to uint64") | ||
} | ||
return any(res).(T), nil | ||
case bool: | ||
res, err := simpleJson.Bool() | ||
if err != nil { | ||
return zero, errors.WithMessage(err, "unable to resolve JSON value to bool") | ||
} | ||
return any(res).(T), nil | ||
case []string: | ||
res, err := simpleJson.StringArray() | ||
if err != nil { | ||
return zero, errors.WithMessage(err, "unable to resolve JSON value to []string") | ||
} | ||
return any(res).(T), nil | ||
case []interface{}: | ||
res, err := simpleJson.Array() | ||
if err != nil { | ||
return zero, errors.WithMessage(err, "unable to resolve JSON value to []interface{}") | ||
} | ||
return any(res).(T), nil | ||
case map[string]interface{}: | ||
res, err := simpleJson.Map() | ||
if err != nil { | ||
return zero, errors.WithMessage(err, "unable to resolve JSON value to map[string]interface{}") | ||
} | ||
return any(res).(T), nil | ||
case []byte: | ||
res, err := simpleJson.Bytes() | ||
if err != nil { | ||
return zero, errors.WithMessage(err, "unable to resolve JSON value to []byte") | ||
} | ||
return any(res).(T), nil | ||
default: | ||
return zero, errors.Errorf("unsupported generic type: %T. unable to resolve JSON value.", zero) | ||
} | ||
} |
Oops, something went wrong.