From 0a90aa256b640d08a56f447fde9f9d0524fcb1b8 Mon Sep 17 00:00:00 2001
From: aacebo <aacebowork@gmail.com>
Date: Mon, 2 Dec 2024 10:58:17 +0800
Subject: [PATCH] fix for pointer input

---
 gq/pointer.go      |  14 ++++++
 gq/pointer_test.go | 106 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 120 insertions(+)

diff --git a/gq/pointer.go b/gq/pointer.go
index ff5017b..2cb5bc9 100644
--- a/gq/pointer.go
+++ b/gq/pointer.go
@@ -15,6 +15,13 @@ func (self Pointer) Key() string {
 }
 
 func (self Pointer) Do(params *DoParams) Result {
+	value := reflect.ValueOf(params.Value)
+
+	if value.Kind() == reflect.Pointer {
+		value = value.Elem()
+		params.Value = value.Interface()
+	}
+
 	res := self.Type.Do(params)
 	data := reflect.ValueOf(res.Data)
 
@@ -28,6 +35,13 @@ func (self Pointer) Do(params *DoParams) Result {
 }
 
 func (self Pointer) Resolve(params *ResolveParams) Result {
+	value := reflect.ValueOf(params.Value)
+
+	if value.Kind() == reflect.Pointer {
+		value = value.Elem()
+		params.Value = value.Interface()
+	}
+
 	res := self.Type.Resolve(params)
 	data := reflect.ValueOf(res.Data)
 
diff --git a/gq/pointer_test.go b/gq/pointer_test.go
index 1fbacd4..11c653e 100644
--- a/gq/pointer_test.go
+++ b/gq/pointer_test.go
@@ -30,6 +30,28 @@ func TestPointer(t *testing.T) {
 		}
 	})
 
+	t.Run("should resolve *string as pointer", func(t *testing.T) {
+		schema := gq.Pointer{gq.String{}}
+		value := "testing"
+		res := schema.Do(&gq.DoParams{
+			Value: &value,
+		})
+
+		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{
@@ -51,6 +73,28 @@ func TestPointer(t *testing.T) {
 		}
 	})
 
+	t.Run("should resolve *bool as pointer", func(t *testing.T) {
+		schema := gq.Pointer{gq.Bool{}}
+		value := true
+		res := schema.Do(&gq.DoParams{
+			Value: &value,
+		})
+
+		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{
@@ -72,6 +116,28 @@ func TestPointer(t *testing.T) {
 		}
 	})
 
+	t.Run("should resolve *int as pointer", func(t *testing.T) {
+		schema := gq.Pointer{gq.Int{}}
+		value := 102
+		res := schema.Do(&gq.DoParams{
+			Value: &value,
+		})
+
+		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{
@@ -93,6 +159,28 @@ func TestPointer(t *testing.T) {
 		}
 	})
 
+	t.Run("should resolve *float as pointer", func(t *testing.T) {
+		schema := gq.Pointer{gq.Float{}}
+		value := 11.123
+		res := schema.Do(&gq.DoParams{
+			Value: &value,
+		})
+
+		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{
@@ -110,6 +198,24 @@ func TestPointer(t *testing.T) {
 		}
 	})
 
+	t.Run("should resolve `*time.Time` as pointer", func(t *testing.T) {
+		schema := gq.Pointer{gq.Date{}}
+		value := time.Now()
+		res := schema.Do(&gq.DoParams{
+			Value: &value,
+		})
+
+		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"`