{"id":19965366,"url":"https://github.com/eric2788/common-utils","last_synced_at":"2026-05-12T18:17:31.886Z","repository":{"id":57652798,"uuid":"451399520","full_name":"eric2788/common-utils","owner":"eric2788","description":"All common utils for my golang development","archived":false,"fork":false,"pushed_at":"2023-05-30T02:54:28.000Z","size":57,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-12T08:33:05.996Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eric2788.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-01-24T09:31:31.000Z","updated_at":"2022-01-24T09:31:58.000Z","dependencies_parsed_at":"2024-11-13T06:02:13.979Z","dependency_job_id":null,"html_url":"https://github.com/eric2788/common-utils","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eric2788%2Fcommon-utils","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eric2788%2Fcommon-utils/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eric2788%2Fcommon-utils/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eric2788%2Fcommon-utils/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eric2788","download_url":"https://codeload.github.com/eric2788/common-utils/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241396781,"owners_count":19956408,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-13T02:28:29.496Z","updated_at":"2026-05-12T18:17:26.427Z","avatar_url":"https://github.com/eric2788.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# common-utils\n\n本人在 golang 程序開發經常使用的工具\n\n## Modules\n\n- request - 仿 axios 的請求 API\n- regex - 目前只有 utils 類\n- datetime - 目前只有 utils 類\n- array - 目前只有 utils 類\n- str - 目前只有 utils 類\n- stream - 仿 Functional Programming 的 collection API\n\nutils 類別的 package 將不作介紹，可自行參考源碼\n\n### Request\n\n基本請求\n\n```go\nrequester := request.New()\nvar resp Product\n_, err := requester.Get(\"https://dummyjson.com/products/1\", \u0026resp)\nif err != nil {\n    panic(err)\n}\n```\n\n原始請求\n\n```go\nrequester := request.New().Raw()\nresp, err := requester.Get(\"https://dummyjson.com/products/1\")\nif err != nil {\n    panic(err)\n}\nr := resp.Resp // *http.Response\n```\n\n帶有 base url 的 requester\n\n```go\nrequester := request.New(\n    request.WithBaseUrl(\"https://dummyjson.com\"),\n    // headers（如有)\n    request.WithHeaders(map[string]string{\n        \"Content-Type\": \"application/json\"\n    }),\n\n    //cookies (如有)\n    request.WithCookies(map[string]string{\n        \"token\": \"awhdiawhdiawhidahwi\"\n    }),\n\n    // 自定義 http 客戶端\n    request.WithClient(\u0026http.Client{}),\n\n    // 自定義逾時\n    request.WithTimeout(10 * time.Second)\n)\n\nvar products []Product\nvar product Product\n_, err := requester.Get(\"/products\", \u0026products)\n_, err = requester.Get(\"/product/1\", \u0026product)\n```\n\n帶有 query string 的請求\n\n```go\nrequester.Get(\"https://dummyjson.com/products\", request.Query(map[string]interface{}{\n    \"page\": 1,\n    \"pageSize\": 30\n}))\n```\n\n帶有 payload 數據的請求\n\n```go\n// 默認是json請求\nrequester.Post(\"https://dummyjson.com/products\", request.Data(map[string]interface{}{\n    \"title\": \"Dummy Product\",\n    \"price\": 234,\n}))\n```\n\n改用 form url encode 作為 payload 數據\n\n```go\nrequester.Post(\"https://dummyjson.com/products\",\n    request.Data(map[string]interface{}{\n        \"title\": \"Dummy Product\",\n        \"price\": 234,\n    }),\n    request.DataEncoder(request.FormUrlEncodedEncoder) // 庫內置的 encoder\n)\n```\n\n自定義 encoder/decoder\n\n```go\n\nmyEncoder := func(data map[string]interface{}) (io.Reader, error) {\n    buffer := new(bytes.Buffer)\n\tenc := gob.NewEncoder(buffer)\n\terr := enc.Encode(data)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn buffer, nil\n}\n\nmyDecoder := func(data []byte, res interface{}) error {\n    buffer := bytes.NewBuffer(data)\n\tdec := gob.NewDecoder(buffer)\n\treturn dec.Decode(res)\n}\n\n// 設置為默認的 encoder/decoder\nrequester := request.New(\n    request.WithBaseUrl(\"https://dummyjson.com\"),\n    request.WithDefaultEncoder(myEnoder),\n    request.WithDefaultDecoder(myDecoder),\n)\n\nvar products []Product\n_, err := requester.Get(\"/products\", \u0026products)\nvar product Product\n_, err = requester.Get(\"/products/1\", \u0026product, request.WithEncoder(request.JsonEncoder)) // 把此請求改用 JsonEncoder\n```\n\n請求/回應攔截\n\n```go\nrequester := request.New(\n    AddRequestIntercepter(func(r *http.Request) error {\n\t\t// do something with request\n\t\tt.Logf(\"prepare to request: %s\", r.URL.String())\n\t\treturn nil\n\t}),\n\tAddResponseIntercepter(func(r *http.Response) error {\n\t\t// do something with response\n\t\tt.Logf(\"status code from %s: %d\", r.Request.URL.String(), r.StatusCode)\n\t\treturn nil\n\t}),\n)\n```\n\n\n### Stream\n\n大致分為兩種\n\nStream[T] - 可以從 array / set 中初始化\nMapStream[K, V] - 可以從 map 中初始化\n\n懶，直接上 test function\n\n**Steam[T]**\n\n```go\n  func TestStudentArr(t *testing.T) {\n\n\tstudents := []Student{\n\t\t{\"Alice\", 20},\n\t\t{\"Bob\", 18},\n\t\t{\"Charlie\", 19},\n\t\t{\"David\", 20},\n\t\t{\"Eve\", 18},\n\t\t{\"Frank\", 19},\n\t\t{\"Grace\", 20},\n\t\t{\"Heidi\", 18},\n\t\t{\"Ivan\", 19},\n\t\t{\"Judy\", 20},\n\t\t{\"Kevin\", 18},\n\t\t{\"Lily\", 19},\n\t\t{\"Mallory\", 20},\n\t\t{\"Nate\", 18},\n\t\t{\"Oliver\", 19},\n\t\t{\"Peggy\", 20},\n\t\t// give me some non-adult\n\t\t{\"Quentin\", 17},\n\t\t{\"Romeo\", 17},\n\t\t{\"Steve\", 17},\n\t\t{\"Trent\", 17},\n\t\t{\"Uma\", 17},\n\t\t{\"Victor\", 17},\n\t\t{\"Walter\", 17},\n\t\t{\"Xavier\", 17},\n\t\t{\"Yvonne\", 17},\n\t\t{\"Zack\", 17},\n\t}\n\n\t// filter\n\n\tadults := From(students).Filter(func(s Student) bool {\n\t\treturn s.Age \u003e= 18\n\t})\n\n\tt.Log(\"adults:\", adults)\n\n\t// anyMatch\n\n\tany20 := adults.AnyMatch(func(s Student) bool {\n\t\treturn s.Age == 20\n\t})\n\n\tt.Log(\"any20:\", any20)\n\n\t// combine\n\n\tr := From(students).\n\t\tFilter(func(s Student) bool {\n\t\t\treturn s.Age == 20\n\t\t}).\n\t\tAnyMatch(func(s Student) bool {\n\t\t\treturn s.Name == \"Alice\"\n\t\t})\n\n\tt.Log(\"20 and Alice:\", r)\n\n\t// map\n\n\tnames := MapTo(From(students), func(s Student) string {\n\t\treturn s.Name\n\t})\n\n\tt.Log(\"names:\", names)\n\n\n\ts := From(students).Filter(func(s Student) bool {\n\t\treturn s.Age \u003e 17\n\t})\n\n\tm1 := ToMapStream(s, func(s Student)(string, int)  {\n\t\treturn s.Name, s.Age\n\t})\n\n\tt.Logf(\"%+v\", m1.ToMap())\n\t\n\tm2 := ToMapStream(s, func(s Student)(string, Student)  {\n\t\treturn s.Name, s\n\t})\n\n\tt.Logf(\"%+v\", m2.ToMap())\n\n}\n```\n\n\n**MapStream[K, V]**\n\n```go\nfunc TestMapStream(t *testing.T) {\n\tm := map[string]string{\n\t\t\"1\": \"a\",\n\t\t\"2\": \"b\",\n\t\t\"3\": \"c\",\n\t}\n\n\tms := FromMap(m)\n\tr := ms.Filter(func(k, v string) bool {\n\t\treturn k == \"1\"\n\t})\n\n\tt.Log(r.ToMap())\n\n\tr = ms.Map(func(k, v string) (string, string) {\n\t\treturn k, v + \"!\"\n\t})\n\n\tt.Log(r.ToMap())\n\n\t// map to entries -\u003e Stream[MapEntry[K, V]]\n\tr2 := ms.Entries().Find(func(e MapEntry[string, string]) bool {\n\t\treturn e.Key == \"1\"\n\t})\n\t\n\tt.Logf(\"%v: %v\", r2.Key, r2.Value)\n\t\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feric2788%2Fcommon-utils","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feric2788%2Fcommon-utils","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feric2788%2Fcommon-utils/lists"}