From 04858e304f5d2cf37d6604812500ede443a22ae7 Mon Sep 17 00:00:00 2001 From: xing Date: Sat, 21 Jan 2023 19:31:23 +0800 Subject: [PATCH] =?UTF-8?q?helper=E5=87=BD=E6=95=B0=20=E5=88=86=E5=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- helper/func.go | 95 +------ helper/func_test.go | 248 +----------------- helper/{ => html}/html.go | 9 +- helper/{ => html}/html_test.go | 10 +- helper/{ => maps}/function.go | 6 +- helper/{ => maps}/function_test.go | 10 +- helper/{ => maps}/map.go | 10 +- helper/{ => maps}/map_test.go | 16 +- helper/number/number.go | 67 +++++ helper/number/number_test.go | 193 ++++++++++++++ helper/{ => slice}/slice.go | 53 ++-- helper/{ => slice}/slice_test.go | 164 ++++-------- helper/slice/sort.go | 42 +++ helper/slice/sort_test.go | 112 ++++++++ helper/{ => strings}/strings.go | 6 +- helper/{ => strings}/strings_test.go | 6 +- internal/actions/comment.go | 4 +- internal/actions/detail.go | 4 +- internal/actions/feed.go | 6 +- internal/actions/index.go | 9 +- internal/actions/login.go | 4 +- internal/middleware/flowLimit.go | 4 +- internal/middleware/staticFileCache.go | 4 +- internal/phpass/phpass.go | 4 +- internal/pkg/cache/feed.go | 12 +- internal/pkg/cache/posts.go | 6 +- internal/pkg/dao/comments.go | 7 +- internal/pkg/dao/postmeta.go | 6 +- internal/pkg/dao/posts.go | 3 +- internal/pkg/models/wp_postmeta.go | 6 +- internal/plugins/gravatar.go | 4 +- internal/plugins/pagination.go | 4 +- .../theme/twentyseventeen/twentyseventeen.go | 6 +- model/parse.go | 6 +- model/query.go | 4 +- model/query_test.go | 6 +- plugin/digest/digest.go | 11 +- rss2/rss2.go | 4 +- safety/slice_test.go | 4 +- stream/simpleMapStream_test.go | 17 +- stream/simpleStream.go | 16 +- stream/simpleStream_test.go | 43 +-- 42 files changed, 645 insertions(+), 606 deletions(-) rename helper/{ => html}/html.go (94%) rename helper/{ => html}/html_test.go (94%) rename helper/{ => maps}/function.go (79%) rename helper/{ => maps}/function_test.go (88%) rename helper/{ => maps}/map.go (71%) rename helper/{ => maps}/map_test.go (89%) create mode 100644 helper/number/number.go create mode 100644 helper/number/number_test.go rename helper/{ => slice}/slice.go (64%) rename helper/{ => slice}/slice_test.go (61%) create mode 100644 helper/slice/sort.go create mode 100644 helper/slice/sort_test.go rename helper/{ => strings}/strings.go (78%) rename helper/{ => strings}/strings_test.go (69%) diff --git a/helper/func.go b/helper/func.go index b5e918e..302ca66 100644 --- a/helper/func.go +++ b/helper/func.go @@ -1,31 +1,14 @@ package helper import ( - "fmt" - "math/rand" "reflect" - "sort" ) -type IntNumber interface { - ~int | ~int64 | ~int32 | ~int8 | ~int16 | - ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 -} - func ToAny[T any](v T) any { return v } -func IsContainInArr[T comparable](a T, arr []T) bool { - for _, v := range arr { - if a == v { - return true - } - } - return false -} - -func StructColumn[T any, M any](arr []M, field string) (r []T) { +func StructColumnToSlice[T any, M any](arr []M, field string) (r []T) { for i := 0; i < len(arr); i++ { v := reflect.ValueOf(arr[i]).FieldByName(field).Interface() if val, ok := v.(T); ok { @@ -34,79 +17,3 @@ func StructColumn[T any, M any](arr []M, field string) (r []T) { } return } - -func RandNum[T IntNumber](start, end T) T { - end++ - return T(rand.Int63n(int64(end-start))) + start -} - -type anyArr[T any] struct { - data []T - fn func(i, j T) bool -} - -func (r anyArr[T]) Len() int { - return len(r.data) -} - -func (r anyArr[T]) Swap(i, j int) { - r.data[i], r.data[j] = r.data[j], r.data[i] -} - -func (r anyArr[T]) Less(i, j int) bool { - return r.fn(r.data[i], r.data[j]) -} - -func SimpleSort[T any](arr []T, fn func(i, j T) bool) { - slice := anyArr[T]{ - data: arr, - fn: fn, - } - sort.Sort(slice) - return -} - -func SimpleSortR[T any](arr []T, fn func(i, j T) bool) (r []T) { - r = make([]T, 0, len(arr)) - for _, t := range arr { - r = append(r, t) - } - slice := anyArr[T]{ - data: r, - fn: fn, - } - sort.Sort(slice) - return -} - -func Min[T IntNumber | ~float64 | ~float32](a ...T) T { - min := a[0] - for _, t := range a { - if min > t { - min = t - } - } - return min -} - -func Max[T IntNumber | ~float64 | ~float32](a ...T) T { - max := a[0] - for _, t := range a { - if max < t { - max = t - } - } - return max -} - -func Sum[T IntNumber | ~float64 | ~float32](a ...T) T { - s := T(0) - for _, t := range a { - s += t - } - return s -} - -func NumberToString[T IntNumber | ~float64 | ~float32](n T) string { - return fmt.Sprintf("%v", n) -} diff --git a/helper/func_test.go b/helper/func_test.go index 3fd7bdd..7ea6f0c 100644 --- a/helper/func_test.go +++ b/helper/func_test.go @@ -34,17 +34,17 @@ func BenchmarkOr(b *testing.B) { } } -func BenchmarkStructColumn(b *testing.B) { +func BenchmarkStructColumnToSlice(b *testing.B) { y := getX() fmt.Println(y) b.ResetTimer() //b.N = 2 for i := 0; i < 1; i++ { - StructColumn[int, *x](y, "Id") + StructColumnToSlice[int, *x](y, "Id") } } -func TestStructColumn(t *testing.T) { +func TestStructColumnToSlice(t *testing.T) { type args struct { arr []x field string @@ -67,14 +67,14 @@ func TestStructColumn(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if gotR := StructColumn[uint64, x](tt.args.arr, tt.args.field); !reflect.DeepEqual(gotR, tt.wantR) { - t.Errorf("StructColumn() = %v, want %v", gotR, tt.wantR) + if gotR := StructColumnToSlice[uint64, x](tt.args.arr, tt.args.field); !reflect.DeepEqual(gotR, tt.wantR) { + t.Errorf("StructColumnToSlice() = %v, want %v", gotR, tt.wantR) } }) } } -func TestToInterface(t *testing.T) { +func TestToAny(t *testing.T) { type args struct { v int } @@ -97,239 +97,3 @@ func TestToInterface(t *testing.T) { }) } } - -func TestRandNum(t *testing.T) { - type args struct { - start int - end int - } - tests := []struct { - name string - args args - }{ - { - name: "t1", - args: args{ - start: 1, - end: 2, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - for i := 0; i < 100; i++ { - got := RandNum(tt.args.start, tt.args.end) - if got > tt.args.end || got < tt.args.start { - t.Errorf("RandNum() = %v, range error", got) - } - } - }) - } -} - -func TestSimpleSort(t *testing.T) { - type xy struct { - x int - y int - } - - type args struct { - arr []xy - fn func(i, j xy) bool - } - tests := []struct { - name string - args args - wantR []xy - }{ - { - name: "t1", - args: args{ - arr: []xy{ - {1, 2}, - {3, 4}, - {1, 3}, - {2, 1}, - {1, 6}, - }, - fn: func(i, j xy) bool { - if i.x < j.x { - return true - } - if i.x == j.x && i.y > i.y { - return true - } - return false - }, - }, - wantR: []xy{ - {1, 2}, - {1, 3}, - {1, 6}, - {2, 1}, - {3, 4}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if SimpleSort(tt.args.arr, tt.args.fn); !reflect.DeepEqual(tt.args.arr, tt.wantR) { - t.Errorf("SimpleSort() = %v, want %v", tt.args.arr, tt.wantR) - } - }) - } -} - -func TestMin(t *testing.T) { - type args struct { - a []int - } - tests := []struct { - name string - args args - want int - }{ - { - name: "t1", - args: args{a: []int{1, 2, 3}}, - want: 1, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := Min(tt.args.a...); got != tt.want { - t.Errorf("Min() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestMax(t *testing.T) { - type args struct { - a []int - } - tests := []struct { - name string - args args - want int - }{ - { - name: "t1", - args: args{a: []int{1, 2, 3}}, - want: 3, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := Max(tt.args.a...); got != tt.want { - t.Errorf("Max() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestSum(t *testing.T) { - type args struct { - a []int - } - tests := []struct { - name string - args args - want int - }{ - { - name: "t1", - args: args{a: RangeSlice(1, 10, 1)}, - want: 55, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := Sum(tt.args.a...); got != tt.want { - t.Errorf("Sum() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestNumberToString(t *testing.T) { - type args struct { - n float64 - } - tests := []struct { - name string - args args - want string - }{ - { - name: "t1", - args: args{n: 111}, - want: "111", - }, - { - name: "t2", - args: args{n: 111.222222}, - want: "111.222222", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := NumberToString(tt.args.n); got != tt.want { - t.Errorf("NumberToString() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestSimpleSortR(t *testing.T) { - type xy struct { - x int - y int - } - type args[T any] struct { - arr []T - fn func(i, j T) bool - } - type testCase[T any] struct { - name string - args args[T] - wantR []T - } - tests := []testCase[xy]{ - { - name: "t1", - args: args[xy]{ - arr: []xy{ - {1, 2}, - {3, 4}, - {1, 3}, - {2, 1}, - {1, 6}, - }, - fn: func(i, j xy) bool { - if i.x < j.x { - return true - } - if i.x == j.x && i.y > i.y { - return true - } - return false - }, - }, - wantR: []xy{ - {1, 2}, - {1, 3}, - {1, 6}, - {2, 1}, - {3, 4}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if gotR := SimpleSortR[xy](tt.args.arr, tt.args.fn); !reflect.DeepEqual(gotR, tt.wantR) { - t.Errorf("SimpleSortR() = %v, want %v", gotR, tt.wantR) - } - }) - } -} diff --git a/helper/html.go b/helper/html/html.go similarity index 94% rename from helper/html.go rename to helper/html/html.go index f729dc4..a95ad83 100644 --- a/helper/html.go +++ b/helper/html/html.go @@ -1,8 +1,9 @@ -package helper +package html import ( "fmt" "github.com/dlclark/regexp2" + "github.com/fthvgb1/wp-go/helper/slice" "regexp" "strings" ) @@ -119,7 +120,7 @@ func StripTagsX(str, allowable string) string { var tagx = regexp.MustCompile(`()`) var selfCloseTags = map[string]string{"area": "", "base": "", "basefont": "", "br": "", "col": "", "command": "", "embed": "", "frame": "", "hr": "", "img": "", "input": "", "isindex": "", "link": "", "meta": "", "param": "", "source": "", "track": "", "wbr": ""} -func CloseHtmlTag(str string) string { +func CloseTag(str string) string { tags := tag.FindAllString(str, -1) if len(tags) < 1 { return str @@ -135,13 +136,13 @@ func CloseHtmlTag(str string) string { } tagss = append(tagss, ss) } - r := SliceMap(SliceReverse(ClearClosedTag(tagss)), func(s string) string { + r := slice.Map(slice.Reverse(UnClosedTag(tagss)), func(s string) string { return fmt.Sprintf("", strings.Trim(s, "<>")) }) return strings.Join(r, "") } -func ClearClosedTag(s []string) []string { +func UnClosedTag(s []string) []string { i := 0 for { if len(s[i:]) < 2 { diff --git a/helper/html_test.go b/helper/html/html_test.go similarity index 94% rename from helper/html_test.go rename to helper/html/html_test.go index f812053..8a3a192 100644 --- a/helper/html_test.go +++ b/helper/html/html_test.go @@ -1,4 +1,4 @@ -package helper +package html import ( "reflect" @@ -183,8 +183,8 @@ func TestCloseHtmlTag(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := CloseHtmlTag(tt.args.str); !reflect.DeepEqual(got, tt.want) { - t.Errorf("CloseHtmlTag() = %v, want %v", got, tt.want) + if got := CloseTag(tt.args.str); !reflect.DeepEqual(got, tt.want) { + t.Errorf("CloseTag() = %v, want %v", got, tt.want) } }) } @@ -222,8 +222,8 @@ func Test_clearTag(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := ClearClosedTag(tt.args.s); !reflect.DeepEqual(got, tt.want) { - t.Errorf("ClearClosedTag() = %v, want %v", got, tt.want) + if got := UnClosedTag(tt.args.s); !reflect.DeepEqual(got, tt.want) { + t.Errorf("UnClosedTag() = %v, want %v", got, tt.want) } }) } diff --git a/helper/function.go b/helper/maps/function.go similarity index 79% rename from helper/function.go rename to helper/maps/function.go index c44c397..dd492c8 100644 --- a/helper/function.go +++ b/helper/maps/function.go @@ -1,4 +1,4 @@ -package helper +package maps import "strings" @@ -25,14 +25,14 @@ func GetStrMapAnyVal[T any](key string, v map[string]any) (r T, o bool) { return } -func GetStrMapAnyValToAny(key string, v map[string]any) (r any, o bool) { +func GetStrMapAnyValWithAny(key string, v map[string]any) (r any, o bool) { k := strings.Split(key, ".") if len(k) > 1 { val, ok := v[k[0]] if ok { vx, ok := val.(map[string]any) if ok { - r, o = GetStrMapAnyValToAny(strings.Join(k[1:], "."), vx) + r, o = GetStrMapAnyValWithAny(strings.Join(k[1:], "."), vx) } } } else { diff --git a/helper/function_test.go b/helper/maps/function_test.go similarity index 88% rename from helper/function_test.go rename to helper/maps/function_test.go index b1576a4..0256a60 100644 --- a/helper/function_test.go +++ b/helper/maps/function_test.go @@ -1,4 +1,4 @@ -package helper +package maps import ( "reflect" @@ -65,7 +65,7 @@ func TestGetStrMapAnyVal(t *testing.T) { } } -func TestGetStrMapAnyValToAny(t *testing.T) { +func TestGetStrMapAnyValWithAny(t *testing.T) { type args struct { key string v map[string]any @@ -113,12 +113,12 @@ func TestGetStrMapAnyValToAny(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - gotR, gotO := GetStrMapAnyValToAny(tt.args.key, tt.args.v) + gotR, gotO := GetStrMapAnyValWithAny(tt.args.key, tt.args.v) if !reflect.DeepEqual(gotR, tt.wantR) { - t.Errorf("GetStrMapAnyValToAny() gotR = %v, want %v", gotR, tt.wantR) + t.Errorf("GetStrMapAnyValWithAny() gotR = %v, want %v", gotR, tt.wantR) } if gotO != tt.wantO { - t.Errorf("GetStrMapAnyValToAny() gotO = %v, want %v", gotO, tt.wantO) + t.Errorf("GetStrMapAnyValWithAny() gotO = %v, want %v", gotO, tt.wantO) } }) } diff --git a/helper/map.go b/helper/maps/map.go similarity index 71% rename from helper/map.go rename to helper/maps/map.go index 9f64c56..9ec3ae2 100644 --- a/helper/map.go +++ b/helper/maps/map.go @@ -1,4 +1,4 @@ -package helper +package maps import "encoding/json" @@ -21,7 +21,7 @@ func StructToAnyMap[K comparable, T any](s T) (r map[K]any, err error) { return } -func MapToSlice[T any, K comparable, V any](m map[K]V, fn func(K, V) (T, bool)) (r []T) { +func FilterToSlice[T any, K comparable, V any](m map[K]V, fn func(K, V) (T, bool)) (r []T) { for k, v := range m { vv, ok := fn(k, v) if ok { @@ -31,15 +31,15 @@ func MapToSlice[T any, K comparable, V any](m map[K]V, fn func(K, V) (T, bool)) return } -// MapAnyAnyToStrAny map[any]any => map[string]any 方便json转换 -func MapAnyAnyToStrAny(m map[any]any) (r map[string]any) { +// AnyAnyToStrAny map[any]any => map[string]any 方便json转换 +func AnyAnyToStrAny(m map[any]any) (r map[string]any) { r = make(map[string]any) for k, v := range m { kk, ok := k.(string) if ok { vv, ok := v.(map[any]any) if ok { - r[kk] = MapAnyAnyToStrAny(vv) + r[kk] = AnyAnyToStrAny(vv) } else { r[kk] = v } diff --git a/helper/map_test.go b/helper/maps/map_test.go similarity index 89% rename from helper/map_test.go rename to helper/maps/map_test.go index 4084cc7..c90ac1a 100644 --- a/helper/map_test.go +++ b/helper/maps/map_test.go @@ -1,4 +1,4 @@ -package helper +package maps import ( "reflect" @@ -118,7 +118,15 @@ func TestStructToAnyMap(t *testing.T) { t.Errorf("StructToAnyMap() error = %v, wantErr %v", err, tt.wantErr) return } - if !reflect.DeepEqual(gotR, tt.wantR) { + gr, err := StrAnyMapToStruct[Me](gotR) + if err != nil { + panic(err) + } + wr, err := StrAnyMapToStruct[Me](tt.wantR) + if err != nil { + panic(err) + } + if !reflect.DeepEqual(gr, wr) { t.Errorf("StructToAnyMap() gotR = %v, want %v", gotR, tt.wantR) } }) @@ -157,8 +165,8 @@ func TestMapToSlice(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if gotR := MapToSlice(tt.args.m, tt.args.fn); !reflect.DeepEqual(gotR, tt.wantR) { - t.Errorf("MapToSlice() = %v, want %v", gotR, tt.wantR) + if gotR := FilterToSlice(tt.args.m, tt.args.fn); !reflect.DeepEqual(gotR, tt.wantR) { + t.Errorf("FilterToSlice() = %v, want %v", gotR, tt.wantR) } }) } diff --git a/helper/number/number.go b/helper/number/number.go new file mode 100644 index 0000000..c386a2f --- /dev/null +++ b/helper/number/number.go @@ -0,0 +1,67 @@ +package number + +import ( + "fmt" + "math/rand" +) + +type IntNumber interface { + ~int | ~int64 | ~int32 | ~int8 | ~int16 | + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 +} + +func Range[T IntNumber](start, end, step T) []T { + if step == 0 { + panic("step can't be 0") + } + l := int((end-start+1)/step + 1) + if l < 0 { + l = 0 - l + } + r := make([]T, 0, l) + for i := start; ; { + r = append(r, i) + i = i + step + if (step > 0 && i > end) || (step < 0 && i < end) { + break + } + } + return r +} + +func Rand[T IntNumber](start, end T) T { + end++ + return T(rand.Int63n(int64(end-start))) + start +} + +func Min[T IntNumber | ~float64 | ~float32](a ...T) T { + min := a[0] + for _, t := range a { + if min > t { + min = t + } + } + return min +} + +func Max[T IntNumber | ~float64 | ~float32](a ...T) T { + max := a[0] + for _, t := range a { + if max < t { + max = t + } + } + return max +} + +func Sum[T IntNumber | ~float64 | ~float32](a ...T) T { + s := T(0) + for _, t := range a { + s += t + } + return s +} + +func ToString[T IntNumber | ~float64 | ~float32](n T) string { + return fmt.Sprintf("%v", n) +} diff --git a/helper/number/number_test.go b/helper/number/number_test.go new file mode 100644 index 0000000..5c44cda --- /dev/null +++ b/helper/number/number_test.go @@ -0,0 +1,193 @@ +package number + +import ( + "reflect" + "testing" +) + +func TestRange(t *testing.T) { + type args struct { + start int + end int + step int + } + tests := []struct { + name string + args args + want []int + }{ + { + name: "t1", + args: args{ + start: 1, + end: 5, + step: 1, + }, + want: []int{1, 2, 3, 4, 5}, + }, + { + name: "t2", + args: args{ + start: 0, + end: 5, + step: 2, + }, + want: []int{0, 2, 4}, + }, + { + name: "t3", + args: args{ + start: 1, + end: 11, + step: 3, + }, + want: []int{1, 4, 7, 10}, + }, + { + name: "t4", + args: args{ + start: 0, + end: -5, + step: -1, + }, + want: []int{0, -1, -2, -3, -4, -5}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := Range(tt.args.start, tt.args.end, tt.args.step); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Range() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestMin(t *testing.T) { + type args struct { + a []int + } + tests := []struct { + name string + args args + want int + }{ + { + name: "t1", + args: args{a: []int{1, 2, 3}}, + want: 1, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := Min(tt.args.a...); got != tt.want { + t.Errorf("Min() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestMax(t *testing.T) { + type args struct { + a []int + } + tests := []struct { + name string + args args + want int + }{ + { + name: "t1", + args: args{a: []int{1, 2, 3}}, + want: 3, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := Max(tt.args.a...); got != tt.want { + t.Errorf("Max() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestSum(t *testing.T) { + type args struct { + a []int + } + tests := []struct { + name string + args args + want int + }{ + { + name: "t1", + args: args{a: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}, + want: 55, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := Sum(tt.args.a...); got != tt.want { + t.Errorf("Sum() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestToString(t *testing.T) { + type args struct { + n float64 + } + tests := []struct { + name string + args args + want string + }{ + { + name: "t1", + args: args{n: 111}, + want: "111", + }, + { + name: "t2", + args: args{n: 111.222222}, + want: "111.222222", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ToString(tt.args.n); got != tt.want { + t.Errorf("NumberToString() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestRand(t *testing.T) { + type args struct { + start int + end int + } + tests := []struct { + name string + args args + }{ + { + name: "t1", + args: args{ + start: 1, + end: 2, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + for i := 0; i < 100; i++ { + got := Rand(tt.args.start, tt.args.end) + if got > tt.args.end || got < tt.args.start { + t.Errorf("RandNum() = %v, range error", got) + } + } + }) + } +} diff --git a/helper/slice.go b/helper/slice/slice.go similarity index 64% rename from helper/slice.go rename to helper/slice/slice.go index 159a0c3..cc0f8ef 100644 --- a/helper/slice.go +++ b/helper/slice/slice.go @@ -1,6 +1,6 @@ -package helper +package slice -func SliceMap[T, R any](arr []T, fn func(T) R) []R { +func Map[T, R any](arr []T, fn func(T) R) []R { r := make([]R, 0, len(arr)) for _, t := range arr { r = append(r, fn(t)) @@ -8,7 +8,7 @@ func SliceMap[T, R any](arr []T, fn func(T) R) []R { return r } -func SliceFilterAndMap[N any, T any](arr []T, fn func(T) (N, bool)) (r []N) { +func FilterAndMap[N any, T any](arr []T, fn func(T) (N, bool)) (r []N) { for _, t := range arr { x, ok := fn(t) if ok { @@ -18,7 +18,7 @@ func SliceFilterAndMap[N any, T any](arr []T, fn func(T) (N, bool)) (r []N) { return } -func SliceFilter[T any](arr []T, fn func(T) bool) []T { +func Filter[T any](arr []T, fn func(T) bool) []T { var r []T for _, t := range arr { if fn(t) { @@ -28,14 +28,14 @@ func SliceFilter[T any](arr []T, fn func(T) bool) []T { return r } -func SliceReduce[R, T any](arr []T, fn func(T, R) R, r R) R { +func Reduce[R, T any](arr []T, fn func(T, R) R, r R) R { for _, t := range arr { r = fn(t, r) } return r } -func SliceReverse[T any](arr []T) []T { +func Reverse[T any](arr []T) []T { var r = make([]T, 0, len(arr)) for i := len(arr); i > 0; i-- { r = append(r, arr[i-1]) @@ -43,7 +43,7 @@ func SliceReverse[T any](arr []T) []T { return r } -func SliceSelfReverse[T any](arr []T) []T { +func ReverseSelf[T any](arr []T) []T { l := len(arr) half := l / 2 for i := 0; i < half; i++ { @@ -52,13 +52,13 @@ func SliceSelfReverse[T any](arr []T) []T { return arr } -func SimpleSliceToMap[K comparable, V any](arr []V, fn func(V) K) map[K]V { - return SliceToMap(arr, func(v V) (K, V) { +func SimpleToMap[K comparable, V any](arr []V, fn func(V) K) map[K]V { + return ToMap(arr, func(v V) (K, V) { return fn(v), v }, true) } -func SliceToMap[K comparable, V, T any](arr []V, fn func(V) (K, T), isCoverPrev bool) map[K]T { +func ToMap[K comparable, V, T any](arr []V, fn func(V) (K, T), isCoverPrev bool) map[K]T { m := make(map[K]T) for _, v := range arr { k, r := fn(v) @@ -72,26 +72,7 @@ func SliceToMap[K comparable, V, T any](arr []V, fn func(V) (K, T), isCoverPrev return m } -func RangeSlice[T IntNumber](start, end, step T) []T { - if step == 0 { - panic("step can't be 0") - } - l := int((end-start+1)/step + 1) - if l < 0 { - l = 0 - l - } - r := make([]T, 0, l) - for i := start; ; { - r = append(r, i) - i = i + step - if (step > 0 && i > end) || (step < 0 && i < end) { - break - } - } - return r -} - -func SlicePagination[T any](arr []T, page, pageSize int) []T { +func Pagination[T any](arr []T, page, pageSize int) []T { start := (page - 1) * pageSize l := len(arr) if start > l { @@ -104,7 +85,7 @@ func SlicePagination[T any](arr []T, page, pageSize int) []T { return arr[start:end] } -func SliceChunk[T any](arr []T, size int) [][]T { +func Chunk[T any](arr []T, size int) [][]T { var r [][]T i := 0 for { @@ -153,3 +134,13 @@ func Comb[T any](arr []T, m int) (r [][]T) { } return r } + + +func IsContained[T comparable](a T, arr []T) bool { + for _, v := range arr { + if a == v { + return true + } + } + return false +} diff --git a/helper/slice_test.go b/helper/slice/slice_test.go similarity index 61% rename from helper/slice_test.go rename to helper/slice/slice_test.go index 81912c6..46f1e0e 100644 --- a/helper/slice_test.go +++ b/helper/slice/slice_test.go @@ -1,12 +1,13 @@ -package helper +package slice import ( + "github.com/fthvgb1/wp-go/helper/number" "reflect" "testing" ) -func TestSlicePagination(t *testing.T) { - arr := RangeSlice[int](1, 10, 1) +func TestPagination(t *testing.T) { + arr := number.Range[int](1, 10, 1) type args struct { arr []int page int @@ -24,7 +25,7 @@ func TestSlicePagination(t *testing.T) { page: 1, pageSize: 2, }, - want: RangeSlice[int](1, 2, 1), + want: number.Range[int](1, 2, 1), }, { name: "t2", args: args{ @@ -32,7 +33,7 @@ func TestSlicePagination(t *testing.T) { page: 2, pageSize: 2, }, - want: RangeSlice[int](3, 4, 1), + want: number.Range[int](3, 4, 1), }, { name: "t3", args: args{ @@ -53,14 +54,14 @@ func TestSlicePagination(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := SlicePagination(tt.args.arr, tt.args.page, tt.args.pageSize); !reflect.DeepEqual(got, tt.want) { - t.Errorf("SlicePagination() = %v, want %v", got, tt.want) + if got := Pagination(tt.args.arr, tt.args.page, tt.args.pageSize); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Pagination() = %v, want %v", got, tt.want) } }) } } -func TestSliceReduce(t *testing.T) { +func TestReduce(t *testing.T) { type args struct { arr []int fn func(int, int) int @@ -73,7 +74,7 @@ func TestSliceReduce(t *testing.T) { }{ { name: "t1", - args: args{arr: RangeSlice(1, 10, 1), fn: func(i int, i2 int) int { + args: args{arr: number.Range(1, 10, 1), fn: func(i int, i2 int) int { return i + i2 }}, want: 55, @@ -81,14 +82,14 @@ func TestSliceReduce(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := SliceReduce(tt.args.arr, tt.args.fn, tt.args.r); !reflect.DeepEqual(got, tt.want) { - t.Errorf("SliceReduce() = %v, want %v", got, tt.want) + if got := Reduce(tt.args.arr, tt.args.fn, tt.args.r); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Reduce() = %v, want %v", got, tt.want) } }) } } -func TestSliceFilter(t *testing.T) { +func TestFilter(t *testing.T) { type args struct { arr []int fn func(int) bool @@ -100,22 +101,22 @@ func TestSliceFilter(t *testing.T) { }{ { name: "t1", - args: args{arr: RangeSlice(1, 10, 1), fn: func(i int) bool { + args: args{arr: number.Range(1, 10, 1), fn: func(i int) bool { return i > 4 }}, - want: RangeSlice(5, 10, 1), + want: number.Range(5, 10, 1), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := SliceFilter(tt.args.arr, tt.args.fn); !reflect.DeepEqual(got, tt.want) { - t.Errorf("SliceFilter() = %v, want %v", got, tt.want) + if got := Filter(tt.args.arr, tt.args.fn); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Filter() = %v, want %v", got, tt.want) } }) } } -func TestSliceMap(t *testing.T) { +func TestMap(t *testing.T) { type args struct { arr []int8 fn func(int8) int @@ -128,24 +129,24 @@ func TestSliceMap(t *testing.T) { { name: "t1", args: args{ - arr: RangeSlice[int8](1, 10, 1), + arr: number.Range[int8](1, 10, 1), fn: func(i int8) int { return int(i) }, }, - want: RangeSlice(1, 10, 1), + want: number.Range(1, 10, 1), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := SliceMap(tt.args.arr, tt.args.fn); !reflect.DeepEqual(got, tt.want) { - t.Errorf("SliceMap() = %v, want %v", got, tt.want) + if got := Map(tt.args.arr, tt.args.fn); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Map() = %v, want %v", got, tt.want) } }) } } -func TestSliceReverse(t *testing.T) { +func TestReverse(t *testing.T) { type args struct { arr []int } @@ -156,71 +157,14 @@ func TestSliceReverse(t *testing.T) { }{ { name: "t1", - args: args{arr: RangeSlice(1, 10, 1)}, - want: RangeSlice(10, 1, -1), + args: args{arr: number.Range(1, 10, 1)}, + want: number.Range(10, 1, -1), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := SliceReverse(tt.args.arr); !reflect.DeepEqual(got, tt.want) { - t.Errorf("SliceReverse() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestRangeSlice(t *testing.T) { - type args struct { - start int - end int - step int - } - tests := []struct { - name string - args args - want []int - }{ - { - name: "t1", - args: args{ - start: 1, - end: 5, - step: 1, - }, - want: []int{1, 2, 3, 4, 5}, - }, - { - name: "t2", - args: args{ - start: 0, - end: 5, - step: 2, - }, - want: []int{0, 2, 4}, - }, - { - name: "t3", - args: args{ - start: 1, - end: 11, - step: 3, - }, - want: []int{1, 4, 7, 10}, - }, - { - name: "t4", - args: args{ - start: 0, - end: -5, - step: -1, - }, - want: []int{0, -1, -2, -3, -4, -5}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := RangeSlice(tt.args.start, tt.args.end, tt.args.step); !reflect.DeepEqual(got, tt.want) { - t.Errorf("RangeSlice() = %v, want %v", got, tt.want) + if got := Reverse(tt.args.arr); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Reverse() = %v, want %v", got, tt.want) } }) } @@ -240,20 +184,20 @@ func TestSlice(t *testing.T) { { name: "t1", args: args{ - arr: RangeSlice(1, 10, 1), + arr: number.Range(1, 10, 1), offset: 3, length: 2, }, - wantR: RangeSlice(4, 5, 1), + wantR: number.Range(4, 5, 1), }, { name: "t2", args: args{ - arr: RangeSlice(1, 10, 1), + arr: number.Range(1, 10, 1), offset: 3, length: 0, }, - wantR: RangeSlice(4, 10, 1), + wantR: number.Range(4, 10, 1), }, } for _, tt := range tests { @@ -278,7 +222,7 @@ func TestComb(t *testing.T) { { name: "t1", args: args{ - arr: RangeSlice(1, 5, 1), + arr: number.Range(1, 5, 1), m: 2, }, wantR: [][]int{ @@ -297,7 +241,7 @@ func TestComb(t *testing.T) { { name: "t2", args: args{ - arr: RangeSlice(1, 5, 1), + arr: number.Range(1, 5, 1), m: 3, }, wantR: [][]int{ @@ -316,7 +260,7 @@ func TestComb(t *testing.T) { { name: "t3", args: args{ - arr: RangeSlice(1, 5, 1), + arr: number.Range(1, 5, 1), m: 4, }, wantR: [][]int{ @@ -337,7 +281,7 @@ func TestComb(t *testing.T) { } } -func TestSliceChunk(t *testing.T) { +func TestChunk(t *testing.T) { type args struct { arr []int size int @@ -350,7 +294,7 @@ func TestSliceChunk(t *testing.T) { { name: "t1", args: args{ - arr: RangeSlice(1, 7, 1), + arr: number.Range(1, 7, 1), size: 2, }, want: [][]int{{1, 2}, {3, 4}, {5, 6}, {7}}, @@ -358,7 +302,7 @@ func TestSliceChunk(t *testing.T) { { name: "t2", args: args{ - arr: RangeSlice(1, 8, 1), + arr: number.Range(1, 8, 1), size: 2, }, want: [][]int{{1, 2}, {3, 4}, {5, 6}, {7, 8}}, @@ -366,8 +310,8 @@ func TestSliceChunk(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := SliceChunk(tt.args.arr, tt.args.size); !reflect.DeepEqual(got, tt.want) { - t.Errorf("SliceChunk() = %v, want %v", got, tt.want) + if got := Chunk(tt.args.arr, tt.args.size); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Chunk() = %v, want %v", got, tt.want) } }) } @@ -393,14 +337,14 @@ func TestSimpleSliceToMap(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := SimpleSliceToMap(tt.args.arr, tt.args.fn); !reflect.DeepEqual(got, tt.want) { - t.Errorf("SimpleSliceToMap() = %v, want %v", got, tt.want) + if got := SimpleToMap(tt.args.arr, tt.args.fn); !reflect.DeepEqual(got, tt.want) { + t.Errorf("SimpleToMap() = %v, want %v", got, tt.want) } }) } } -func TestSliceToMap(t *testing.T) { +func TestToMap(t *testing.T) { type ss struct { id int v string @@ -439,14 +383,14 @@ func TestSliceToMap(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := SliceToMap(tt.args.arr, tt.args.fn, tt.args.isCoverPrev); !reflect.DeepEqual(got, tt.want) { - t.Errorf("SliceToMap() = %v, want %v", got, tt.want) + if got := ToMap(tt.args.arr, tt.args.fn, tt.args.isCoverPrev); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ToMap() = %v, want %v", got, tt.want) } }) } } -func TestSliceSelfReverse(t *testing.T) { +func TestReverseSelf(t *testing.T) { type args struct { arr []int } @@ -458,27 +402,27 @@ func TestSliceSelfReverse(t *testing.T) { { name: "t1", args: args{ - arr: RangeSlice(1, 10, 1), + arr: number.Range(1, 10, 1), }, - want: RangeSlice(10, 1, -1), + want: number.Range(10, 1, -1), }, { name: "t2", args: args{ - arr: RangeSlice(1, 9, 1), + arr: number.Range(1, 9, 1), }, - want: RangeSlice(9, 1, -1), + want: number.Range(9, 1, -1), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := SliceSelfReverse(tt.args.arr); !reflect.DeepEqual(got, tt.want) { - t.Errorf("SliceSelfReverse() = %v, want %v", got, tt.want) + if got := ReverseSelf(tt.args.arr); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ReverseSelf() = %v, want %v", got, tt.want) } }) } } -func TestSliceFilterAndMap(t *testing.T) { +func TestFilterAndMap(t *testing.T) { type a struct { x int y string @@ -513,8 +457,8 @@ func TestSliceFilterAndMap(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if gotR := SliceFilterAndMap[string](tt.args.arr, tt.args.fn); !reflect.DeepEqual(gotR, tt.wantR) { - t.Errorf("SliceFilterAndMap() = %v, want %v", gotR, tt.wantR) + if gotR := FilterAndMap[string](tt.args.arr, tt.args.fn); !reflect.DeepEqual(gotR, tt.wantR) { + t.Errorf("FilterAndMap() = %v, want %v", gotR, tt.wantR) } }) } diff --git a/helper/slice/sort.go b/helper/slice/sort.go new file mode 100644 index 0000000..359b4dc --- /dev/null +++ b/helper/slice/sort.go @@ -0,0 +1,42 @@ +package slice + +import "sort" + +type anyArr[T any] struct { + data []T + fn func(i, j T) bool +} + +func (r anyArr[T]) Len() int { + return len(r.data) +} + +func (r anyArr[T]) Swap(i, j int) { + r.data[i], r.data[j] = r.data[j], r.data[i] +} + +func (r anyArr[T]) Less(i, j int) bool { + return r.fn(r.data[i], r.data[j]) +} + +func SortSelf[T any](arr []T, fn func(i, j T) bool) { + slice := anyArr[T]{ + data: arr, + fn: fn, + } + sort.Sort(slice) + return +} + +func Sort[T any](arr []T, fn func(i, j T) bool) (r []T) { + r = make([]T, 0, len(arr)) + for _, t := range arr { + r = append(r, t) + } + slice := anyArr[T]{ + data: r, + fn: fn, + } + sort.Sort(slice) + return +} diff --git a/helper/slice/sort_test.go b/helper/slice/sort_test.go new file mode 100644 index 0000000..6cf7e96 --- /dev/null +++ b/helper/slice/sort_test.go @@ -0,0 +1,112 @@ +package slice + +import ( + "reflect" + "testing" +) + +func TestSortSelf(t *testing.T) { + type xy struct { + x int + y int + } + + type args struct { + arr []xy + fn func(i, j xy) bool + } + tests := []struct { + name string + args args + wantR []xy + }{ + { + name: "t1", + args: args{ + arr: []xy{ + {1, 2}, + {3, 4}, + {1, 3}, + {2, 1}, + {1, 6}, + }, + fn: func(i, j xy) bool { + if i.x < j.x { + return true + } + if i.x == j.x && i.y > i.y { + return true + } + return false + }, + }, + wantR: []xy{ + {1, 2}, + {1, 3}, + {1, 6}, + {2, 1}, + {3, 4}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if SortSelf(tt.args.arr, tt.args.fn); !reflect.DeepEqual(tt.args.arr, tt.wantR) { + t.Errorf("SimpleSort() = %v, want %v", tt.args.arr, tt.wantR) + } + }) + } +} + +func TestSort(t *testing.T) { + type xy struct { + x int + y int + } + type args[T any] struct { + arr []T + fn func(i, j T) bool + } + type testCase[T any] struct { + name string + args args[T] + wantR []T + } + tests := []testCase[xy]{ + { + name: "t1", + args: args[xy]{ + arr: []xy{ + {1, 2}, + {3, 4}, + {1, 3}, + {2, 1}, + {1, 6}, + }, + fn: func(i, j xy) bool { + if i.x < j.x { + return true + } + if i.x == j.x && i.y > i.y { + return true + } + return false + }, + }, + wantR: []xy{ + {1, 2}, + {1, 3}, + {1, 6}, + {2, 1}, + {3, 4}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if gotR := Sort[xy](tt.args.arr, tt.args.fn); !reflect.DeepEqual(gotR, tt.wantR) { + t.Errorf("SimpleSortR() = %v, want %v", gotR, tt.wantR) + } + }) + } +} \ No newline at end of file diff --git a/helper/strings.go b/helper/strings/strings.go similarity index 78% rename from helper/strings.go rename to helper/strings/strings.go index 8deff9f..c1af80b 100644 --- a/helper/strings.go +++ b/helper/strings/strings.go @@ -1,4 +1,4 @@ -package helper +package strings import ( "crypto/md5" @@ -7,7 +7,7 @@ import ( "strings" ) -func StrJoin(s ...string) (str string) { +func Join(s ...string) (str string) { if len(s) == 1 { return s[0] } else if len(s) > 1 { @@ -20,7 +20,7 @@ func StrJoin(s ...string) (str string) { return } -func StringMd5(str string) string { +func Md5(str string) string { h := md5.New() _, err := io.WriteString(h, str) if err != nil { diff --git a/helper/strings_test.go b/helper/strings/strings_test.go similarity index 69% rename from helper/strings_test.go rename to helper/strings/strings_test.go index ff97690..a04457c 100644 --- a/helper/strings_test.go +++ b/helper/strings/strings_test.go @@ -1,4 +1,4 @@ -package helper +package strings import "testing" @@ -15,8 +15,8 @@ func TestStrJoin(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if gotStr := StrJoin(tt.args.s...); gotStr != tt.wantStr { - t.Errorf("StrJoin() = %v, want %v", gotStr, tt.wantStr) + if gotStr := Join(tt.args.s...); gotStr != tt.wantStr { + t.Errorf("Join() = %v, want %v", gotStr, tt.wantStr) } }) } diff --git a/internal/actions/comment.go b/internal/actions/comment.go index 27ce120..4b01a16 100644 --- a/internal/actions/comment.go +++ b/internal/actions/comment.go @@ -4,7 +4,7 @@ import ( "bytes" "errors" "fmt" - "github.com/fthvgb1/wp-go/helper" + "github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/internal/mail" "github.com/fthvgb1/wp-go/internal/pkg/cache" "github.com/fthvgb1/wp-go/internal/pkg/config" @@ -81,7 +81,7 @@ func PostComment(c *gin.Context) { return } newReq.Host = home.Host - newReq.Header.Set("Cookie", strings.Join(helper.SliceMap(c.Request.Cookies(), func(t *http.Cookie) string { + newReq.Header.Set("Cookie", strings.Join(slice.Map(c.Request.Cookies(), func(t *http.Cookie) string { return fmt.Sprintf("%s=%s", t.Name, t.Value) }), "; ")) ress, er := http.DefaultClient.Do(newReq) diff --git a/internal/actions/detail.go b/internal/actions/detail.go index 3af8404..5d29f48 100644 --- a/internal/actions/detail.go +++ b/internal/actions/detail.go @@ -2,7 +2,7 @@ package actions import ( "fmt" - "github.com/fthvgb1/wp-go/helper" + str "github.com/fthvgb1/wp-go/helper/strings" "github.com/fthvgb1/wp-go/internal/pkg/cache" "github.com/fthvgb1/wp-go/internal/pkg/logs" "github.com/fthvgb1/wp-go/internal/pkg/models" @@ -49,7 +49,7 @@ func Detail(c *gin.Context) { if isApproveComment == true { return } - c.HTML(status, helper.StrJoin(theme.GetTemplateName(), "/posts/detail.gohtml"), h) + c.HTML(status, str.Join(theme.GetTemplateName(), "/posts/detail.gohtml"), h) }() id := c.Param("id") Id := 0 diff --git a/internal/actions/feed.go b/internal/actions/feed.go index 7b6f593..e2e74fd 100644 --- a/internal/actions/feed.go +++ b/internal/actions/feed.go @@ -1,7 +1,7 @@ package actions import ( - "github.com/fthvgb1/wp-go/helper" + str "github.com/fthvgb1/wp-go/helper/strings" "github.com/fthvgb1/wp-go/internal/pkg/cache" "github.com/gin-gonic/gin" "net/http" @@ -11,7 +11,7 @@ import ( var tmp = "Mon, 02 Jan 2006 15:04:05 GMT" func isCacheExpired(c *gin.Context, lastTime time.Time) bool { - eTag := helper.StringMd5(lastTime.Format(tmp)) + eTag := str.Md5(lastTime.Format(tmp)) since := c.Request.Header.Get("If-Modified-Since") cTag := c.Request.Header.Get("If-None-Match") if since != "" && cTag != "" { @@ -41,7 +41,7 @@ func Feed(c *gin.Context) { func setFeed(s string, c *gin.Context, t time.Time) { lastTimeGMT := t.Format(tmp) - eTag := helper.StringMd5(lastTimeGMT) + eTag := str.Md5(lastTimeGMT) c.Header("Content-Type", "application/rss+xml; charset=UTF-8") c.Header("Last-Modified", lastTimeGMT) c.Header("ETag", eTag) diff --git a/internal/actions/index.go b/internal/actions/index.go index 60e570c..aa8b41f 100644 --- a/internal/actions/index.go +++ b/internal/actions/index.go @@ -2,7 +2,8 @@ package actions import ( "fmt" - "github.com/fthvgb1/wp-go/helper" + "github.com/fthvgb1/wp-go/helper/slice" + str "github.com/fthvgb1/wp-go/helper/strings" "github.com/fthvgb1/wp-go/internal/pkg/cache" dao "github.com/fthvgb1/wp-go/internal/pkg/dao" "github.com/fthvgb1/wp-go/internal/pkg/logs" @@ -83,7 +84,7 @@ func (h *indexHandle) getSearchKey() string { func (h *indexHandle) parseParams() (err error) { h.order = h.c.Query("order") - if !helper.IsContainInArr(h.order, []string{"asc", "desc"}) { + if !slice.IsContained(h.order, []string{"asc", "desc"}) { h.order = "asc" } year := h.c.Param("year") @@ -142,7 +143,7 @@ func (h *indexHandle) parseParams() (err error) { } s := h.c.Query("s") if s != "" && strings.Replace(s, " ", "", -1) != "" { - q := helper.StrJoin("%", s, "%") + q := str.Join("%", s, "%") h.where = append(h.where, []string{ "and", "post_title", "like", q, "", "or", "post_content", "like", q, "", @@ -150,7 +151,7 @@ func (h *indexHandle) parseParams() (err error) { }, []string{"post_password", ""}) h.postType = append(h.postType, "page", "attachment") h.header = fmt.Sprintf("%s的搜索结果", s) - h.setTitleLR(helper.StrJoin(`"`, s, `"`, "的搜索结果"), wpconfig.Options.Value("blogname")) + h.setTitleLR(str.Join(`"`, s, `"`, "的搜索结果"), wpconfig.Options.Value("blogname")) h.search = s h.scene = plugins.Search } diff --git a/internal/actions/login.go b/internal/actions/login.go index 85a7aac..f076c1c 100644 --- a/internal/actions/login.go +++ b/internal/actions/login.go @@ -2,7 +2,7 @@ package actions import ( "fmt" - "github.com/fthvgb1/wp-go/helper" + str "github.com/fthvgb1/wp-go/helper/strings" "github.com/fthvgb1/wp-go/internal/phpass" "github.com/fthvgb1/wp-go/internal/wpconfig" "github.com/gin-contrib/sessions" @@ -33,7 +33,7 @@ func Login(c *gin.Context) { c.Error(err) return } - cohash := fmt.Sprintf("wp-postpass_%s", helper.StringMd5(wpconfig.Options.Value("siteurl"))) + cohash := fmt.Sprintf("wp-postpass_%s", str.Md5(wpconfig.Options.Value("siteurl"))) c.SetCookie(cohash, pass, 24*3600, "/", "", false, false) c.Redirect(http.StatusFound, ref) diff --git a/internal/middleware/flowLimit.go b/internal/middleware/flowLimit.go index 82aeaee..ad62407 100644 --- a/internal/middleware/flowLimit.go +++ b/internal/middleware/flowLimit.go @@ -1,7 +1,7 @@ package middleware import ( - "github.com/fthvgb1/wp-go/helper" + "github.com/fthvgb1/wp-go/helper/number" "github.com/fthvgb1/wp-go/safety" "github.com/gin-gonic/gin" "net/http" @@ -35,7 +35,7 @@ func FlowLimit(maxRequestSleepNum, maxRequestNum int64, sleepTime []time.Duratio n := atomic.LoadInt64(&flow) if n >= atomic.LoadInt64(&maxRequestSleepNum) && n <= atomic.LoadInt64(&maxRequestNum) { ss := s.Load() - t := helper.RandNum(ss[0], ss[1]) + t := number.Rand(ss[0], ss[1]) time.Sleep(t) } else if n > atomic.LoadInt64(&maxRequestNum) { c.String(http.StatusForbidden, "请求太多了,服务器君表示压力山大==!, 请稍后访问") diff --git a/internal/middleware/staticFileCache.go b/internal/middleware/staticFileCache.go index 3e13e23..9d3bdc2 100644 --- a/internal/middleware/staticFileCache.go +++ b/internal/middleware/staticFileCache.go @@ -1,14 +1,14 @@ package middleware import ( - "github.com/fthvgb1/wp-go/helper" + "github.com/fthvgb1/wp-go/helper/slice" "github.com/gin-gonic/gin" "strings" ) func SetStaticFileCache(c *gin.Context) { f := strings.Split(strings.TrimLeft(c.FullPath(), "/"), "/") - if len(f) > 0 && helper.IsContainInArr(f[0], []string{"wp-includes", "wp-content", "favicon.ico"}) { + if len(f) > 0 && slice.IsContained(f[0], []string{"wp-includes", "wp-content", "favicon.ico"}) { c.Header("Cache-Control", "private, max-age=86400") } c.Next() diff --git a/internal/phpass/phpass.go b/internal/phpass/phpass.go index 3ba6af8..4b412cd 100644 --- a/internal/phpass/phpass.go +++ b/internal/phpass/phpass.go @@ -3,7 +3,7 @@ package phpass import ( "crypto/md5" "fmt" - "github.com/fthvgb1/wp-go/helper" + str "github.com/fthvgb1/wp-go/helper/strings" "golang.org/x/crypto/bcrypt" "io" "os" @@ -49,7 +49,7 @@ func (p *PasswordHash) getRandomBytes(count int) (r string, err error) { if len(buf) < count { r = "" for i := 0; i < count; i = i + 16 { - p.randomState = helper.StringMd5(fmt.Sprintf("%d%s", time.Now().UnixMilli(), p.randomState)) + p.randomState = str.Md5(fmt.Sprintf("%d%s", time.Now().UnixMilli(), p.randomState)) n, err := md5Raw(p.randomState) if err != nil { diff --git a/internal/pkg/cache/feed.go b/internal/pkg/cache/feed.go index 0f36212..1fa195b 100644 --- a/internal/pkg/cache/feed.go +++ b/internal/pkg/cache/feed.go @@ -3,7 +3,7 @@ package cache import ( "fmt" "github.com/fthvgb1/wp-go/cache" - "github.com/fthvgb1/wp-go/helper" + "github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/internal/pkg/logs" "github.com/fthvgb1/wp-go/internal/pkg/models" "github.com/fthvgb1/wp-go/internal/plugins" @@ -47,7 +47,7 @@ func PostFeedCache() *cache.MapCache[string, string] { func feed(arg ...any) (xml []string, err error) { c := arg[0].(*gin.Context) r := RecentPosts(c, 10) - ids := helper.SliceMap(r, func(t models.Posts) uint64 { + ids := slice.Map(r, func(t models.Posts) uint64 { return t.Id }) posts, err := GetPostsByIds(c, ids) @@ -56,7 +56,7 @@ func feed(arg ...any) (xml []string, err error) { } rs := templateRss rs.LastBuildDate = time.Now().Format(timeFormat) - rs.Items = helper.SliceMap(posts, func(t models.Posts) rss2.Item { + rs.Items = slice.Map(posts, func(t models.Posts) rss2.Item { desc := "无法提供摘要。这是一篇受保护的文章。" plugins.PasswordProjectTitle(&t) if t.PostPassword != "" { @@ -138,7 +138,7 @@ func postFeed(arg ...any) (x string, err error) { } } } else { - rs.Items = helper.SliceMap(comments, func(t models.Comments) rss2.Item { + rs.Items = slice.Map(comments, func(t models.Comments) rss2.Item { return rss2.Item{ Title: fmt.Sprintf("评价者:%s", t.CommentAuthor), Link: fmt.Sprintf("%s/p/%d#comment-%d", wpconfig.Options.Value("siteurl"), post.Id, t.CommentId), @@ -161,13 +161,13 @@ func commentsFeed(args ...any) (r []string, err error) { rs.Title = fmt.Sprintf("\"%s\"的评论", wpconfig.Options.Value("blogname")) rs.LastBuildDate = time.Now().Format(timeFormat) rs.AtomLink = fmt.Sprintf("%s/comments/feed", wpconfig.Options.Value("siteurl")) - com, err := GetCommentByIds(c, helper.SliceMap(commens, func(t models.Comments) uint64 { + com, err := GetCommentByIds(c, slice.Map(commens, func(t models.Comments) uint64 { return t.CommentId })) if nil != err { return []string{}, err } - rs.Items = helper.SliceMap(com, func(t models.Comments) rss2.Item { + rs.Items = slice.Map(com, func(t models.Comments) rss2.Item { post, _ := GetPostById(c, t.CommentPostId) plugins.PasswordProjectTitle(&post) desc := "评论受保护:要查看请输入密码。" diff --git a/internal/pkg/cache/posts.go b/internal/pkg/cache/posts.go index e4b2c8c..b12581f 100644 --- a/internal/pkg/cache/posts.go +++ b/internal/pkg/cache/posts.go @@ -3,7 +3,7 @@ package cache import ( "context" "fmt" - "github.com/fthvgb1/wp-go/helper" + "github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/internal/pkg/logs" "github.com/fthvgb1/wp-go/internal/pkg/models" "github.com/gin-gonic/gin" @@ -67,10 +67,10 @@ func GetMonthPostIds(ctx context.Context, year, month string, page, limit int, o return } if order == "desc" { - res = helper.SliceReverse(res) + res = slice.Reverse(res) } total = len(res) - rr := helper.SlicePagination(res, page, limit) + rr := slice.Pagination(res, page, limit) r, err = GetPostsByIds(ctx, rr) return } diff --git a/internal/pkg/dao/comments.go b/internal/pkg/dao/comments.go index 6d289e0..6b65fa8 100644 --- a/internal/pkg/dao/comments.go +++ b/internal/pkg/dao/comments.go @@ -3,6 +3,7 @@ package common import ( "context" "github.com/fthvgb1/wp-go/helper" + "github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/internal/pkg/models" "github.com/fthvgb1/wp-go/model" "strconv" @@ -36,7 +37,7 @@ func PostComments(args ...any) ([]uint64, error) { if err != nil { return nil, err } - return helper.SliceMap(r, func(t models.Comments) uint64 { + return slice.Map(r, func(t models.Comments) uint64 { return t.CommentId }), err } @@ -47,11 +48,11 @@ func GetCommentByIds(args ...any) (map[uint64]models.Comments, error) { m := make(map[uint64]models.Comments) r, err := model.SimpleFind[models.Comments](ctx, model.SqlBuilder{ {"comment_ID", "in", ""}, {"comment_approved", "1"}, - }, "*", helper.SliceMap(ids, helper.ToAny[uint64])) + }, "*", slice.Map(ids, helper.ToAny[uint64])) if err != nil { return m, err } - return helper.SimpleSliceToMap(r, func(t models.Comments) uint64 { + return slice.SimpleToMap(r, func(t models.Comments) uint64 { return t.CommentId }), err } diff --git a/internal/pkg/dao/postmeta.go b/internal/pkg/dao/postmeta.go index d9a92f6..1b0d9bf 100644 --- a/internal/pkg/dao/postmeta.go +++ b/internal/pkg/dao/postmeta.go @@ -4,6 +4,8 @@ import ( "context" "fmt" "github.com/fthvgb1/wp-go/helper" + "github.com/fthvgb1/wp-go/helper/maps" + "github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/internal/pkg/logs" "github.com/fthvgb1/wp-go/internal/pkg/models" "github.com/fthvgb1/wp-go/model" @@ -17,7 +19,7 @@ func GetPostMetaByPostIds(args ...any) (r map[uint64]map[string]any, err error) ids := args[1].([]uint64) rr, err := model.Find[models.Postmeta](ctx, model.SqlBuilder{ {"post_id", "in", ""}, - }, "*", "", nil, nil, nil, 0, helper.SliceMap(ids, helper.ToAny[uint64])) + }, "*", "", nil, nil, nil, 0, slice.Map(ids, helper.ToAny[uint64])) if err != nil { return } @@ -76,7 +78,7 @@ func thumbnail(metadata models.WpAttachmentMetadata, thumbType, host string) (r r.Width = metadata.Sizes[thumbType].Width r.Height = metadata.Sizes[thumbType].Height up := strings.Split(metadata.File, "/") - r.Srcset = strings.Join(helper.MapToSlice[string](metadata.Sizes, func(s string, size models.MetaDataFileSize) (r string, ok bool) { + r.Srcset = strings.Join(maps.FilterToSlice[string](metadata.Sizes, func(s string, size models.MetaDataFileSize) (r string, ok bool) { up[2] = size.File if s == "post-thumbnail" { return diff --git a/internal/pkg/dao/posts.go b/internal/pkg/dao/posts.go index 1e24d45..287cc85 100644 --- a/internal/pkg/dao/posts.go +++ b/internal/pkg/dao/posts.go @@ -5,6 +5,7 @@ import ( "database/sql" "fmt" "github.com/fthvgb1/wp-go/helper" + "github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/internal/pkg/models" "github.com/fthvgb1/wp-go/internal/wpconfig" "github.com/fthvgb1/wp-go/model" @@ -17,7 +18,7 @@ func GetPostsByIds(ids ...any) (m map[uint64]models.Posts, err error) { ctx := ids[0].(context.Context) m = make(map[uint64]models.Posts) id := ids[1].([]uint64) - arg := helper.SliceMap(id, helper.ToAny[uint64]) + arg := slice.Map(id, helper.ToAny[uint64]) rawPosts, err := model.Find[models.Posts](ctx, model.SqlBuilder{{ "Id", "in", "", }}, "a.*,ifnull(d.name,'') category_name,ifnull(taxonomy,'') `taxonomy`", "", nil, model.SqlBuilder{{ diff --git a/internal/pkg/models/wp_postmeta.go b/internal/pkg/models/wp_postmeta.go index d4a1544..2d1b358 100644 --- a/internal/pkg/models/wp_postmeta.go +++ b/internal/pkg/models/wp_postmeta.go @@ -1,7 +1,7 @@ package models import ( - "github.com/fthvgb1/wp-go/helper" + "github.com/fthvgb1/wp-go/helper/maps" "github.com/leeqvip/gophp" ) @@ -29,7 +29,7 @@ func (p Postmeta) AttachmentMetadata() (r WpAttachmentMetadata, err error) { } info, ok := unSerialize.(map[string]any) if ok { - r, err = helper.StrAnyMapToStruct[WpAttachmentMetadata](info) + r, err = maps.StrAnyMapToStruct[WpAttachmentMetadata](info) } } return @@ -42,7 +42,7 @@ func AttachmentMetadata(s string) (r WpAttachmentMetadata, err error) { } info, ok := unSerialize.(map[string]any) if ok { - r, err = helper.StrAnyMapToStruct[WpAttachmentMetadata](info) + r, err = maps.StrAnyMapToStruct[WpAttachmentMetadata](info) } return } diff --git a/internal/plugins/gravatar.go b/internal/plugins/gravatar.go index 1509233..1ebb7c5 100644 --- a/internal/plugins/gravatar.go +++ b/internal/plugins/gravatar.go @@ -2,7 +2,7 @@ package plugins import ( "fmt" - "github.com/fthvgb1/wp-go/helper" + str "github.com/fthvgb1/wp-go/helper/strings" "github.com/fthvgb1/wp-go/internal/wpconfig" "math/rand" "net/url" @@ -16,7 +16,7 @@ func Gravatar(email string, isTls bool) (u string) { num := rand.Intn(3) h := "" if email != "" { - h = helper.StringMd5(strings.ToLower(email)) + h = str.Md5(strings.ToLower(email)) num = int(h[0] % 3) } if isTls { diff --git a/internal/plugins/pagination.go b/internal/plugins/pagination.go index b5bacff..bdc68d5 100644 --- a/internal/plugins/pagination.go +++ b/internal/plugins/pagination.go @@ -2,7 +2,7 @@ package plugins import ( "fmt" - "github.com/fthvgb1/wp-go/helper" + str "github.com/fthvgb1/wp-go/helper/strings" "regexp" "strings" ) @@ -65,5 +65,5 @@ func (p PageEle) Url(path, query string, page int) string { if path == "" { path = "/" } - return helper.StrJoin(path, query) + return str.Join(path, query) } diff --git a/internal/theme/twentyseventeen/twentyseventeen.go b/internal/theme/twentyseventeen/twentyseventeen.go index 67bc3f6..804527b 100644 --- a/internal/theme/twentyseventeen/twentyseventeen.go +++ b/internal/theme/twentyseventeen/twentyseventeen.go @@ -2,7 +2,7 @@ package twentyseventeen import ( "github.com/elliotchance/phpserialize" - "github.com/fthvgb1/wp-go/helper" + "github.com/fthvgb1/wp-go/helper/maps" "github.com/fthvgb1/wp-go/internal/pkg/cache" "github.com/fthvgb1/wp-go/internal/pkg/logs" "github.com/fthvgb1/wp-go/internal/pkg/models" @@ -86,8 +86,8 @@ func getHeaderMarkup() (r HeaderImageMeta, err error) { if ok { err = phpserialize.Unmarshal([]byte(mods), &rr) if err == nil { - rx := helper.MapAnyAnyToStrAny(rr) - r, err = helper.StrAnyMapToStruct[HeaderImageMeta](rx) + rx := maps.AnyAnyToStrAny(rr) + r, err = maps.StrAnyMapToStruct[HeaderImageMeta](rx) } } return diff --git a/model/parse.go b/model/parse.go index 9fdbd9a..caef825 100644 --- a/model/parse.go +++ b/model/parse.go @@ -2,7 +2,7 @@ package model import ( "fmt" - "github.com/fthvgb1/wp-go/helper" + "github.com/fthvgb1/wp-go/helper/slice" "strconv" "strings" ) @@ -25,7 +25,7 @@ func (w SqlBuilder) parseField(ss []string, s *strings.Builder) { } func (w SqlBuilder) parseIn(ss []string, s *strings.Builder, c *int, args *[]any, in *[][]any) (t bool) { - if helper.IsContainInArr(ss[1], []string{"in", "not in"}) && len(*in) > 0 { + if slice.IsContained(ss[1], []string{"in", "not in"}) && len(*in) > 0 { s.WriteString(" (") for _, p := range (*in)[*c] { s.WriteString("?,") @@ -148,7 +148,7 @@ func (w SqlBuilder) ParseWhere(in *[][]any) (string, []any, error) { func (w SqlBuilder) parseOrderBy() string { s := strings.Builder{} for _, ss := range w { - if len(ss) == 2 && ss[0] != "" && helper.IsContainInArr(ss[1], []string{"asc", "desc"}) { + if len(ss) == 2 && ss[0] != "" && slice.IsContained(ss[1], []string{"asc", "desc"}) { s.WriteString(" ") s.WriteString(ss[0]) s.WriteString(" ") diff --git a/model/query.go b/model/query.go index 8dd0ff4..f994166 100644 --- a/model/query.go +++ b/model/query.go @@ -3,7 +3,7 @@ package model import ( "context" "fmt" - "github.com/fthvgb1/wp-go/helper" + "github.com/fthvgb1/wp-go/helper/number" "math/rand" "strings" "time" @@ -87,7 +87,7 @@ func SimplePagination[T Model](ctx context.Context, where ParseWhere, fields, gr return } -func FindOneById[T Model, I helper.IntNumber](ctx context.Context, id I) (T, error) { +func FindOneById[T Model, I number.IntNumber](ctx context.Context, id I) (T, error) { var r T sql := fmt.Sprintf("select * from `%s` where `%s`=?", r.Table(), r.PrimaryKey()) err := globalBb.Get(ctx, &r, sql, id) diff --git a/model/query_test.go b/model/query_test.go index 5796b0c..f742527 100644 --- a/model/query_test.go +++ b/model/query_test.go @@ -4,6 +4,8 @@ import ( "context" "database/sql" "github.com/fthvgb1/wp-go/helper" + "github.com/fthvgb1/wp-go/helper/number" + "github.com/fthvgb1/wp-go/helper/slice" _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" "reflect" @@ -497,10 +499,10 @@ func TestSimplePagination(t *testing.T) { order: nil, join: nil, having: nil, - in: [][]any{helper.SliceMap[int, any](helper.RangeSlice(431, 440, 1), helper.ToAny[int])}, + in: [][]any{slice.Map[int, any](number.Range(431, 440, 1), helper.ToAny[int])}, }, wantR: func() (r []post) { - r, err := Select[post](ctx, "select * from "+post{}.Table()+" where ID in (?,?,?,?,?)", helper.SliceMap[int, any](helper.RangeSlice(431, 435, 1), helper.ToAny[int])...) + r, err := Select[post](ctx, "select * from "+post{}.Table()+" where ID in (?,?,?,?,?)", slice.Map[int, any](number.Range(431, 435, 1), helper.ToAny[int])...) if err != nil && err != sql.ErrNoRows { panic(err) } else if err == sql.ErrNoRows { diff --git a/plugin/digest/digest.go b/plugin/digest/digest.go index 44a136e..d9913fe 100644 --- a/plugin/digest/digest.go +++ b/plugin/digest/digest.go @@ -2,7 +2,8 @@ package digest import ( "fmt" - "github.com/fthvgb1/wp-go/helper" + "github.com/fthvgb1/wp-go/helper/html" + "github.com/fthvgb1/wp-go/helper/slice" "regexp" "strings" "unicode/utf8" @@ -17,7 +18,7 @@ func ClearHtml(str string) string { content := removeWpBlock.ReplaceAllString(str, "") content = strings.Trim(content, " \t\n\r\000\x0B") content = strings.Replace(content, "]]>", "]]>", -1) - content = helper.StripTagsX(content, "