From 899914c40cd4e87867171a526e222b72fb06461c Mon Sep 17 00:00:00 2001
From: ko_oler <kooler89@gmail.com>
Date: Tue, 22 Aug 2023 16:45:14 +0300
Subject: [PATCH] =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=BF?=
 =?UTF-8?q?=D0=BE=20=D0=9F=D0=A0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 pkg/schema/field/timestamp.go      | 49 +++++++++++--------------
 pkg/schema/field/timestamp_test.go | 57 +++++++++++++++++-------------
 2 files changed, 52 insertions(+), 54 deletions(-)

diff --git a/pkg/schema/field/timestamp.go b/pkg/schema/field/timestamp.go
index cbe95923..7626639a 100644
--- a/pkg/schema/field/timestamp.go
+++ b/pkg/schema/field/timestamp.go
@@ -5,8 +5,6 @@ import (
 	"fmt"
 	"reflect"
 	"time"
-
-	"git.perx.ru/perxis/perxis-go/pkg/errors"
 )
 
 var timestampType = &TimestampType{}
@@ -31,31 +29,25 @@ func (TimestampType) IsEmpty(v interface{}) bool {
 }
 
 func (TimestampType) Decode(_ context.Context, _ *Field, v interface{}) (interface{}, error) {
-	if v == nil {
-		return nil, nil
-	}
-
 	switch i := v.(type) {
+	case nil:
+		return 0, nil
 	case string:
 		duration, err := time.ParseDuration(i)
-		if err != nil {
-			t, err := time.Parse(time.TimeOnly, i)
-			if err != nil {
-				return nil, errors.Wrap(err, "wrong format")
-			}
+		if err == nil {
+			return duration.Nanoseconds(), nil
+		}
+		t, err := time.Parse(time.TimeOnly, i)
+		if err == nil {
 			return t.Sub(time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())).Nanoseconds(), nil
 		}
-		return duration.Nanoseconds(), nil
+		return nil, err
 	default:
-		v, err := ToInt(i)
-		if err != nil {
-			return nil, fmt.Errorf("TimestampField decode error: unsupported value type : \"%s\"", reflect.ValueOf(v).Kind())
-		}
-		return v, nil
+		return toTimestamp(i)
 	}
 }
 
