changed types.JsonArray to support generics

This commit is contained in:
Gani Georgiev
2023-03-22 17:12:44 +02:00
parent a79f3a7c56
commit 923fc26a31
13 changed files with 69 additions and 65 deletions
+1 -1
View File
@@ -254,7 +254,7 @@ func TestToUniqueStringSlice(t *testing.T) {
{[]any{0, 1, "test", ""}, []string{"0", "1", "test"}},
{[]string{"test1", "test2", "test1"}, []string{"test1", "test2"}},
{`["test1", "test2", "test2"]`, []string{"test1", "test2"}},
{types.JsonArray{"test1", "test2", "test1"}, []string{"test1", "test2"}},
{types.JsonArray[string]{"test1", "test2", "test1"}, []string{"test1", "test2"}},
}
for i, scenario := range scenarios {
+10 -8
View File
@@ -7,30 +7,32 @@ import (
)
// JsonArray defines a slice that is safe for json and db read/write.
type JsonArray []any
type JsonArray[T any] []T
// internal alias to prevent recursion during marshalization.
type jsonArrayAlias[T any] JsonArray[T]
// MarshalJSON implements the [json.Marshaler] interface.
func (m JsonArray) MarshalJSON() ([]byte, error) {
type alias JsonArray // prevent recursion
func (m JsonArray[T]) MarshalJSON() ([]byte, error) {
// initialize an empty map to ensure that `[]` is returned as json
if m == nil {
m = JsonArray{}
m = JsonArray[T]{}
}
return json.Marshal(alias(m))
return json.Marshal(jsonArrayAlias[T](m))
}
// Value implements the [driver.Valuer] interface.
func (m JsonArray) Value() (driver.Value, error) {
func (m JsonArray[T]) Value() (driver.Value, error) {
data, err := json.Marshal(m)
return string(data), err
}
// Scan implements [sql.Scanner] interface to scan the provided value
// into the current `JsonArray` instance.
func (m *JsonArray) Scan(value any) error {
// into the current JsonArray[T] instance.
func (m *JsonArray[T]) Scan(value any) error {
var data []byte
switch v := value.(type) {
case nil:
+14 -13
View File
@@ -2,6 +2,7 @@ package types_test
import (
"database/sql/driver"
"encoding/json"
"testing"
"github.com/pocketbase/pocketbase/tools/types"
@@ -9,14 +10,14 @@ import (
func TestJsonArrayMarshalJSON(t *testing.T) {
scenarios := []struct {
json types.JsonArray
json json.Marshaler
expected string
}{
{nil, "[]"},
{types.JsonArray{}, `[]`},
{types.JsonArray{1, 2, 3}, `[1,2,3]`},
{types.JsonArray{"test1", "test2", "test3"}, `["test1","test2","test3"]`},
{types.JsonArray{1, "test"}, `[1,"test"]`},
{new(types.JsonArray[any]), "[]"},
{types.JsonArray[any]{}, `[]`},
{types.JsonArray[int]{1, 2, 3}, `[1,2,3]`},
{types.JsonArray[string]{"test1", "test2", "test3"}, `["test1","test2","test3"]`},
{types.JsonArray[any]{1, "test"}, `[1,"test"]`},
}
for i, s := range scenarios {
@@ -33,14 +34,14 @@ func TestJsonArrayMarshalJSON(t *testing.T) {
func TestJsonArrayValue(t *testing.T) {
scenarios := []struct {
json types.JsonArray
json driver.Valuer
expected driver.Value
}{
{nil, `[]`},
{types.JsonArray{}, `[]`},
{types.JsonArray{1, 2, 3}, `[1,2,3]`},
{types.JsonArray{"test1", "test2", "test3"}, `["test1","test2","test3"]`},
{types.JsonArray{1, "test"}, `[1,"test"]`},
{new(types.JsonArray[any]), `[]`},
{types.JsonArray[any]{}, `[]`},
{types.JsonArray[int]{1, 2, 3}, `[1,2,3]`},
{types.JsonArray[string]{"test1", "test2", "test3"}, `["test1","test2","test3"]`},
{types.JsonArray[any]{1, "test"}, `[1,"test"]`},
}
for i, s := range scenarios {
@@ -77,7 +78,7 @@ func TestJsonArrayScan(t *testing.T) {
}
for i, s := range scenarios {
arr := types.JsonArray{}
arr := types.JsonArray[any]{}
scanErr := arr.Scan(s.value)
hasErr := scanErr != nil