From 763a229c75477a58eb16e2e078ec3dca2cab9038 Mon Sep 17 00:00:00 2001 From: aacebo Date: Sun, 1 Dec 2024 20:07:30 +0800 Subject: [PATCH] add pointer type --- gq/any.go | 10 --- gq/bool.go | 10 --- gq/date.go | 10 --- gq/float.go | 10 --- gq/int.go | 10 --- gq/pointer.go | 45 ++++++++++++++ gq/pointer_test.go | 152 +++++++++++++++++++++++++++++++++++++++++++++ gq/string.go | 10 --- 8 files changed, 197 insertions(+), 60 deletions(-) create mode 100644 gq/pointer.go create mode 100644 gq/pointer_test.go diff --git a/gq/any.go b/gq/any.go index 0a0c9e0..1e776b4 100644 --- a/gq/any.go +++ b/gq/any.go @@ -2,8 +2,6 @@ package gq import ( "encoding/json" - - "github.com/thegogod/rum/gq/query" ) type Any struct{} @@ -13,15 +11,7 @@ func (self Any) Key() string { } func (self Any) Do(params *DoParams) Result { - parser := query.Parser([]byte(params.Query)) - query, err := parser.Parse() - - if err != nil { - return Result{Error: err} - } - return self.Resolve(&ResolveParams{ - Query: query, Value: params.Value, Context: params.Context, }) diff --git a/gq/bool.go b/gq/bool.go index b63abf1..938400f 100644 --- a/gq/bool.go +++ b/gq/bool.go @@ -2,8 +2,6 @@ package gq import ( "encoding/json" - - "github.com/thegogod/rum/gq/query" ) type Bool struct{} @@ -13,15 +11,7 @@ func (self Bool) Key() string { } func (self Bool) Do(params *DoParams) Result { - parser := query.Parser([]byte(params.Query)) - query, err := parser.Parse() - - if err != nil { - return Result{Error: err} - } - return self.Resolve(&ResolveParams{ - Query: query, Value: params.Value, Context: params.Context, }) diff --git a/gq/date.go b/gq/date.go index 321e1d4..2369761 100644 --- a/gq/date.go +++ b/gq/date.go @@ -3,8 +3,6 @@ package gq import ( "encoding/json" "time" - - "github.com/thegogod/rum/gq/query" ) type Date struct{} @@ -14,15 +12,7 @@ func (self Date) Key() string { } func (self Date) Do(params *DoParams) Result { - parser := query.Parser([]byte(params.Query)) - query, err := parser.Parse() - - if err != nil { - return Result{Error: err} - } - return self.Resolve(&ResolveParams{ - Query: query, Value: params.Value, Context: params.Context, }) diff --git a/gq/float.go b/gq/float.go index b84d173..061f895 100644 --- a/gq/float.go +++ b/gq/float.go @@ -2,8 +2,6 @@ package gq import ( "encoding/json" - - "github.com/thegogod/rum/gq/query" ) type Float struct{} @@ -13,15 +11,7 @@ func (self Float) Key() string { } func (self Float) Do(params *DoParams) Result { - parser := query.Parser([]byte(params.Query)) - query, err := parser.Parse() - - if err != nil { - return Result{Error: err} - } - return self.Resolve(&ResolveParams{ - Query: query, Value: params.Value, Context: params.Context, }) diff --git a/gq/int.go b/gq/int.go index b62d78f..693056c 100644 --- a/gq/int.go +++ b/gq/int.go @@ -2,8 +2,6 @@ package gq import ( "encoding/json" - - "github.com/thegogod/rum/gq/query" ) type Int struct{} @@ -13,15 +11,7 @@ func (self Int) Key() string { } func (self Int) Do(params *DoParams) Result { - parser := query.Parser([]byte(params.Query)) - query, err := parser.Parse() - - if err != nil { - return Result{Error: err} - } - return self.Resolve(&ResolveParams{ - Query: query, Value: params.Value, Context: params.Context, }) diff --git a/gq/pointer.go b/gq/pointer.go new file mode 100644 index 0000000..ff5017b --- /dev/null +++ b/gq/pointer.go @@ -0,0 +1,45 @@ +package gq + +import ( + "encoding/json" + "fmt" + "reflect" +) + +type Pointer struct { + Type Schema +} + +func (self Pointer) Key() string { + return fmt.Sprintf("Pointer[%s]", self.Type.Key()) +} + +func (self Pointer) Do(params *DoParams) Result { + res := self.Type.Do(params) + data := reflect.ValueOf(res.Data) + + if data.IsValid() && data.Kind() != reflect.Pointer { + pointer := reflect.New(data.Type()) + pointer.Elem().Set(data) + res.Data = pointer.Interface() + } + + return res +} + +func (self Pointer) Resolve(params *ResolveParams) Result { + res := self.Type.Resolve(params) + data := reflect.ValueOf(res.Data) + + if data.IsValid() && data.Kind() != reflect.Pointer { + pointer := reflect.New(data.Type()) + pointer.Elem().Set(data) + res.Data = pointer.Interface() + } + + return res +} + +func (self Pointer) MarshalJSON() ([]byte, error) { + return json.Marshal(self.Key()) +} diff --git a/gq/pointer_test.go b/gq/pointer_test.go new file mode 100644 index 0000000..5a609e8 --- /dev/null +++ b/gq/pointer_test.go @@ -0,0 +1,152 @@ +package gq_test + +import ( + "testing" + "time" + + "github.com/thegogod/rum/gq" +) + +func TestPointer(t *testing.T) { + t.Run("should resolve string as pointer", func(t *testing.T) { + schema := gq.Pointer{gq.String{}} + res := schema.Do(&gq.DoParams{ + Value: "testing", + }) + + if res.Error != nil { + t.Fatal(res.Error) + } + + v, ok := res.Data.(*string) + + if !ok { + t.Fatal(res.Data) + } + + if *v != "testing" { + t.Fatalf("expected `%s`, received `%s`", "testing", *v) + } + }) + + t.Run("should resolve bool as pointer", func(t *testing.T) { + schema := gq.Pointer{gq.Bool{}} + res := schema.Do(&gq.DoParams{ + Value: true, + }) + + if res.Error != nil { + t.Fatal(res.Error) + } + + v, ok := res.Data.(*bool) + + if !ok { + t.Fatal(res.Data) + } + + if *v != true { + t.Fatalf("expected `%v`, received `%v`", true, *v) + } + }) + + t.Run("should resolve int as pointer", func(t *testing.T) { + schema := gq.Pointer{gq.Int{}} + res := schema.Do(&gq.DoParams{ + Value: 102, + }) + + if res.Error != nil { + t.Fatal(res.Error) + } + + v, ok := res.Data.(*int) + + if !ok { + t.Fatal(res.Data) + } + + if *v != 102 { + t.Fatalf("expected `%v`, received `%v`", 102, *v) + } + }) + + t.Run("should resolve float as pointer", func(t *testing.T) { + schema := gq.Pointer{gq.Float{}} + res := schema.Do(&gq.DoParams{ + Value: 11.123, + }) + + if res.Error != nil { + t.Fatal(res.Error) + } + + v, ok := res.Data.(*float64) + + if !ok { + t.Fatal(res.Data) + } + + if *v != 11.123 { + t.Fatalf("expected `%v`, received `%v`", 11.123, *v) + } + }) + + t.Run("should resolve `time.Time` as pointer", func(t *testing.T) { + schema := gq.Pointer{gq.Date{}} + res := schema.Do(&gq.DoParams{ + Value: time.Now(), + }) + + if res.Error != nil { + t.Fatal(res.Error) + } + + _, ok := res.Data.(*time.Time) + + if !ok { + t.Fatal(res.Data) + } + }) + + t.Run("should resolve struct as pointer", func(t *testing.T) { + type User struct { + Name string `json:"name"` + Email string `json:"email"` + } + + schema := gq.Pointer{gq.Object[User]{ + Name: "User", + Fields: gq.Fields{ + "name": gq.Field{Type: gq.String{}}, + "email": gq.Field{Type: gq.String{}}, + }, + }} + + res := schema.Do(&gq.DoParams{ + Query: "{name,email}", + Value: User{ + Name: "test", + Email: "test@test.com", + }, + }) + + if res.Error != nil { + t.Fatal(res.Error) + } + + user, ok := res.Data.(*User) + + if !ok { + t.Fatal(res.Data) + } + + if user.Name != "test" { + t.Fatalf("expected `%s`, received `%s`", "test", user.Name) + } + + if user.Email != "test@test.com" { + t.Fatalf("expected `%s`, received `%s`", "test@test.com", user.Email) + } + }) +} diff --git a/gq/string.go b/gq/string.go index f986777..db1063f 100644 --- a/gq/string.go +++ b/gq/string.go @@ -2,8 +2,6 @@ package gq import ( "encoding/json" - - "github.com/thegogod/rum/gq/query" ) type String struct{} @@ -13,15 +11,7 @@ func (self String) Key() string { } func (self String) Do(params *DoParams) Result { - parser := query.Parser([]byte(params.Query)) - query, err := parser.Parse() - - if err != nil { - return Result{Error: err} - } - return self.Resolve(&ResolveParams{ - Query: query, Value: params.Value, Context: params.Context, })