Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions gcollection/gstack/stack.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Package gstack
// Author: hyphen
// Copyright 2024 hyphen. All rights reserved.
// Create-time: 2024/1/3
package gstack

import (
"github.com/hyphennn/glamda/internal"
)

type node[T any] struct {
val T
next *node[T]
}

type Stack[T any] struct {
top *node[T]
size int
}

func NewStack[T any]() *Stack[T] {
return &Stack[T]{nil, 0}
}

func (s *Stack[T]) Size() int {
return s.size
}

func (s *Stack[T]) Push(t T) {
s.top = &node[T]{t, s.top}
s.size++
}

func (s *Stack[T]) PushN(ts ...T) {
for _, t := range ts {
s.Push(t)
}
}

func (s *Stack[T]) Pop() (T, bool) {
if s.top == nil {
return internal.Zero[T](), false
}
ot := s.top
s.top = s.top.next
s.size--
return ot.val, true
}

func (s *Stack[T]) PopN(n int) []T {
ret := []T{}
for i := 0; i < n; i++ {
v, ok := s.Pop()
if !ok {
break
}
ret = append(ret, v)
}
return ret
}

func (s *Stack[T]) Peek() (T, bool) {
if s.top == nil {
return internal.Zero[T](), false
}
return s.top.val, true
}

func (s *Stack[T]) PeekN(n int) []T {
ptr := s.top
ret := []T{}
for i := 0; i < n; i++ {
if ptr == nil {
break
}
ret = append(ret, ptr.val)
ptr = ptr.next
}
return ret
}
39 changes: 39 additions & 0 deletions gcollection/gstack/stack_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Package gstack
// Author: hyphen
// Copyright 2024 hyphen. All rights reserved.
// Create-time: 2024/1/3
package gstack

import (
"testing"

"github.com/hyphennn/glamda/internal/assert"
)

func TestStack(t *testing.T) {
stk := NewStack[int]()
stk.PushN([]int{1, 1, 4, 5, 1, 4}...)
stk.Push(1)
v, ok := stk.Peek()
vs := stk.PeekN(5)
assert.Equal(t, v, 1)
assert.True(t, ok)
assert.Equal(t, stk.Size(), 7)
assert.Equal(t, vs, []int{1, 4, 1, 5, 4})
v, ok = stk.Pop()
assert.Equal(t, v, 1)
assert.True(t, ok)
assert.Equal(t, stk.Size(), 6)
vs = stk.PopN(5)
assert.Equal(t, vs, []int{4, 1, 5, 4, 1})
assert.Equal(t, stk.Size(), 1)
assert.Equal(t, stk.PeekN(3), []int{1})
v, ok = stk.Pop()
v, ok = stk.Pop()
assert.Equal(t, v, 0)
assert.False(t, ok)
stk.Push(1)
v, ok = stk.Pop()
assert.Equal(t, v, 1)
assert.True(t, ok)
}
153 changes: 153 additions & 0 deletions gutils/gutils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
// Package gutils
// Author: hyphen
// Copyright 2023 hyphen. All rights reserved.
// Create-time: 2023/12/4
package gutils

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"sync"

"github.com/hyphennn/glamda/internal"
)

func TernaryForm[T any](cond bool, tureVal, falseVal T) T {
if cond {
return tureVal
}
return falseVal
}

type Pair[F, S any] struct {
First F
Second S
}

func MakePair[F, S any](f F, s S) *Pair[F, S] {
return &Pair[F, S]{First: f, Second: s}
}

func (p *Pair[F, S]) Split() (F, S) {
return p.First, p.Second
}

func FastAssert[T any](v any) T {
t, ok := v.(T)
if !ok {
return internal.Zero[T]()
}
return t
}

func MustDo[K, V any](key K, fc func(K) (V, error)) V {
return MustEasyDo(func() (V, error) {
return fc(key)
})
}

func MustDoCtx[K, V any](ctx context.Context, key K, fc func(context.Context, K) (V, error)) V {
return MustEasyDo(func() (V, error) {
return fc(ctx, key)
})
}

func MustEasyDo[V any](fc func() (V, error)) V {
v, err := fc()
if err != nil {
return internal.Zero[V]()
}
return v
}

type ch[T any] chan T

type SafeChan[T any] struct {
ch[T]
once sync.Once
}

func NewSafeChan[T any](size ...int) *SafeChan[T] {
if len(size) == 0 {
return &SafeChan[T]{make(chan T), sync.Once{}}
}
return &SafeChan[T]{make(chan T, size[0]), sync.Once{}}
}

func (s *SafeChan[T]) Listen() (t T) {
t = <-s.ch
return
}

func (s *SafeChan[T]) Send(t T) {
s.ch <- t
}

func (s *SafeChan[T]) Close() {
s.once.Do(func() {
close(s.ch)
})
}

func Paging[T any](arr []T, offset, limit int) []T {
return arr[TernaryForm((offset)*limit <= len(arr), (offset)*limit, len(arr)):TernaryForm((offset+1)*limit <= len(arr), (offset+1)*limit, len(arr))]
}

var client = &http.Client{}

func AccessResp(ctx context.Context, url string, method string, header map[string]string, param map[string]string,
body any, setAuthorization func(*http.Request)) (*http.Response, error) {
return access(ctx, url, method, header, param, body, setAuthorization)
}

func Access[T any](ctx context.Context, url string, method string, header map[string]string, param map[string]string,
body any, setAuthorization func(*http.Request), isSuccess func(response *http.Response) bool) (T, error) {
var ret T
resp, err := access(ctx, url, method, header, param, body, setAuthorization)
if err != nil {
return ret, fmt.Errorf("access %s failed: %w", url, err)
}
defer resp.Body.Close()
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return ret, fmt.Errorf("read resp body failed: %w", err)
}
if isSuccess != nil && !isSuccess(resp) {
return ret, fmt.Errorf("is success return false: %s", string(respBody))
}
err = json.Unmarshal(respBody, &ret)
if err != nil {
return ret, fmt.Errorf("unmarshal resp body failed: %w", err)
}
return ret, nil
}

func access(ctx context.Context, url string, method string, header map[string]string, param map[string]string,
body any, setAuthorization func(*http.Request)) (*http.Response, error) {
bodyJSON, err := json.Marshal(body)
if err != nil {
return nil, err
}
bodyReader := bytes.NewReader(bodyJSON)
req, err := http.NewRequestWithContext(ctx, method, url, bodyReader)
if setAuthorization != nil {
setAuthorization(req)
}
q := req.URL.Query()
for k, v := range param {
q.Add(k, v)
}
req.URL.RawQuery = q.Encode()
for k, v := range header {
req.Header.Add(k, v)
}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("access %s failed: %w", url, err)
}
return resp, nil
}
93 changes: 0 additions & 93 deletions gutils/lutils.go

This file was deleted.

File renamed without changes.