Categorygithub.com/eric2788/common-utils
module
0.0.0-20230530025427-301a0a7f2da8
Repository: https://github.com/eric2788/common-utils.git
Documentation: pkg.go.dev

# README

common-utils

本人在 golang 程序開發經常使用的工具

Modules

  • request - 仿 axios 的請求 API
  • regex - 目前只有 utils 類
  • datetime - 目前只有 utils 類
  • array - 目前只有 utils 類
  • str - 目前只有 utils 類
  • stream - 仿 Functional Programming 的 collection API

utils 類別的 package 將不作介紹,可自行參考源碼

Request

基本請求

requester := request.New()
var resp Product
_, err := requester.Get("https://dummyjson.com/products/1", &resp)
if err != nil {
    panic(err)
}

原始請求

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

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 的請求

requester.Get("https://dummyjson.com/products", request.Query(map[string]interface{}{
    "page": 1,
    "pageSize": 30
}))

帶有 payload 數據的請求

// 默認是json請求
requester.Post("https://dummyjson.com/products", request.Data(map[string]interface{}{
    "title": "Dummy Product",
    "price": 234,
}))

改用 form url encode 作為 payload 數據

requester.Post("https://dummyjson.com/products",
    request.Data(map[string]interface{}{
        "title": "Dummy Product",
        "price": 234,
    }),
    request.DataEncoder(request.FormUrlEncodedEncoder) // 庫內置的 encoder
)

自定義 encoder/decoder


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

請求/回應攔截

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]

  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]

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)
	
}

# Packages

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author