mirror of https://github.com/rocboss/paopao-ce
parent
0aa6dae372
commit
81ae8c0596
@ -0,0 +1,64 @@
|
||||
// Copyright 2023 ROC. All rights reserved.
|
||||
// Use of this source code is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
stdjson "encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/rocboss/paopao-ce/pkg/json"
|
||||
)
|
||||
|
||||
var (
|
||||
_ stdjson.Marshaler = (*JsonType[any])(nil)
|
||||
_ stdjson.Unmarshaler = (*JsonType[any])(nil)
|
||||
_ driver.Valuer = (*JsonType[any])(nil)
|
||||
_ sql.Scanner = (*JsonType[any])(nil)
|
||||
)
|
||||
|
||||
type JsonType[T any] struct {
|
||||
Data T
|
||||
}
|
||||
|
||||
func (j *JsonType[T]) MarshalJSON() ([]byte, error) {
|
||||
if j == nil {
|
||||
return []byte(`null`), nil
|
||||
}
|
||||
return json.Marshal(j.Data)
|
||||
}
|
||||
|
||||
func (j *JsonType[T]) UnmarshalJSON(data []byte) error {
|
||||
if j == nil {
|
||||
return errors.New("JSONText.UnmarshalJSON: on nil pointer")
|
||||
}
|
||||
return json.Unmarshal(data, &j.Data)
|
||||
|
||||
}
|
||||
|
||||
func (j *JsonType[T]) Value() (driver.Value, error) {
|
||||
if j == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return j.MarshalJSON()
|
||||
}
|
||||
|
||||
func (j *JsonType[T]) Scan(value any) error {
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
var b []byte
|
||||
switch v := value.(type) {
|
||||
case []byte:
|
||||
b = v
|
||||
case string:
|
||||
b = []byte(v)
|
||||
default:
|
||||
return fmt.Errorf("JSONText.Scan: expected []byte or string, got %T (%q)", value, value)
|
||||
}
|
||||
return j.UnmarshalJSON(b)
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
// Copyright 2023 ROC. All rights reserved.
|
||||
// Use of this source code is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package types_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/rocboss/paopao-ce/pkg/types"
|
||||
)
|
||||
|
||||
var _ = Describe("Json", Ordered, func() {
|
||||
type jsonCases []struct {
|
||||
j types.JsonType[json.RawMessage]
|
||||
b []byte
|
||||
}
|
||||
var samples jsonCases
|
||||
|
||||
BeforeAll(func() {
|
||||
samples = jsonCases{
|
||||
{
|
||||
j: types.JsonType[json.RawMessage]{json.RawMessage(`null`)},
|
||||
b: []byte(`null`),
|
||||
},
|
||||
{
|
||||
j: types.JsonType[json.RawMessage]{json.RawMessage(`{}`)},
|
||||
b: []byte(`{}`),
|
||||
},
|
||||
{
|
||||
j: types.JsonType[json.RawMessage]{json.RawMessage(`[]`)},
|
||||
b: []byte(`[]`),
|
||||
},
|
||||
{
|
||||
j: types.JsonType[json.RawMessage]{json.RawMessage(`[{"b":true,"n":123},{"s":"foo","obj":{"f1":456,"f2":false}},[null]]`)},
|
||||
b: []byte(`[{"b":true,"n":123},{"s":"foo","obj":{"f1":456,"f2":false}},[null]]`),
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
It("driver valuer ", func() {
|
||||
for _, t := range samples {
|
||||
v, err := t.j.Value()
|
||||
Expect(err).To(BeNil())
|
||||
Expect(v).To(Equal(t.b))
|
||||
}
|
||||
})
|
||||
|
||||
It("sql scan ", func() {
|
||||
for _, t := range samples {
|
||||
var jv types.JsonType[json.RawMessage]
|
||||
err := jv.Scan(t.b)
|
||||
Expect(err).To(BeNil())
|
||||
Expect(jv.Data).To(Equal(t.j.Data))
|
||||
}
|
||||
})
|
||||
})
|
@ -0,0 +1,17 @@
|
||||
// Copyright 2023 ROC. All rights reserved.
|
||||
// Use of this source code is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package types_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func TestTypes(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Types Suite")
|
||||
}
|
Loading…
Reference in new issue