-func ToInt(i interface{}) (interface{}, error) {
+func toTimestamp(i interface{}) (interface{}, error) {
 	switch v := i.(type) {
 	case int64:
 		return v, nil
@@ -66,26 +58,25 @@ func ToInt(i interface{}) (interface{}, error) {
 	case int32:
 		return int64(v), nil
 	case uint64:
-		return v, nil
+		return int64(v), nil
 	case uint:
-		return uint64(v), nil
+		return int64(v), nil
 	case uint8:
-		return uint64(v), nil
+		return int64(v), nil
 	case uint32:
-		return uint64(v), nil
+		return int64(v), nil
 	default:
-		return 0, errors.Errorf("error convert \"%s\" to timestamp", i)
+		return 0, fmt.Errorf("unsupported value type: \"%s\"", reflect.ValueOf(v).Kind())
 	}
 }
 
 func (TimestampType) Encode(_ context.Context, _ *Field, v interface{}) (interface{}, error) {
-	if v == nil {
-		return nil, nil
-	}
-	if _, ok := v.(int64); ok {
-		return v, nil
+	switch i := v.(type) {
+	case nil:
+		return 0, nil
+	default:
+		return toTimestamp(i)
 	}
-	return nil, fmt.Errorf("TimestampField encode error: unsupported value type : \"%s\"", reflect.ValueOf(v).Kind())
 }
 
 func Timestamp(o ...interface{}) *Field {
diff --git a/pkg/schema/field/timestamp_test.go b/pkg/schema/field/timestamp_test.go
index 94be768b..67be1abb 100644
--- a/pkg/schema/field/timestamp_test.go
+++ b/pkg/schema/field/timestamp_test.go
@@ -4,6 +4,8 @@ import (
 	"context"
 	"reflect"
 	"testing"
+
+	"github.com/stretchr/testify/require"
 )
 
 func TestTimestamp_Decode(t *testing.T) {
@@ -13,31 +15,34 @@ func TestTimestamp_Decode(t *testing.T) {
 		data    interface{}
 		want    interface{}
 		wantErr bool
+		errMsg  string
 	}{
-		{"Correct", Timestamp(), int64(2), int64(2), false},                 // #0
-		{"Correct", Timestamp(), uint64(2), uint64(2), false},               // #1
-		{"Correct", Timestamp(), 2, int64(2), false},                        // #2
-		{"Correct", Timestamp(), "13h10m44s", int64(47444000000000), false}, // #3
-		{"Correct", Timestamp(), "24h", int64(86400000000000), false},       // #4
-		{"Correct", Timestamp(), "2.5h", int64(9000000000000), false},       // #5
-		{"Correct", Timestamp(), "-5h", int64(-18000000000000), false},      // #5
-		{"Correct", Timestamp(), "13:10:44", int64(47444000000000), false},  // #6
-		{"Correct", Timestamp(), "23:59:59", int64(86399000000000), false},  // #7
-		{"Correct", Timestamp(), "00:00:00", int64(0), false},               // #8
-		{"Correct", Timestamp(), "00:00:01", int64(1000000000), false},      // #8
+		{"Correct", Timestamp(), int64(2), int64(2), false, ""},                 // #0
+		{"Correct", Timestamp(), int32(2), int64(2), false, ""},                 // #1
+		{"Correct", Timestamp(), 2, int64(2), false, ""},                        // #2
+		{"Correct", Timestamp(), "13h10m44s", int64(47444000000000), false, ""}, // #3
+		{"Correct", Timestamp(), "24h", int64(86400000000000), false, ""},       // #4
+		{"Correct", Timestamp(), "2.5h", int64(9000000000000), false, ""},       // #5
+		{"Correct", Timestamp(), "-5h", int64(-18000000000000), false, ""},      // #5
+		{"Correct", Timestamp(), "13:10:44", int64(47444000000000), false, ""},  // #6
+		{"Correct", Timestamp(), "23:59:59", int64(86399000000000), false, ""},  // #7
+		{"Correct", Timestamp(), "00:00:00", int64(0), false, ""},               // #8
+		{"Correct", Timestamp(), "00:00:01", int64(1000000000), false, ""},      // #8
+		{"Correct", Timestamp(), uint64(2), int64(2), false, ""},
+		{"Correct", Timestamp(), nil, 0, false, ""},
 
-		{"Wrong data", Timestamp(), "", nil, true},         // #0
-		{"Wrong data", Timestamp(), []byte(""), nil, true}, // #1
-		{"Wrong data", Timestamp(), 2.2, nil, true},        // #2
-		{"Wrong data", Timestamp(), "13:10", nil, true},    // #3
-		{"Wrong data", Timestamp(), "24:00:00", nil, true}, // #4
+		{"Wrong data", Timestamp(), "", nil, true, "decode error: parsing time \"\" as \"15:04:05\": cannot parse \"\" as \"15\""},          // #0
+		{"Wrong data", Timestamp(), []byte(""), nil, true, "decode error: unsupported value type: \"slice\""},                               // #1
+		{"Wrong data", Timestamp(), 2.2, nil, true, "decode error: unsupported value type: \"float64\""},                                    // #2
+		{"Wrong data", Timestamp(), "13:10", nil, true, "decode error: parsing time \"13:10\" as \"15:04:05\": cannot parse \"\" as \":\""}, // #3
+		{"Wrong data", Timestamp(), "24:00:00", nil, true, "decode error: parsing time \"24:00:00\": hour out of range"},                    // #4
 
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			got, err := Decode(context.Background(), tt.field, tt.data)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("Decode() error = %v, wantErr %v", err, tt.wantErr)
+			if tt.wantErr {
+				require.Equal(t, tt.errMsg, err.Error())
 				return
 			}
 			if !reflect.DeepEqual(got, tt.want) {
@@ -54,20 +59,22 @@ func TestTimestamp_Encode(t *testing.T) {
 		data    interface{}
 		want    interface{}
 		wantErr bool
+		errMsg  string
 	}{
-		{"Correct", Timestamp(), int64(2), int64(2), false}, // #0
+		{"Correct", Timestamp(), int64(2), int64(2), false, ""},  // #0
+		{"Correct", Timestamp(), 2, int64(2), false, ""},         // #1
+		{"Correct", Timestamp(), uint64(2), int64(2), false, ""}, // #2
 
-		{"Wrong data", Timestamp(), "", nil, true},         // #0
-		{"Wrong data", Timestamp(), []byte(""), nil, true}, // #1
-		{"Wrong data", Timestamp(), 2.2, nil, true},        // #2
-		{"Wrong data", Timestamp(), uint64(2), nil, true},  // #2
+		{"Wrong data", Timestamp(), "", nil, true, "encode error: unsupported value type: \"string\""},        // #0
+		{"Wrong data", Timestamp(), []byte(""), nil, true, "encode error: unsupported value type: \"slice\""}, // #1
+		{"Wrong data", Timestamp(), 2.2, nil, true, "encode error: unsupported value type: \"float64\""},      // #2
 
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			got, err := Encode(context.Background(), tt.field, tt.data)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("Decode() error = %v, wantErr %v", err, tt.wantErr)
+			if tt.wantErr {
+				require.Equal(t, tt.errMsg, err.Error())
 				return
 			}
 			if !reflect.DeepEqual(got, tt.want) {
-- 
GitLab