Skip to content

Commit 73f52c5

Browse files
authored
Merge pull request #9 from hyphennn/hyphen/dev
feat: add some util
2 parents 5dc0ebc + a4ce05f commit 73f52c5

5 files changed

Lines changed: 272 additions & 93 deletions

File tree

gcollection/gstack/stack.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Package gstack
2+
// Author: hyphen
3+
// Copyright 2024 hyphen. All rights reserved.
4+
// Create-time: 2024/1/3
5+
package gstack
6+
7+
import (
8+
"github.com/hyphennn/glamda/internal"
9+
)
10+
11+
type node[T any] struct {
12+
val T
13+
next *node[T]
14+
}
15+
16+
type Stack[T any] struct {
17+
top *node[T]
18+
size int
19+
}
20+
21+
func NewStack[T any]() *Stack[T] {
22+
return &Stack[T]{nil, 0}
23+
}
24+
25+
func (s *Stack[T]) Size() int {
26+
return s.size
27+
}
28+
29+
func (s *Stack[T]) Push(t T) {
30+
s.top = &node[T]{t, s.top}
31+
s.size++
32+
}
33+
34+
func (s *Stack[T]) PushN(ts ...T) {
35+
for _, t := range ts {
36+
s.Push(t)
37+
}
38+
}
39+
40+
func (s *Stack[T]) Pop() (T, bool) {
41+
if s.top == nil {
42+
return internal.Zero[T](), false
43+
}
44+
ot := s.top
45+
s.top = s.top.next
46+
s.size--
47+
return ot.val, true
48+
}
49+
50+
func (s *Stack[T]) PopN(n int) []T {
51+
ret := []T{}
52+
for i := 0; i < n; i++ {
53+
v, ok := s.Pop()
54+
if !ok {
55+
break
56+
}
57+
ret = append(ret, v)
58+
}
59+
return ret
60+
}
61+
62+
func (s *Stack[T]) Peek() (T, bool) {
63+
if s.top == nil {
64+
return internal.Zero[T](), false
65+
}
66+
return s.top.val, true
67+
}
68+
69+
func (s *Stack[T]) PeekN(n int) []T {
70+
ptr := s.top
71+
ret := []T{}
72+
for i := 0; i < n; i++ {
73+
if ptr == nil {
74+
break
75+
}
76+
ret = append(ret, ptr.val)
77+
ptr = ptr.next
78+
}
79+
return ret
80+
}

gcollection/gstack/stack_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Package gstack
2+
// Author: hyphen
3+
// Copyright 2024 hyphen. All rights reserved.
4+
// Create-time: 2024/1/3
5+
package gstack
6+
7+
import (
8+
"testing"
9+
10+
"github.com/hyphennn/glamda/internal/assert"
11+
)
12+
13+
func TestStack(t *testing.T) {
14+
stk := NewStack[int]()
15+
stk.PushN([]int{1, 1, 4, 5, 1, 4}...)
16+
stk.Push(1)
17+
v, ok := stk.Peek()
18+
vs := stk.PeekN(5)
19+
assert.Equal(t, v, 1)
20+
assert.True(t, ok)
21+
assert.Equal(t, stk.Size(), 7)
22+
assert.Equal(t, vs, []int{1, 4, 1, 5, 4})
23+
v, ok = stk.Pop()
24+
assert.Equal(t, v, 1)
25+
assert.True(t, ok)
26+
assert.Equal(t, stk.Size(), 6)
27+
vs = stk.PopN(5)
28+
assert.Equal(t, vs, []int{4, 1, 5, 4, 1})
29+
assert.Equal(t, stk.Size(), 1)
30+
assert.Equal(t, stk.PeekN(3), []int{1})
31+
v, ok = stk.Pop()
32+
v, ok = stk.Pop()
33+
assert.Equal(t, v, 0)
34+
assert.False(t, ok)
35+
stk.Push(1)
36+
v, ok = stk.Pop()
37+
assert.Equal(t, v, 1)
38+
assert.True(t, ok)
39+
}

