https://github.com/eric2788/common-utils
All common utils for my golang development
https://github.com/eric2788/common-utils
Last synced: about 1 month ago
JSON representation
All common utils for my golang development
- Host: GitHub
- URL: https://github.com/eric2788/common-utils
- Owner: eric2788
- Created: 2022-01-24T09:31:31.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2023-05-30T02:54:28.000Z (about 3 years ago)
- Last Synced: 2025-01-12T08:33:05.996Z (over 1 year ago)
- Language: Go
- Size: 55.7 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# common-utils
本人在 golang 程序開發經常使用的工具
## Modules
- request - 仿 axios 的請求 API
- regex - 目前只有 utils 類
- datetime - 目前只有 utils 類
- array - 目前只有 utils 類
- str - 目前只有 utils 類
- stream - 仿 Functional Programming 的 collection API
utils 類別的 package 將不作介紹,可自行參考源碼
### Request
基本請求
```go
requester := request.New()
var resp Product
_, err := requester.Get("https://dummyjson.com/products/1", &resp)
if err != nil {
panic(err)
}
```
原始請求
```go
requester := request.New().Raw()
resp, err := requester.Get("https://dummyjson.com/products/1")
if err != nil {
panic(err)
}
r := resp.Resp // *http.Response
```
帶有 base url 的 requester
```go
requester := request.New(
request.WithBaseUrl("https://dummyjson.com"),
// headers(如有)
request.WithHeaders(map[string]string{
"Content-Type": "application/json"
}),
//cookies (如有)
request.WithCookies(map[string]string{
"token": "awhdiawhdiawhidahwi"
}),
// 自定義 http 客戶端
request.WithClient(&http.Client{}),
// 自定義逾時
request.WithTimeout(10 * time.Second)
)
var products []Product
var product Product
_, err := requester.Get("/products", &products)
_, err = requester.Get("/product/1", &product)
```
帶有 query string 的請求
```go
requester.Get("https://dummyjson.com/products", request.Query(map[string]interface{}{
"page": 1,
"pageSize": 30
}))
```
帶有 payload 數據的請求
```go
// 默認是json請求
requester.Post("https://dummyjson.com/products", request.Data(map[string]interface{}{
"title": "Dummy Product",
"price": 234,
}))
```
改用 form url encode 作為 payload 數據
```go
requester.Post("https://dummyjson.com/products",
request.Data(map[string]interface{}{
"title": "Dummy Product",
"price": 234,
}),
request.DataEncoder(request.FormUrlEncodedEncoder) // 庫內置的 encoder
)
```
自定義 encoder/decoder
```go
myEncoder := func(data map[string]interface{}) (io.Reader, error) {
buffer := new(bytes.Buffer)
enc := gob.NewEncoder(buffer)
err := enc.Encode(data)
if err != nil {
return nil, err
}
return buffer, nil
}
myDecoder := func(data []byte, res interface{}) error {
buffer := bytes.NewBuffer(data)
dec := gob.NewDecoder(buffer)
return dec.Decode(res)
}
// 設置為默認的 encoder/decoder
requester := request.New(
request.WithBaseUrl("https://dummyjson.com"),
request.WithDefaultEncoder(myEnoder),
request.WithDefaultDecoder(myDecoder),
)
var products []Product
_, err := requester.Get("/products", &products)
var product Product
_, err = requester.Get("/products/1", &product, request.WithEncoder(request.JsonEncoder)) // 把此請求改用 JsonEncoder
```
請求/回應攔截
```go
requester := request.New(
AddRequestIntercepter(func(r *http.Request) error {
// do something with request
t.Logf("prepare to request: %s", r.URL.String())
return nil
}),
AddResponseIntercepter(func(r *http.Response) error {
// do something with response
t.Logf("status code from %s: %d", r.Request.URL.String(), r.StatusCode)
return nil
}),
)
```
### Stream
大致分為兩種
Stream[T] - 可以從 array / set 中初始化
MapStream[K, V] - 可以從 map 中初始化
懶,直接上 test function
**Steam[T]**
```go
func TestStudentArr(t *testing.T) {
students := []Student{
{"Alice", 20},
{"Bob", 18},
{"Charlie", 19},
{"David", 20},
{"Eve", 18},
{"Frank", 19},
{"Grace", 20},
{"Heidi", 18},
{"Ivan", 19},
{"Judy", 20},
{"Kevin", 18},
{"Lily", 19},
{"Mallory", 20},
{"Nate", 18},
{"Oliver", 19},
{"Peggy", 20},
// give me some non-adult
{"Quentin", 17},
{"Romeo", 17},
{"Steve", 17},
{"Trent", 17},
{"Uma", 17},
{"Victor", 17},
{"Walter", 17},
{"Xavier", 17},
{"Yvonne", 17},
{"Zack", 17},
}
// filter
adults := From(students).Filter(func(s Student) bool {
return s.Age >= 18
})
t.Log("adults:", adults)
// anyMatch
any20 := adults.AnyMatch(func(s Student) bool {
return s.Age == 20
})
t.Log("any20:", any20)
// combine
r := From(students).
Filter(func(s Student) bool {
return s.Age == 20
}).
AnyMatch(func(s Student) bool {
return s.Name == "Alice"
})
t.Log("20 and Alice:", r)
// map
names := MapTo(From(students), func(s Student) string {
return s.Name
})
t.Log("names:", names)
s := From(students).Filter(func(s Student) bool {
return s.Age > 17
})
m1 := ToMapStream(s, func(s Student)(string, int) {
return s.Name, s.Age
})
t.Logf("%+v", m1.ToMap())
m2 := ToMapStream(s, func(s Student)(string, Student) {
return s.Name, s
})
t.Logf("%+v", m2.ToMap())
}
```
**MapStream[K, V]**
```go
func TestMapStream(t *testing.T) {
m := map[string]string{
"1": "a",
"2": "b",
"3": "c",
}
ms := FromMap(m)
r := ms.Filter(func(k, v string) bool {
return k == "1"
})
t.Log(r.ToMap())
r = ms.Map(func(k, v string) (string, string) {
return k, v + "!"
})
t.Log(r.ToMap())
// map to entries -> Stream[MapEntry[K, V]]
r2 := ms.Entries().Find(func(e MapEntry[string, string]) bool {
return e.Key == "1"
})
t.Logf("%v: %v", r2.Key, r2.Value)
}
```