gutils/gutils.go

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
// Package gutils
2+
// Author: hyphen
3+
// Copyright 2023 hyphen. All rights reserved.
4+
// Create-time: 2023/12/4
5+
package gutils
6+
7+
import (
8+
"bytes"
9+
"context"
10+
"encoding/json"
11+
"fmt"
12+
"io/ioutil"
13+
"net/http"
14+
"sync"
15+
16+
"github.com/hyphennn/glamda/internal"
17+
)
18+
19+
func TernaryForm[T any](cond bool, tureVal, falseVal T) T {
20+
if cond {
21+
return tureVal
22+
}
23+
return falseVal
24+
}
25+
26+
type Pair[F, S any] struct {
27+
First F
28+
Second S
29+
}
30+
31+
func MakePair[F, S any](f F, s S) *Pair[F, S] {
32+
return &Pair[F, S]{First: f, Second: s}
33+
}
34+
35+
func (p *Pair[F, S]) Split() (F, S) {
36+
return p.First, p.Second
37+
}
38+
39+
func FastAssert[T any](v any) T {
40+
t, ok := v.(T)
41+
if !ok {
42+
return internal.Zero[T]()
43+
}
44+
return t
45+
}
46+
47+
func MustDo[K, V any](key K, fc func(K) (V, error)) V {
48+
return MustEasyDo(func() (V, error) {
49+
return fc(key)
50+
})
51+
}
52+
53+
func MustDoCtx[K, V any](ctx context.Context, key K, fc func(context.Context, K) (V, error)) V {
54+
return MustEasyDo(func() (V, error) {
55+
return fc(ctx, key)
56+
})
57+
}
58+
59+
func MustEasyDo[V any](fc func() (V, error)) V {
60+
v, err := fc()
61+
if err != nil {
62+
return internal.Zero[V]()
63+
}
64+
return v
65+
}
66+
67+
type ch[T any] chan T
68+
69+
type SafeChan[T any] struct {
70+
ch[T]
71+
once sync.Once
72+
}
73+
74+
func NewSafeChan[T any](size ...int) *SafeChan[T] {
75+
if len(size) == 0 {
76+
return &SafeChan[T]{make(chan T), sync.Once{}}
77+
}
78+
return &SafeChan[T]{make(chan T, size[0]), sync.Once{}}
79+
}
80+
81+
func (s *SafeChan[T]) Listen() (t T) {
82+
t = <-s.ch
83+
return
84+
}
85+
86+
func (s *SafeChan[T]) Send(t T) {
87+
s.ch <- t
88+
}
89+
90+
func (s *SafeChan[T]) Close() {
91+
s.once.Do(func() {
92+
close(s.ch)
93+
})
94+
}
95+
96+
func Paging[T any](arr []T, offset, limit int) []T {
97+
return arr[TernaryForm((offset)*limit <= len(arr), (offset)*limit, len(arr)):TernaryForm((offset+1)*limit <= len(arr), (offset+1)*limit, len(arr))]
98+
}
99+
100+
var client = &http.Client{}
101+
102+
func AccessResp(ctx context.Context, url string, method string, header map[string]string, param map[string]string,
103+
body any, setAuthorization func(*http.Request)) (*http.Response, error) {
104+
return access(ctx, url, method, header, param, body, setAuthorization)
105+
}
106+
107+
func Access[T any](ctx context.Context, url string, method string, header map[string]string, param map[string]string,
108+
body any, setAuthorization func(*http.Request), isSuccess func(response *http.Response) bool) (T, error) {
109+
var ret T
110+
resp, err := access(ctx, url, method, header, param, body, setAuthorization)
111+
if err != nil {
112+
return ret, fmt.Errorf("access %s failed: %w", url, err)
113+
}
114+
defer resp.Body.Close()
115+
respBody, err := ioutil.ReadAll(resp.Body)
116+
if err != nil {
117+
return ret, fmt.Errorf("read resp body failed: %w", err)
118+
}
119+
if isSuccess != nil && !isSuccess(resp) {
120+
return ret, fmt.Errorf("is success return false: %s", string(respBody))
121+
}
122+
err = json.Unmarshal(respBody, &ret)
123+
if err != nil {
124+
return ret, fmt.Errorf("unmarshal resp body failed: %w", err)
125+
}
126+
return ret, nil
127+
}
128+
129+
func access(ctx context.Context, url string, method string, header map[string]string, param map[string]string,
130+
body any, setAuthorization func(*http.Request)) (*http.Response, error) {
131+
bodyJSON, err := json.Marshal(body)
132+
if err != nil {
133+
return nil, err
134+
}
135+
bodyReader := bytes.NewReader(bodyJSON)
136+
req, err := http.NewRequestWithContext(ctx, method, url, bodyReader)
137+
if setAuthorization != nil {
138+
setAuthorization(req)
139+
}
140+
q := req.URL.Query()
141+
for k, v := range param {
142+
q.Add(k, v)
143+
}
144+
req.URL.RawQuery = q.Encode()
145+
for k, v := range header {
146+
req.Header.Add(k, v)
147+
}
148+
resp, err := client.Do(req)
149+
if err != nil {
150+
return nil, fmt.Errorf("access %s failed: %w", url, err)
151+
}
152+
return resp, nil
153+
}

gutils/lutils.go

Lines changed: 0 additions & 93 deletions
This file was deleted.
File renamed without changes.

0 commit comments

Comments
 (0)