1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-02-04 12:52:28 +08:00

Compare commits

...

49 Commits

Author SHA1 Message Date
dudaodong
76d68e326b release v1.3.2 2022-08-31 17:05:38 +08:00
dudaodong
67b4782ac2 doc: add document for functions in netutil/http_client.go 2022-08-31 15:53:18 +08:00
dudaodong
1d8b9a2625 feat: add http client for sending http request 2022-08-31 11:49:27 +08:00
dudaodong
94ae1acc78 doc: update readme file 2022-08-29 15:31:19 +08:00
dudaodong
aece2995d6 refactor: change ReverseStr to Reverse in strutil package 2022-08-29 15:11:15 +08:00
dudaodong
f5ec5eb58d feat: add EncodeByte and DecodeByte 2022-08-29 15:08:50 +08:00
dudaodong
d62284e9a6 feat: add IsZeroValue function 2022-08-29 14:59:36 +08:00
dudaodong
b6815224fd release v1.3.1 2022-08-02 17:52:18 +08:00
dudaodong
5931b882ee doc: update document for system package 2022-07-29 13:33:23 +08:00
dudaodong
f8096e3585 doc: update slice document 2022-07-29 13:31:04 +08:00
dudaodong
979381bfb7 doc: update convertor document 2022-07-29 13:28:25 +08:00
dudaodong
3e2c25f827 doc: update netutil document 2022-07-29 13:23:30 +08:00
dudaodong
2c7bcc9fbb doc: update slice document 2022-07-29 13:17:05 +08:00
dudaodong
3a944ab12f test: update slice unit test 2022-07-27 15:31:12 +08:00
dudaodong
387079d034 feat: os.go, add GetOsBits 2022-07-27 15:27:39 +08:00
dudaodong
33e3631b72 fix: fix aes/des cbc crypto iv bug 2022-07-27 15:26:45 +08:00
dudaodong
b3149ea619 feat: convertor.go, add ToChannel 2022-07-27 15:22:43 +08:00
dudaodong
116ff284c3 feat: net.go, add IsInternalIP, GetRequestPublicIp, EncodeUrl 2022-07-27 15:18:20 +08:00
dudaodong
0cb251f7b8 feat: add ToSlice and ToSlicePointer and AppendIfAbsent 2022-07-27 15:12:14 +08:00
dudaodong
683def2242 docs: update go version badge 2022-06-24 09:41:46 +08:00
dudaodong
d4a90f2869 release v1.3.0 2022-06-22 16:30:45 +08:00
dudaodong
be67de3b40 release v1.3.0 2022-06-22 15:58:41 +08:00
dudaodong
6898ed413e docs: add doc for UniqueBy function 2022-06-22 15:47:48 +08:00
dudaodong
5dbdbcd651 docs: add doc for UniqueBy function 2022-06-22 15:45:29 +08:00
dudaodong
ae0facd32d refactor: clean code for slice/slice.go 2022-06-22 14:21:45 +08:00
dudaodong
2d7e19fb87 feat: add UniqueBy function in slice.go 2022-06-22 12:00:01 +08:00
dudaodong
24d4a03227 update .gitignore file 2022-06-22 11:27:31 +08:00
dudaodong
93fb089f6e docs: add CreateDir function for fileutil 2022-06-17 17:25:16 +08:00
dudaodong
2fe272f2ef docs: add CreateDir function for fileutil 2022-06-17 17:22:08 +08:00
dudaodong
77859ffa15 docs: add doc for SplitEx function 2022-06-17 17:19:59 +08:00
dudaodong
f83f47df3a feat: add SplitEx function 2022-06-17 17:13:58 +08:00
dudaodong
885c08847d docs: add doc for function IndexOf and LastIndexOf 2022-06-17 17:11:09 +08:00
dudaodong
cc4a20751f test: add unit test for funcation IndexOf and LastIndexOf 2022-06-17 17:02:44 +08:00
dudaodong
b0d1d39452 feat: add IndexOf and LastIndexOf function in slice.go 2022-06-17 17:01:37 +08:00
dudaodong
02fa7bc8be docs: add doc for function Equal and EqualWithFunc 2022-06-17 16:57:42 +08:00
dudaodong
433eb63b86 feat: add EqualWith function for slice 2022-06-17 15:47:36 +08:00
dudaodong
a2541dac03 feat: add Equal function for slice 2022-06-17 15:37:36 +08:00
dudaodong
690e746811 update readme file 2022-04-29 14:50:29 +08:00
dudaodong
7cb97a26c5 release v1.2.9 2022-04-14 11:41:46 +08:00
dudaodong
39d373d37b fix: fix http post to support multipart/form-data header 2022-04-14 11:39:21 +08:00
dudaodong
1aefd6aa12 release v1.2.8 2022-04-13 11:46:14 +08:00
dudaodong
c7aa44b8a4 fix: fix http post fucntion 2022-04-13 11:38:45 +08:00
dudaodong
0e3dc68de5 release v1.2.7 2022-03-29 10:52:55 +08:00
dudaodong
4083e75ed4 fix: fix ToBytes bug 2022-03-26 21:09:28 +08:00
dudaodong
1327eff62f docs: add doc for unix time 2022-03-24 16:09:19 +08:00
dudaodong
eb24c37143 docs: add doc for unix time 2022-03-24 16:07:17 +08:00
dudaodong
b7a6c91064 feat: add unix date conversion 2022-03-24 16:03:57 +08:00
dudaodong
555e185871 feat: add unix date conversion 2022-03-24 16:01:41 +08:00
dudaodong
cb0efc5cc7 docs: replace path '/main' with '/v1' 2022-03-16 16:18:28 +08:00
53 changed files with 3726 additions and 600 deletions

1
.gitignore vendored
View File

@@ -6,4 +6,5 @@ fileutil/*.txt
fileutil/*.zip fileutil/*.zip
fileutil/*.link fileutil/*.link
fileutil/unzip/* fileutil/unzip/*
slice/testdata/*
cryptor/*.pem cryptor/*.pem

455
README.md
View File

@@ -3,13 +3,13 @@
<br/> <br/>
![Go version](https://img.shields.io/badge/go-%3E%3D1.16<recommend>-9cf) ![Go version](https://img.shields.io/badge/go-v1.16-9cf)
[![Release](https://img.shields.io/badge/release-1.2.6-green.svg)](https://github.com/duke-git/lancet/releases) [![Release](https://img.shields.io/badge/release-1.3.2-green.svg)](https://github.com/duke-git/lancet/releases)
[![GoDoc](https://godoc.org/github.com//duke-git/lancet?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet) [![GoDoc](https://godoc.org/github.com//duke-git/lancet?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet)
[![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet)](https://goreportcard.com/report/github.com/duke-git/lancet) [![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet)](https://goreportcard.com/report/github.com/duke-git/lancet)
[![test](https://github.com/duke-git/lancet/actions/workflows/codecov.yml/badge.svg?branch=main&event=push)](https://github.com/duke-git/lancet/actions/workflows/codecov.yml) [![test](https://github.com/duke-git/lancet/actions/workflows/codecov.yml/badge.svg?branch=main&event=push)](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
[![codecov](https://codecov.io/gh/duke-git/lancet/branch/main/graph/badge.svg?token=FC48T1F078)](https://codecov.io/gh/duke-git/lancet) [![codecov](https://codecov.io/gh/duke-git/lancet/branch/main/graph/badge.svg?token=FC48T1F078)](https://codecov.io/gh/duke-git/lancet)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/duke-git/lancet/blob/main/LICENSE) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/duke-git/lancet/blob/v1/LICENSE)
</div> </div>
@@ -24,7 +24,7 @@ English | [简体中文](./README_zh-CN.md)
## Feature ## Feature
- 👏 Comprehensive, efficient and reusable. - 👏 Comprehensive, efficient and reusable.
- 💪 180+ go util functions, support string, slice, datetime, net, crypt... - 💪 200+ go util functions, support string, slice, datetime, net, crypt...
- 💅 Only depend on the go standard library. - 💅 Only depend on the go standard library.
- 🌍 Unit test for every exported function. - 🌍 Unit test for every exported function.
@@ -44,7 +44,7 @@ import "github.com/duke-git/lancet/strutil"
## Example ## Example
Here takes the string function ReverseStr (reverse order string) as an example, and the strutil package needs to be imported. Here takes the string function Reverse (reverse order string) as an example, and the strutil package needs to be imported.
```go ```go
package main package main
@@ -56,99 +56,110 @@ import (
func main() { func main() {
s := "hello" s := "hello"
rs := strutil.ReverseStr(s) rs := strutil.Reverse(s)
fmt.Println(rs) //olleh fmt.Println(rs) //olleh
} }
``` ```
## API Documentation ## API Documentation
### Convertor package contains some functions for data convertion. ### 1. Convertor package contains some functions for data convertion.
```go ```go
import "github.com/duke-git/lancet/convertor" import "github.com/duke-git/lancet/convertor"
``` ```
#### Function list: #### Function list:
- [ColorHexToRGB](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ColorHexToRGB) - [ColorHexToRGB](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#ColorHexToRGB)
- [ColorRGBToHex](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ColorRGBToHex) - [ColorRGBToHex](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#ColorRGBToHex)
- [ToBool](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToBool) - [ToBool](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#ToBool)
- [ToBytes](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToBytes) - [ToBytes](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#ToBytes)
- [ToChar](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToChar) - [ToChar](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#ToChar)
- [ToInt](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToInt) - [ToChannel](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#ToChannel)
- [ToJson](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToJson) - [ToInt](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#ToInt)
- [ToString](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToString) - [ToJson](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#ToJson)
- [StructToMap](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#StructToMap) - [ToString](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#ToString)
- [StructToMap](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#StructToMap)
- [EncodeByte](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#EncodeByte)
- [DecodeByte](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#DecodeByte)
### Cryptor package is for data encryption and decryption. ### 2. Cryptor package is for data encryption and decryption.
```go ```go
import "github.com/duke-git/lancet/cryptor" import "github.com/duke-git/lancet/cryptor"
``` ```
#### Function list: #### Function list:
- [AesEcbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesEcbEncrypt) - [AesEcbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#AesEcbEncrypt)
- [AesEcbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesEcbDecrypt) - [AesEcbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#AesEcbDecrypt)
- [AesCbcEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCbcEncrypt) - [AesCbcEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#AesCbcEncrypt)
- [AesCbcDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCbcDecrypt) - [AesCbcDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#AesCbcDecrypt)
- [AesCtrCrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCtrCrypt) - [AesCtrCrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#AesCtrCrypt)
- [AesCfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCfbEncrypt) - [AesCfbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#AesCfbEncrypt)
- [AesCfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCfbDecrypt) - [AesCfbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#AesCfbDecrypt)
- [AesOfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesOfbEncrypt) - [AesOfbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#AesOfbEncrypt)
- [AesOfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesOfbDecrypt) - [AesOfbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#AesOfbDecrypt)
- [Base64StdEncode](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Base64StdEncode) - [Base64StdEncode](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Base64StdEncode)
- [Base64StdDecode](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Base64StdDecode) - [Base64StdDecode](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Base64StdDecode)
- [DesEcbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesEcbEncrypt) - [DesEcbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#DesEcbEncrypt)
- [DesEcbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesEcbDecrypt) - [DesEcbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#DesEcbDecrypt)
- [DesCbcEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCbcEncrypt) - [DesCbcEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#DesCbcEncrypt)
- [DesCbcDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCbcDecrypt) - [DesCbcDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#DesCbcDecrypt)
- [DesCtrCrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCtrCrypt) - [DesCtrCrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#DesCtrCrypt)
- [DesCfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCfbEncrypt) - [DesCfbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#DesCfbEncrypt)
- [DesCfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCfbDecrypt) - [DesCfbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#DesCfbDecrypt)
- [DesOfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesOfbEncrypt) - [DesOfbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#DesOfbEncrypt)
- [DesOfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesOfbDecrypt) - [DesOfbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#DesOfbDecrypt)
- [HmacMd5](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacMd5) - [HmacMd5](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#HmacMd5)
- [HmacSha1](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacSha1) - [HmacSha1](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#HmacSha1)
- [HmacSha256](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacSha256) - [HmacSha256](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#HmacSha256)
- [HmacSha512](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacSha512) - [HmacSha512](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#HmacSha512)
- [Md5String](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Md5String) - [Md5String](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Md5String)
- [Md5File](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Md5File) - [Md5File](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Md5File)
- [Sha1](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Sha1) - [Sha1](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Sha1)
- [Sha256](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Sha256) - [Sha256](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Sha256)
- [Sha512](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Sha512) - [Sha512](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#Sha512)
- [GenerateRsaKey](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#GenerateRsaKey) - [GenerateRsaKey](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#GenerateRsaKey)
- [RsaEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#RsaEncrypt) - [RsaEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#RsaEncrypt)
- [RsaDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#RsaDecrypt) - [RsaDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#RsaDecrypt)
### Datetime package supports date and time format and compare. ### 3. Datetime package supports date and time format and compare.
```go ```go
import "github.com/duke-git/lancet/datetime" import "github.com/duke-git/lancet/datetime"
``` ```
#### Function list: #### Function list:
- [AddDay](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddDay) - [AddDay](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#AddDay)
- [AddHour](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddHour) - [AddHour](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#AddHour)
- [AddMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddMinute) - [AddMinute](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#AddMinute)
- [BeginOfMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfMinute) - [BeginOfMinute](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfMinute)
- [BeginOfHour](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfHour) - [BeginOfHour](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfHour)
- [BeginOfDay](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfDay) - [BeginOfDay](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfDay)
- [BeginOfWeek](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfWeek) - [BeginOfWeek](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfWeek)
- [BeginOfMonth](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfMonth) - [BeginOfMonth](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfMonth)
- [BeginOfYear](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfYear) - [BeginOfYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfYear)
- [EndOfMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfMinute) - [EndOfMinute](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfMinute)
- [EndOfHour](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfHour) - [EndOfHour](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfHour)
- [EndOfDay](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfDay) - [EndOfDay](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfDay)
- [EndOfWeek](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfWeek) - [EndOfWeek](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfWeek)
- [EndOfMonth](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfMonth) - [EndOfMonth](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfMonth)
- [EndOfYear](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfYear) - [EndOfYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfYear)
- [GetNowDate](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNowDate) - [GetNowDate](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#GetNowDate)
- [GetNowTime](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNowTime) - [GetNowTime](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#GetNowTime)
- [GetNowDateTime](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNowDateTime) - [GetNowDateTime](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#GetNowDateTime)
- [GetZeroHourTimestamp](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetZeroHourTimestamp) - [GetZeroHourTimestamp](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#GetZeroHourTimestamp)
- [GetNightTimestamp](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNightTimestamp) - [GetNightTimestamp](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#GetNightTimestamp)
- [FormatTimeToStr](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#FormatTimeToStr) - [FormatTimeToStr](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#FormatTimeToStr)
- [FormatStrToTime](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#FormatStrToTime) - [FormatStrToTime](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#FormatStrToTime)
- [NewUnix](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#NewUnix)
- [NewUnixNow](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#NewUnixNow)
- [NewFormat](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#NewFormat)
- [NewISO8601](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#NewISO8601)
- [ToUnix](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#ToUnix)
- [ToFormat](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#ToFormat)
- [ToFormatForTpl](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#ToFormatForTpl)
- [ToIso8601](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#ToIso8601)
### Fileutil package implements some basic functions for file operations. ### 4. Fileutil package implements some basic functions for file operations.
```go ```go
import "github.com/duke-git/lancet/fileutil" import "github.com/duke-git/lancet/fileutil"
@@ -156,28 +167,29 @@ import "github.com/duke-git/lancet/fileutil"
#### Function list #### Function list
- [ClearFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#ClearFile) - [ClearFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#ClearFile)
- [CreateFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#CreateFile) - [CreateFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#CreateFile)
- [CopyFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#CopyFile) - [CreateDir](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#CreateDir)
- [FileMode](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#FileMode) - [CopyFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#CopyFile)
- [MiMeType](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#MiMeType) - [FileMode](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#FileMode)
- [IsExist](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#IsExist) - [MiMeType](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#MiMeType)
- [IsLink](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#IsLink) - [IsExist](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#IsExist)
- [IsDir](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#IsDir) - [IsLink](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#IsLink)
- [ListFileNames](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#ListFileNames) - [IsDir](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#IsDir)
- [RemoveFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#RemoveFile) - [ListFileNames](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#ListFileNames)
- [ReadFileToString](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#ReadFileToString) - [RemoveFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#RemoveFile)
- [ReadFileByLine](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#ReadFileByLine) - [ReadFileToString](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#ReadFileToString)
- [Zip](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#Zip) - [ReadFileByLine](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#ReadFileByLine)
- [UnZip](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#UnZip) - [Zip](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#Zip)
- [UnZip](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#UnZip)
### Formatter contains some functions for data formatting. ### 5. Formatter contains some functions for data formatting.
```go ```go
import "github.com/duke-git/lancet/formatter" import "github.com/duke-git/lancet/formatter"
``` ```
#### Function list: #### Function list:
- [Comma](https://github.com/duke-git/lancet/blob/main/docs/formatter.md#Comma) - [Comma](https://github.com/duke-git/lancet/blob/v1/docs/formatter.md#Comma)
### Function package can control the flow of function execution and support part of functional programming ### Function package can control the flow of function execution and support part of functional programming
@@ -186,117 +198,129 @@ import "github.com/duke-git/lancet/function"
``` ```
#### Function list: #### Function list:
- [After](https://github.com/duke-git/lancet/blob/main/docs/function.md#After) - [After](https://github.com/duke-git/lancet/blob/v1/docs/function.md#After)
- [Before](https://github.com/duke-git/lancet/blob/main/docs/function.md#Before) - [Before](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Before)
- [Curry](https://github.com/duke-git/lancet/blob/main/docs/function.md#Curry) - [Curry](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Curry)
- [Compose](https://github.com/duke-git/lancet/blob/main/docs/function.md#Compose) - [Compose](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Compose)
- [Debounced](https://github.com/duke-git/lancet/blob/main/docs/function.md#Debounced) - [Debounced](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Debounced)
- [Delay](https://github.com/duke-git/lancet/blob/main/docs/function.md#Delay) - [Delay](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Delay)
- [Watcher](https://github.com/duke-git/lancet/blob/main/docs/function.md#Watcher) - [Watcher](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Watcher)
### Mathutil package implements some functions for math calculation. ### 6. Mathutil package implements some functions for math calculation.
```go ```go
import "github.com/duke-git/lancet/mathutil" import "github.com/duke-git/lancet/mathutil"
``` ```
#### Function list: #### Function list:
- [Exponent](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Exponent) - [Exponent](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#Exponent)
- [Fibonacci](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Fibonacci) - [Fibonacci](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#Fibonacci)
- [Factorial](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Factorial) - [Factorial](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#Factorial)
- [Percent](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#Percent) - [Percent](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#Percent)
- [RoundToFloat](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#RoundToFloat) - [RoundToFloat](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#RoundToFloat)
- [RoundToString](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#RoundToString) - [RoundToString](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#RoundToString)
- [TruncRound](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#TruncRound) - [TruncRound](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#TruncRound)
### Netutil package contains functions to get net information and send http request. ### 7. Netutil package contains functions to get net information and send http request.
```go ```go
import "github.com/duke-git/lancet/netutil" import "github.com/duke-git/lancet/netutil"
``` ```
#### Function list: #### Function list:
- [ConvertMapToQueryString](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#ConvertMapToQueryString) - [ConvertMapToQueryString](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#ConvertMapToQueryString)
- [GetInternalIp](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetInternalIp) - [EncodeUrl](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#EncodeUrl)
- [GetIps](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetIps) - [GetInternalIp](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#GetInternalIp)
- [GetMacAddrs](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetMacAddrs) - [GetIps](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#GetIps)
- [GetPublicIpInfo](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetPublicIpInfo) - [GetMacAddrs](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#GetMacAddrs)
- [IsPublicIP](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#IsPublicIP) - [GetPublicIpInfo](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#GetPublicIpInfo)
- [HttpGet](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpGet) - [GetRequestPublicIp](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#GetRequestPublicIp)
- [HttpDelete](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpDelete) - [IsPublicIP](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#IsPublicIP)
- [HttpPost](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPost) - [IsInternalIP](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#IsInternalIP)
- [HttpPut](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPut) - [HttpGet](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#HttpGet)
- [HttpPatch](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPatch) - [HttpDelete](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#HttpDelete)
- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#ParseHttpResponse) - [HttpPost](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#HttpPost)
- [HttpPut](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#HttpPut)
- [HttpPatch](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#HttpPatch)
- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#ParseHttpResponse)
### Random package implements some basic functions to generate random int and string.
### 8. Random package implements some basic functions to generate random int and string.
```go ```go
import "github.com/duke-git/lancet/random" import "github.com/duke-git/lancet/random"
``` ```
#### Function list: #### Function list:
- [RandBytes](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandBytes) - [RandBytes](https://github.com/duke-git/lancet/blob/v1/docs/random.md#RandBytes)
- [RandInt](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandInt) - [RandInt](https://github.com/duke-git/lancet/blob/v1/docs/random.md#RandInt)
- [RandString](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandString) - [RandString](https://github.com/duke-git/lancet/blob/v1/docs/random.md#RandString)
- [UUIdV4](https://github.com/duke-git/lancet/blob/main/docs/random.md#UUIdV4) - [UUIdV4](https://github.com/duke-git/lancet/blob/v1/docs/random.md#UUIdV4)
### Retry package is for executing a function repeatedly until it was successful or canceled by the context. ### 9. Retry package is for executing a function repeatedly until it was successful or canceled by the context.
```go ```go
import "github.com/duke-git/lancet/retry" import "github.com/duke-git/lancet/retry"
``` ```
#### Function list: #### Function list:
- [Context](https://github.com/duke-git/lancet/blob/main/docs/retry.md#Context) - [Context](https://github.com/duke-git/lancet/blob/v1/docs/retry.md#Context)
- [Retry](https://github.com/duke-git/lancet/blob/main/docs/retry.md#Retry) - [Retry](https://github.com/duke-git/lancet/blob/v1/docs/retry.md#Retry)
- [RetryFunc](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryFunc) - [RetryFunc](https://github.com/duke-git/lancet/blob/v1/docs/retry.md#RetryFunc)
- [RetryDuration](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryDuration) - [RetryDuration](https://github.com/duke-git/lancet/blob/v1/docs/retry.md#RetryDuration)
- [RetryTimes](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryTimes) - [RetryTimes](https://github.com/duke-git/lancet/blob/v1/docs/retry.md#RetryTimes)
### Slice contains some functions to manipulate slice. ### 10. Slice contains some functions to manipulate slice.
```go ```go
import "github.com/duke-git/lancet/slice" import "github.com/duke-git/lancet/slice"
``` ```
#### Function list: #### Function list:
- [Contain](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Contain) - [AppendIfAbsent](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#AppendIfAbsent)
- [ContainSubSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ContainSubSlice) - [Contain](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Contain)
- [Chunk](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Chunk) - [ContainSubSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#ContainSubSlice)
- [Compact](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Compact) - [Chunk](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Chunk)
- [Concat](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Concat) - [Compact](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Compact)
- [Count](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Count) - [Concat](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Concat)
- [Difference](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Difference) - [Count](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Count)
- [DifferenceBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DifferenceBy) - [Difference](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Difference)
- [DeleteByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DeleteByIndex) - [DifferenceBy](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#DifferenceBy)
- [Drop](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Drop) - [DeleteByIndex](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#DeleteByIndex)
- [Every](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Every) - [Drop](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Drop)
- [Filter](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Filter) - [Every](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Every)
- [Find](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Find) - [Equal](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Equal)
- [FindLast](https://github.com/duke-git/lancet/blob/main/docs/slice.md#FindLast) - [EqualWith](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#EqualWith)
- [FlattenDeep](#FlattenDeep) - [Filter](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Filter)
- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ForEach) - [Find](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Find)
- [GroupBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#GroupBy) - [FindLast](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#FindLast)
- [IntSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#IntSlice) - [FlattenDeep](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#FlattenDeep)
- [InterfaceSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#InterfaceSlice) - [ForEach](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#ForEach)
- [Intersection](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Intersection) - [GroupBy](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#GroupBy)
- [InsertByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice.md#InsertByIndex) - [IntSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#IntSlice)
- [Map](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Map) - [IndexOf](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#IndexOf)
- [ReverseSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ReverseSlice) - [LastIndexOf](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#LastIndexOf)
- [Reduce](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Reduce) - [InterfaceSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#InterfaceSlice)
- [Shuffle](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Shuffle) - [Intersection](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Intersection)
- [SortByField](https://github.com/duke-git/lancet/blob/main/docs/slice.md#SortByField) - [InsertByIndex](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#InsertByIndex)
- [Some](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Some) - [Map](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Map)
- [StringSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#StringSlice) - [ReverseSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#ReverseSlice)
- [Unique](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Unique) - [Reduce](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Reduce)
- [Union](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Union) - [Shuffle](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Shuffle)
- [UpdateByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice.md#UpdateByIndex) - [SortByField](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#SortByField)
- [Without](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Without) - [Some](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Some)
- [StringSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#StringSlice)
- [ToSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#ToSlice)
- [ToSlicePointer](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#ToSlice)
- [Unique](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Unique)
- [UniqueBy](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#UniqueBy)
- [Union](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Union)
- [UpdateByIndex](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#UpdateByIndex)
- [Without](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Without)
### Strutil package contains some functions to manipulate string. ### 11. Strutil package contains some functions to manipulate string.
```go ```go
import "github.com/duke-git/lancet/strutil" import "github.com/duke-git/lancet/strutil"
@@ -304,72 +328,75 @@ import "github.com/duke-git/lancet/strutil"
#### Function list: #### Function list:
- [After](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#After) - [After](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#After)
- [AfterLast](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#AfterLast) - [AfterLast](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#AfterLast)
- [Before](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Before) - [Before](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Before)
- [BeforeLast](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#BeforeLast) - [BeforeLast](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#BeforeLast)
- [CamelCase](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#CamelCase) - [CamelCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#CamelCase)
- [Capitalize](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Capitalize) - [Capitalize](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Capitalize)
- [IsString](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#IsString) - [IsString](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#IsString)
- [KebabCase](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#KebabCase) - [KebabCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#KebabCase)
- [LowerFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#LowerFirst) - [LowerFirst](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#LowerFirst)
- [UpperFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#UpperFirst) - [UpperFirst](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#UpperFirst)
- [PadEnd](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#PadEnd) - [PadEnd](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#PadEnd)
- [PadStart](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#PadStart) - [PadStart](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#PadStart)
- [ReverseStr](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#ReverseStr) - [Reverse](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Reverse)
- [SnakeCase](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#SnakeCase) - [SnakeCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#SnakeCase)
- [Wrap](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Wrap) - [SplitEx](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#SplitEx)
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Unwrap) - [Wrap](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Wrap)
- [Unwrap](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Unwrap)
### System package contain some functions about os, runtime, shell command. ### 12. System package contain some functions about os, runtime, shell command.
```go ```go
import "github.com/duke-git/lancet/system" import "github.com/duke-git/lancet/system"
``` ```
#### Function list: #### Function list:
- [IsWindows](https://github.com/duke-git/lancet/blob/main/docs/system.md#IsWindows) - [IsWindows](https://github.com/duke-git/lancet/blob/v1/docs/system.md#IsWindows)
- [IsLinux](https://github.com/duke-git/lancet/blob/main/docs/system.md#IsLinux) - [IsLinux](https://github.com/duke-git/lancet/blob/v1/docs/system.md#IsLinux)
- [IsMac](https://github.com/duke-git/lancet/blob/main/docs/system.md#IsMac) - [IsMac](https://github.com/duke-git/lancet/blob/v1/docs/system.md#IsMac)
- [GetOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system.md#GetOsEnv) - [GetOsEnv](https://github.com/duke-git/lancet/blob/v1/docs/system.md#GetOsEnv)
- [SetOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system.md#SetOsEnv) - [SetOsEnv](https://github.com/duke-git/lancet/blob/v1/docs/system.md#SetOsEnv)
- [RemoveOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system.md#RemoveOsEnv) - [RemoveOsEnv](https://github.com/duke-git/lancet/blob/v1/docs/system.md#RemoveOsEnv)
- [CompareOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system.md#CompareOsEnv) - [CompareOsEnv](https://github.com/duke-git/lancet/blob/v1/docs/system.md#CompareOsEnv)
- [ExecCommand](https://github.com/duke-git/lancet/blob/main/docs/system.md#ExecCommand) - [ExecCommand](https://github.com/duke-git/lancet/blob/v1/docs/system.md#ExecCommand)
- [GetOsBits](https://github.com/duke-git/lancet/blob/v1/docs/system.md#GetOsBits)
### Validator package contains some functions for data validation. ### 13. Validator package contains some functions for data validation.
```go ```go
import "github.com/duke-git/lancet/validator" import "github.com/duke-git/lancet/validator"
``` ```
#### Function list: #### Function list:
- [ContainChinese](https://github.com/duke-git/lancet/blob/main/docs/validator.md#ContainChinese) - [ContainChinese](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#ContainChinese)
- [ContainLetter](https://github.com/duke-git/lancet/blob/main/docs/validator.md#ContainLetter) - [ContainLetter](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#ContainLetter)
- [ContainLower](https://github.com/duke-git/lancet/blob/main/docs/validator.md#ContainLower) - [ContainLower](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#ContainLower)
- [ContainUpper](https://github.com/duke-git/lancet/blob/main/docs/validator.md#ContainUpper) - [ContainUpper](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#ContainUpper)
- [IsAlpha](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsAlpha) - [IsAlpha](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsAlpha)
- [IsAllUpper](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsAllUpper) - [IsAllUpper](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsAllUpper)
- [IsAllLower](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsAllLower) - [IsAllLower](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsAllLower)
- [IsBase64](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsBase64) - [IsBase64](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsBase64)
- [IsChineseMobile](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsChineseMobile) - [IsChineseMobile](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsChineseMobile)
- [IsChineseIdNum](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsChineseIdNum) - [IsChineseIdNum](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsChineseIdNum)
- [IsChinesePhone](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsChinesePhone) - [IsChinesePhone](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsChinesePhone)
- [IsCreditCard](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsCreditCard) - [IsCreditCard](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsCreditCard)
- [IsDns](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsDns) - [IsDns](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsDns)
- [IsEmail](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsEmail) - [IsEmail](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsEmail)
- [IsEmptyString](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsEmptyString) - [IsEmptyString](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsEmptyString)
- [IsFloatStr](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsFloatStr) - [IsFloatStr](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsFloatStr)
- [IsNumberStr](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsNumberStr) - [IsNumberStr](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsNumberStr)
- [IsJSON](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsJSON) - [IsJSON](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsJSON)
- [IsRegexMatch](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsRegexMatch) - [IsRegexMatch](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsRegexMatch)
- [IsIntStr](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsIntStr) - [IsIntStr](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsIntStr)
- [IsIp](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsIp) - [IsIp](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsIp)
- [IsIpV4](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsIpV4) - [IsIpV4](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsIpV4)
- [IsIpV6](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsIpV6) - [IsIpV6](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsIpV6)
- [IsStrongPassword](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsStrongPassword) - [IsStrongPassword](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsStrongPassword)
- [IsUrl](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsUrl) - [IsUrl](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsUrl)
- [IsWeakPassword](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsWeakPassword) - [IsWeakPassword](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsWeakPassword)
- [IsZeroValue](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsZeroValue)
## How to Contribute ## How to Contribute

View File

@@ -3,13 +3,13 @@
<br/> <br/>
![Go version](https://img.shields.io/badge/go-%3E%3D1.16<recommend>-9cf) ![Go version](https://img.shields.io/badge/go-v1.16-9cf)
[![Release](https://img.shields.io/badge/release-1.2.6-green.svg)](https://github.com/duke-git/lancet/releases) [![Release](https://img.shields.io/badge/release-1.3.2-green.svg)](https://github.com/duke-git/lancet/releases)
[![GoDoc](https://godoc.org/github.com//duke-git/lancet?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet) [![GoDoc](https://godoc.org/github.com//duke-git/lancet?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet)
[![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet)](https://goreportcard.com/report/github.com/duke-git/lancet) [![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet)](https://goreportcard.com/report/github.com/duke-git/lancet)
[![test](https://github.com/duke-git/lancet/actions/workflows/codecov.yml/badge.svg?branch=main&event=push)](https://github.com/duke-git/lancet/actions/workflows/codecov.yml) [![test](https://github.com/duke-git/lancet/actions/workflows/codecov.yml/badge.svg?branch=main&event=push)](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
[![codecov](https://codecov.io/gh/duke-git/lancet/branch/main/graph/badge.svg?token=FC48T1F078)](https://codecov.io/gh/duke-git/lancet) [![codecov](https://codecov.io/gh/duke-git/lancet/branch/main/graph/badge.svg?token=FC48T1F078)](https://codecov.io/gh/duke-git/lancet)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/duke-git/lancet/blob/main/LICENSE) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/duke-git/lancet/blob/v1/LICENSE)
</div> </div>
@@ -24,7 +24,7 @@
## 特性 ## 特性
- 👏 全面、高效、可复用 - 👏 全面、高效、可复用
- 💪 180+常用go工具函数支持string、slice、datetime、net、crypt... - 💪 200+常用go工具函数支持string、slice、datetime、net、crypt...
- 💅 只依赖go标准库 - 💅 只依赖go标准库
- 🌍 所有导出函数单元测试覆盖率100% - 🌍 所有导出函数单元测试覆盖率100%
@@ -44,7 +44,7 @@ import "github.com/duke-git/lancet/strutil"
## 例子 ## 例子
此处以字符串工具函数ReverseStr逆序字符串为例需要导入strutil包: 此处以字符串工具函数Reverse逆序字符串为例需要导入strutil包:
```go ```go
package main package main
@@ -56,99 +56,109 @@ import (
func main() { func main() {
s := "hello" s := "hello"
rs := strutil.ReverseStr(s) rs := strutil.Reverse(s)
fmt.Println(rs) //olleh fmt.Println(rs) //olleh
} }
``` ```
## API文档 ## API文档
### convertor转换器包支持一些常见的数据类型转换。 ### 1. convertor转换器包支持一些常见的数据类型转换。
```go ```go
import "github.com/duke-git/lancet/convertor" import "github.com/duke-git/lancet/convertor"
``` ```
#### 函数列表: #### 函数列表:
- [ColorHexToRGB](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ColorHexToRGB) - [ColorHexToRGB](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#ColorHexToRGB)
- [ColorRGBToHex](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ColorRGBToHex) - [ColorRGBToHex](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#ColorRGBToHex)
- [ToBool](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToBool) - [ToBool](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#ToBool)
- [ToBytes](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToBytes) - [ToBytes](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#ToBytes)
- [ToChar](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToChar) - [ToChar](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#ToChar)
- [ToInt](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToInt) - [ToChannel](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#ToChannel)
- [ToJson](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToJson) - [ToInt](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#ToInt)
- [ToString](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToString) - [ToJson](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#ToJson)
- [StructToMap](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#StructToMap) - [ToString](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#ToString)
- [StructToMap](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#StructToMap)
- [EncodeByte](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#EncodeByte)
- [DecodeByte](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#DecodeByte)
### cryptor加密包支持数据加密和解密获取md5hash值。支持base64, md5, hmac, aes, des, rsa。 ### 2. cryptor加密包支持数据加密和解密获取md5hash值。支持base64, md5, hmac, aes, des, rsa。
```go ```go
import "github.com/duke-git/lancet/cryptor" import "github.com/duke-git/lancet/cryptor"
``` ```
#### 函数列表: #### 函数列表:
- [AesEcbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesEcbEncrypt) - [AesEcbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#AesEcbEncrypt)
- [AesEcbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesEcbDecrypt) - [AesEcbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#AesEcbDecrypt)
- [AesCbcEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCbcEncrypt) - [AesCbcEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#AesCbcEncrypt)
- [AesCbcDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCbcDecrypt) - [AesCbcDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#AesCbcDecrypt)
- [AesCtrCrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCtrCrypt) - [AesCtrCrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#AesCtrCrypt)
- [AesCfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCfbEncrypt) - [AesCfbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#AesCfbEncrypt)
- [AesCfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCfbDecrypt) - [AesCfbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#AesCfbDecrypt)
- [AesOfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesOfbEncrypt) - [AesOfbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#AesOfbEncrypt)
- [AesOfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesOfbDecrypt) - [AesOfbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#AesOfbDecrypt)
- [Base64StdEncode](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Base64StdEncode) - [Base64StdEncode](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Base64StdEncode)
- [Base64StdDecode](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Base64StdDecode) - [Base64StdDecode](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Base64StdDecode)
- [DesEcbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesEcbEncrypt) - [DesEcbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#DesEcbEncrypt)
- [DesEcbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesEcbDecrypt) - [DesEcbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#DesEcbDecrypt)
- [DesCbcEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCbcEncrypt) - [DesCbcEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#DesCbcEncrypt)
- [DesCbcDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCbcDecrypt) - [DesCbcDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#DesCbcDecrypt)
- [DesCtrCrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCtrCrypt) - [DesCtrCrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#DesCtrCrypt)
- [DesCfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCfbEncrypt) - [DesCfbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#DesCfbEncrypt)
- [DesCfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCfbDecrypt) - [DesCfbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#DesCfbDecrypt)
- [DesOfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesOfbEncrypt) - [DesOfbEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#DesOfbEncrypt)
- [DesOfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesOfbDecrypt) - [DesOfbDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#DesOfbDecrypt)
- [HmacMd5](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacMd5) - [HmacMd5](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#HmacMd5)
- [HmacSha1](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacSha1) - [HmacSha1](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#HmacSha1)
- [HmacSha256](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacSha256) - [HmacSha256](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#HmacSha256)
- [HmacSha512](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacSha512) - [HmacSha512](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#HmacSha512)
- [Md5String](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Md5String) - [Md5String](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Md5String)
- [Md5File](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Md5File) - [Md5File](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Md5File)
- [Sha1](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Sha1) - [Sha1](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Sha1)
- [Sha256](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Sha256) - [Sha256](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Sha256)
- [Sha512](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Sha512) - [Sha512](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#Sha512)
- [GenerateRsaKey](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#GenerateRsaKey) - [GenerateRsaKey](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#GenerateRsaKey)
- [RsaEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#RsaEncrypt) - [RsaEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#RsaEncrypt)
- [RsaDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#RsaDecrypt) - [RsaDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#RsaDecrypt)
### datetime日期时间处理包格式化日期比较日期。 ### 3. datetime日期时间处理包格式化日期比较日期。
```go ```go
import "github.com/duke-git/lancet/datetime" import "github.com/duke-git/lancet/datetime"
``` ```
#### 函数列表: #### 函数列表:
- [AddDay](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddDay) - [AddDay](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#AddDay)
- [AddHour](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddHour) - [AddHour](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#AddHour)
- [AddMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddMinute) - [AddMinute](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#AddMinute)
- [BeginOfMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfMinute) - [BeginOfMinute](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfMinute)
- [BeginOfHour](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfHour) - [BeginOfHour](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfHour)
- [BeginOfDay](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfDay) - [BeginOfDay](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfDay)
- [BeginOfWeek](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfWeek) - [BeginOfWeek](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfWeek)
- [BeginOfMonth](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfMonth) - [BeginOfMonth](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfMonth)
- [BeginOfYear](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#BeginOfYear) - [BeginOfYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfYear)
- [EndOfMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfMinute) - [EndOfMinute](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfMinute)
- [EndOfHour](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfHour) - [EndOfHour](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfHour)
- [EndOfDay](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfDay) - [EndOfDay](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfDay)
- [EndOfWeek](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfWeek) - [EndOfWeek](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfWeek)
- [EndOfMonth](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfMonth) - [EndOfMonth](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfMonth)
- [EndOfYear](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#EndOfYear) - [EndOfYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#EndOfYear)
- [GetNowDate](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNowDate) - [GetNowDate](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#GetNowDate)
- [GetNowTime](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNowTime) - [GetNowTime](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#GetNowTime)
- [GetNowDateTime](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNowDateTime) - [GetNowDateTime](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#GetNowDateTime)
- [GetZeroHourTimestamp](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetZeroHourTimestamp) - [GetZeroHourTimestamp](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#GetZeroHourTimestamp)
- [GetNightTimestamp](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNightTimestamp) - [GetNightTimestamp](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#GetNightTimestamp)
- [FormatTimeToStr](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#FormatTimeToStr) - [FormatTimeToStr](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#FormatTimeToStr)
- [FormatStrToTime](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#FormatStrToTime) - [FormatStrToTime](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#FormatStrToTime)
- [NewUnix](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#NewUnix)
### fileutil包支持文件基本操作。 - [NewUnixNow](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#NewUnixNow)
- [NewFormat](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#NewFormat)
- [NewISO8601](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#NewISO8601)
- [ToUnix](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#ToUnix)
- [ToFormat](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#ToFormat)
- [ToFormatForTpl](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#ToFormatForTpl)
- [ToIso8601](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#ToIso8601)
### 4. fileutil包支持文件基本操作。
```go ```go
import "github.com/duke-git/lancet/fileutil" import "github.com/duke-git/lancet/fileutil"
@@ -156,28 +166,29 @@ import "github.com/duke-git/lancet/fileutil"
#### 函数列表: #### 函数列表:
- [ClearFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#ClearFile) - [ClearFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#ClearFile)
- [CreateFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#CreateFile) - [CreateFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#CreateFile)
- [CopyFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#CopyFile) - [CreateDir](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#CreateDir)
- [FileMode](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#FileMode) - [CopyFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#CopyFile)
- [MiMeType](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#MiMeType) - [FileMode](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#FileMode)
- [IsExist](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#IsExist) - [MiMeType](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#MiMeType)
- [IsLink](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#IsLink) - [IsExist](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#IsExist)
- [IsDir](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#IsDir) - [IsLink](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#IsLink)
- [ListFileNames](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#ListFileNames) - [IsDir](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#IsDir)
- [RemoveFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#RemoveFile) - [ListFileNames](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#ListFileNames)
- [ReadFileToString](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#ReadFileToString) - [RemoveFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#RemoveFile)
- [ReadFileByLine](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#ReadFileByLine) - [ReadFileToString](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#ReadFileToString)
- [Zip](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#Zip) - [ReadFileByLine](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#ReadFileByLine)
- [UnZip](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#UnZip) - [Zip](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#Zip)
- [UnZip](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#UnZip)
### formatter格式化器包含一些数据格式化处理方法。 ### 5. formatter格式化器包含一些数据格式化处理方法。
```go ```go
import "github.com/duke-git/lancet/formatter" import "github.com/duke-git/lancet/formatter"
``` ```
#### 函数列表: #### 函数列表:
- [Comma](https://github.com/duke-git/lancet/blob/main/docs/formatter_zh-CN.md#Comma) - [Comma](https://github.com/duke-git/lancet/blob/v1/docs/formatter_zh-CN.md#Comma)
### function函数包控制函数执行流程包含部分函数式编程。 ### function函数包控制函数执行流程包含部分函数式编程。
@@ -187,116 +198,127 @@ import "github.com/duke-git/lancet/function"
``` ```
#### 函数列表: #### 函数列表:
- [After](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#After) - [After](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#After)
- [Before](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Before) - [Before](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Before)
- [Curry](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Curry) - [Curry](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Curry)
- [Compose](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Compose) - [Compose](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Compose)
- [Debounced](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Debounced) - [Debounced](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Debounced)
- [Delay](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Delay) - [Delay](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Delay)
- [Watcher](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Watcher) - [Watcher](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Watcher)
### mathutil包实现了一些数学计算的函数。 ### 6. mathutil包实现了一些数学计算的函数。
```go ```go
import "github.com/duke-git/lancet/mathutil" import "github.com/duke-git/lancet/mathutil"
``` ```
#### Function list: #### Function list:
- [Exponent](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Exponent) - [Exponent](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#Exponent)
- [Fibonacci](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Fibonacci) - [Fibonacci](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#Fibonacci)
- [Factorial](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Factorial) - [Factorial](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#Factorial)
- [Percent](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#Percent) - [Percent](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#Percent)
- [RoundToFloat](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#RoundToFloat) - [RoundToFloat](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#RoundToFloat)
- [RoundToString](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#RoundToString) - [RoundToString](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#RoundToString)
- [TruncRound](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#TruncRound) - [TruncRound](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#TruncRound)
### netutil网络包支持获取ip地址发送http请求。 ### 7. netutil网络包支持获取ip地址发送http请求。
```go ```go
import "github.com/duke-git/lancet/netutil" import "github.com/duke-git/lancet/netutil"
``` ```
#### 函数列表: #### 函数列表:
- [ConvertMapToQueryString](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#ConvertMapToQueryString) - [ConvertMapToQueryString](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#ConvertMapToQueryString)
- [GetInternalIp](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#GetInternalIp) - [EncodeUrl](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#EncodeUrl)
- [GetIps](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetIps) - [GetInternalIp](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#GetInternalIp)
- [GetMacAddrs](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetMacAddrs) - [GetIps](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#GetIps)
- [GetPublicIpInfo](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#GetPublicIpInfo) - [GetMacAddrs](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#GetMacAddrs)
- [IsPublicIP](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#IsPublicIP) - [GetPublicIpInfo](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#GetPublicIpInfo)
- [HttpGet](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpGet) - [GetRequestPublicIp](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#GetRequestPublicIp)
- [HttpDelete](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpDelete) - [IsPublicIP](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#IsPublicIP)
- [HttpPost](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPost) - [IsInternalIP](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#IsInternalIP)
- [HttpPut](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPut) - [HttpGet](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#HttpGet)
- [HttpPatch](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPatch) - [HttpDelete](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#HttpDelete)
- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#ParseHttpResponse) - [HttpPost](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#HttpPost)
- [HttpPut](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#HttpPut)
- [HttpPatch](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#HttpPatch)
- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#ParseHttpResponse)
### random随机数生成器包可以生成随机[]bytes, int, string。 ### 8. random随机数生成器包可以生成随机[]bytes, int, string。
```go ```go
import "github.com/duke-git/lancet/random" import "github.com/duke-git/lancet/random"
``` ```
#### 函数列表: #### 函数列表:
- [RandBytes](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandBytes) - [RandBytes](https://github.com/duke-git/lancet/blob/v1/docs/random_zh-CN.md#RandBytes)
- [RandInt](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandInt) - [RandInt](https://github.com/duke-git/lancet/blob/v1/docs/random_zh-CN.md#RandInt)
- [RandString](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandString) - [RandString](https://github.com/duke-git/lancet/blob/v1/docs/random_zh-CN.md#RandString)
- [UUIdV4](https://github.com/duke-git/lancet/blob/main/docs/random.md#UUIdV4) - [UUIdV4](https://github.com/duke-git/lancet/blob/v1/docs/random.md#UUIdV4)
### retry重试执行函数直到函数运行成功或被context cancel。 ### 9. retry重试执行函数直到函数运行成功或被context cancel。
```go ```go
import "github.com/duke-git/lancet/retry" import "github.com/duke-git/lancet/retry"
``` ```
#### 函数列表: #### 函数列表:
- [Context](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#Context) - [Context](https://github.com/duke-git/lancet/blob/v1/docs/retry_zh-CN.md#Context)
- [Retry](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#Retry) - [Retry](https://github.com/duke-git/lancet/blob/v1/docs/retry_zh-CN.md#Retry)
- [RetryFunc](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryFunc) - [RetryFunc](https://github.com/duke-git/lancet/blob/v1/docs/retry_zh-CN.md#RetryFunc)
- [RetryDuration](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryDuration) - [RetryDuration](https://github.com/duke-git/lancet/blob/v1/docs/retry_zh-CN.md#RetryDuration)
- [RetryTimes](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryTimes) - [RetryTimes](https://github.com/duke-git/lancet/blob/v1/docs/retry_zh-CN.md#RetryTimes)
### slice包包含操作切片的方法集合。 ### 10. slice包包含操作切片的方法集合。
```go ```go
import "github.com/duke-git/lancet/slice" import "github.com/duke-git/lancet/slice"
``` ```
#### 函数列表: #### 函数列表:
- [Contain](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Contain) - [AppendIfAbsent](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#AppendIfAbsent)
- [ContainSubSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ContainSubSlice) - [Contain](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Contain)
- [Chunk](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Chunk) - [ContainSubSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#ContainSubSlice)
- [Compact](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Compact) - [Chunk](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Chunk)
- [Concat](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Concat) - [Compact](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Compact)
- [Count](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Count) - [Concat](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Concat)
- [Difference](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Difference) - [Count](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Count)
- [DifferenceBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#DifferenceBy) - [Difference](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Difference)
- [DeleteByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#DeleteByIndex) - [DifferenceBy](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#DifferenceBy)
- [Drop](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Drop) - [DeleteByIndex](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#DeleteByIndex)
- [Every](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Every) - [Drop](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Drop)
- [Filter](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Filter) - [Every](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Every)
- [Find](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Find) - [Equal](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Equal)
- [FindLast](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#FindLast) - [EqualWith](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#EqualWith)
- [FlattenDeep](#FlattenDeep) - [Filter](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Filter)
- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ForEach) - [Find](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Find)
- [GroupBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#GroupBy) - [FindLast](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#FindLast)
- [IntSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#IntSlice) - [FlattenDeep](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#FlattenDeep)
- [InterfaceSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#InterfaceSlice) - [ForEach](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#ForEach)
- [Intersection](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Intersection) - [GroupBy](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#GroupBy)
- [InsertByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#InsertByIndex) - [IntSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#IntSlice)
- [Map](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Map) - [IndexOf](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#IndexOf)
- [ReverseSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ReverseSlice) - [LastIndexOf](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#LastIndexOf)
- [Reduce](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Reduce) - [InterfaceSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#InterfaceSlice)
- [Shuffle](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Shuffle) - [Intersection](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Intersection)
- [SortByField](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#SortByField) - [InsertByIndex](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#InsertByIndex)
- [Some](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Some) - [Map](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Map)
- [StringSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#StringSlice) - [ReverseSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#ReverseSlice)
- [Unique](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Unique) - [Reduce](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Reduce)
- [Union](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Union) - [Shuffle](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Shuffle)
- [UpdateByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#UpdateByIndex) - [SortByField](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#SortByField)
- [Without](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Without) - [Some](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Some)
- [StringSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#StringSlice)
- [ToSlice](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#ToSlice)
- [ToSlicePointer](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#ToSlice)
- [Unique](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Unique)
- [UniqueBy](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#UniqueBy)
- [Union](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Union)
- [UpdateByIndex](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#UpdateByIndex)
- [Without](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Without)
### strutil包含处理字符串的相关函数。 ### 12. strutil包含处理字符串的相关函数。
```go ```go
import "github.com/duke-git/lancet/strutil" import "github.com/duke-git/lancet/strutil"
@@ -304,73 +326,76 @@ import "github.com/duke-git/lancet/strutil"
#### 函数列表: #### 函数列表:
- [After](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#After) - [After](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#After)
- [AfterLast](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#AfterLast) - [AfterLast](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#AfterLast)
- [Before](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Before) - [Before](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Before)
- [BeforeLast](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#BeforeLast) - [BeforeLast](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#BeforeLast)
- [CamelCase](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#CamelCase) - [CamelCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#CamelCase)
- [Capitalize](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Capitalize) - [Capitalize](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Capitalize)
- [IsString](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#IsString) - [IsString](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#IsString)
- [KebabCase](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#KebabCase) - [KebabCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#KebabCase)
- [LowerFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#LowerFirst) - [LowerFirst](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#LowerFirst)
- [UpperFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#UpperFirst) - [UpperFirst](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#UpperFirst)
- [PadEnd](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#PadEnd) - [PadEnd](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#PadEnd)
- [PadStart](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#PadStart) - [PadStart](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#PadStart)
- [ReverseStr](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#ReverseStr) - [Reverse](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Reverse)
- [SnakeCase](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#SnakeCase) - [SnakeCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#SnakeCase)
- [Wrap](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Wrap) - [SplitEx](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#SplitEx)
- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Unwrap) - [Wrap](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Wrap)
- [Unwrap](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Unwrap)
### system包含os, runtime, shell command相关函数。 ### 13. system包含os, runtime, shell command相关函数。
```go ```go
import "github.com/duke-git/lancet/system" import "github.com/duke-git/lancet/system"
``` ```
#### 函数列表: #### 函数列表:
- [IsWindows](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#IsWindows) - [IsWindows](https://github.com/duke-git/lancet/blob/v1/docs/system_zh-CN.md#IsWindows)
- [IsLinux](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#IsLinux) - [IsLinux](https://github.com/duke-git/lancet/blob/v1/docs/system_zh-CN.md#IsLinux)
- [IsMac](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#IsMac) - [IsMac](https://github.com/duke-git/lancet/blob/v1/docs/system_zh-CN.md#IsMac)
- [GetOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#GetOsEnv) - [GetOsEnv](https://github.com/duke-git/lancet/blob/v1/docs/system_zh-CN.md#GetOsEnv)
- [SetOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#SetOsEnv) - [SetOsEnv](https://github.com/duke-git/lancet/blob/v1/docs/system_zh-CN.md#SetOsEnv)
- [RemoveOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#RemoveOsEnv) - [RemoveOsEnv](https://github.com/duke-git/lancet/blob/v1/docs/system_zh-CN.md#RemoveOsEnv)
- [CompareOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#CompareOsEnv) - [CompareOsEnv](https://github.com/duke-git/lancet/blob/v1/docs/system_zh-CN.md#CompareOsEnv)
- [ExecCommand](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#ExecCommand) - [ExecCommand](https://github.com/duke-git/lancet/blob/v1/docs/system_zh-CN.md#ExecCommand)
- [GetOsBits](https://github.com/duke-git/lancet/blob/v1/docs/system_zh-CN.md#GetOsBits)
### validator验证器包包含常用字符串格式验证函数。 ### 14. validator验证器包包含常用字符串格式验证函数。
```go ```go
import "github.com/duke-git/lancet/validator" import "github.com/duke-git/lancet/validator"
``` ```
#### 函数列表: #### 函数列表:
- [ContainChinese](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#ContainChinese) - [ContainChinese](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#ContainChinese)
- [ContainLetter](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#ContainLetter) - [ContainLetter](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#ContainLetter)
- [ContainLower](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#ContainLower) - [ContainLower](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#ContainLower)
- [ContainUpper](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#ContainUpper) - [ContainUpper](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#ContainUpper)
- [IsAlpha](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsAlpha) - [IsAlpha](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsAlpha)
- [IsAllUpper](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsAllUpper) - [IsAllUpper](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsAllUpper)
- [IsAllLower](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsAllLower) - [IsAllLower](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsAllLower)
- [IsBase64](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsBase64) - [IsBase64](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsBase64)
- [IsChineseMobile](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsChineseMobile) - [IsChineseMobile](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsChineseMobile)
- [IsChineseIdNum](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsChineseIdNum) - [IsChineseIdNum](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsChineseIdNum)
- [IsChinesePhone](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsChinesePhone) - [IsChinesePhone](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsChinesePhone)
- [IsCreditCard](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsCreditCard) - [IsCreditCard](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsCreditCard)
- [IsDns](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsDns) - [IsDns](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsDns)
- [IsEmail](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsEmail) - [IsEmail](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsEmail)
- [IsEmptyString](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsEmptyString) - [IsEmptyString](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsEmptyString)
- [IsFloatStr](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsFloatStr) - [IsFloatStr](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsFloatStr)
- [IsNumberStr](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsNumberStr) - [IsNumberStr](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsNumberStr)
- [IsJSON](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsJSON) - [IsJSON](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsJSON)
- [IsRegexMatch](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsRegexMatch) - [IsRegexMatch](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsRegexMatch)
- [IsIntStr](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsIntStr) - [IsIntStr](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsIntStr)
- [IsIp](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsIp) - [IsIp](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsIp)
- [IsIpV4](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsIpV4) - [IsIpV4](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsIpV4)
- [IsIpV6](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsIpV6) - [IsIpV6](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsIpV6)
- [IsStrongPassword](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsStrongPassword) - [IsStrongPassword](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsStrongPassword)
- [IsUrl](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsUrl) - [IsUrl](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsUrl)
- [IsWeakPassword](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsWeakPassword) - [IsWeakPassword](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsWeakPassword)
- [IsZeroValue](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsZeroValue)
## 如何贡献代码 ## 如何贡献代码

View File

@@ -6,9 +6,11 @@ package convertor
import ( import (
"bytes" "bytes"
"encoding/binary"
"encoding/gob" "encoding/gob"
"encoding/json" "encoding/json"
"fmt" "fmt"
"math"
"reflect" "reflect"
"regexp" "regexp"
"strconv" "strconv"
@@ -21,14 +23,44 @@ func ToBool(s string) (bool, error) {
} }
// ToBytes convert interface to bytes // ToBytes convert interface to bytes
func ToBytes(data interface{}) ([]byte, error) { func ToBytes(value interface{}) ([]byte, error) {
var buf bytes.Buffer v := reflect.ValueOf(value)
enc := gob.NewEncoder(&buf)
err := enc.Encode(data) switch value.(type) {
if err != nil { case int, int8, int16, int32, int64:
return nil, err number := v.Int()
buf := bytes.NewBuffer([]byte{})
buf.Reset()
err := binary.Write(buf, binary.BigEndian, number)
return buf.Bytes(), err
case uint, uint8, uint16, uint32, uint64:
number := v.Uint()
buf := bytes.NewBuffer([]byte{})
buf.Reset()
err := binary.Write(buf, binary.BigEndian, number)
return buf.Bytes(), err
case float32:
number := float32(v.Float())
bits := math.Float32bits(number)
bytes := make([]byte, 4)
binary.BigEndian.PutUint32(bytes, bits)
return bytes, nil
case float64:
number := v.Float()
bits := math.Float64bits(number)
bytes := make([]byte, 8)
binary.BigEndian.PutUint64(bytes, bits)
return bytes, nil
case bool:
return strconv.AppendBool([]byte{}, v.Bool()), nil
case string:
return []byte(v.String()), nil
case []byte:
return v.Bytes(), nil
default:
newValue, err := json.Marshal(value)
return newValue, err
} }
return buf.Bytes(), nil
} }
// ToChar convert string to char slice // ToChar convert string to char slice
@@ -198,3 +230,35 @@ func ColorRGBToHex(red, green, blue int) string {
return "#" + r + g + b return "#" + r + g + b
} }
// ToChannel convert a array of elements to a read-only channels
func ToChannel(array []interface{}) <-chan interface{} {
ch := make(chan interface{})
go func() {
for _, item := range array {
ch <- item
}
close(ch)
}()
return ch
}
// EncodeByte encode data to byte
func EncodeByte(data interface{}) ([]byte, error) {
buffer := bytes.NewBuffer(nil)
encoder := gob.NewEncoder(buffer)
err := encoder.Encode(data)
if err != nil {
return nil, err
}
return buffer.Bytes(), nil
}
// DecodeByte decode byte data to target object
func DecodeByte(data []byte, target interface{}) error {
buffer := bytes.NewBuffer(data)
decoder := gob.NewDecoder(buffer)
return decoder.Decode(target)
}

View File

@@ -42,14 +42,21 @@ func TestToBytes(t *testing.T) {
"1", "1",
} }
expected := [][]byte{ expected := [][]byte{
{3, 4, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0},
{3, 2, 0, 0}, {102, 97, 108, 115, 101},
{4, 12, 0, 1, 49}, {49},
} }
for i := 0; i < len(cases); i++ { for i := 0; i < len(cases); i++ {
actual, _ := ToBytes(cases[i]) actual, _ := ToBytes(cases[i])
assert.Equal(expected[i], actual) assert.Equal(expected[i], actual)
} }
bytesData, err := ToBytes("abc")
if err != nil {
t.Error(err)
t.Fail()
}
assert.Equal("abc", ToString(bytesData))
} }
func TestToInt(t *testing.T) { func TestToInt(t *testing.T) {
@@ -171,3 +178,38 @@ func TestColorRGBToHex(t *testing.T) {
assert := internal.NewAssert(t, "TestColorRGBToHex") assert := internal.NewAssert(t, "TestColorRGBToHex")
assert.Equal(expected, colorHex) assert.Equal(expected, colorHex)
} }
func TestToChannel(t *testing.T) {
assert := internal.NewAssert(t, "TestToChannel")
ch := ToChannel([]interface{}{1, 2, 3})
val1, _ := <-ch
assert.Equal(1, val1)
val2, _ := <-ch
assert.Equal(2, val2)
val3, _ := <-ch
assert.Equal(3, val3)
_, ok := <-ch
assert.Equal(false, ok)
}
func TestEncodeByte(t *testing.T) {
assert := internal.NewAssert(t, "TestEncodeByte")
byteData, _ := EncodeByte("abc")
expected := []byte{6, 12, 0, 3, 97, 98, 99}
assert.Equal(expected, byteData)
}
func TestDecodeByte(t *testing.T) {
assert := internal.NewAssert(t, "TestDecodeByte")
var obj string
byteData := []byte{6, 12, 0, 3, 97, 98, 99}
DecodeByte(byteData, &obj)
assert.Equal("abc", obj)
}

View File

@@ -54,14 +54,18 @@ func AesEcbDecrypt(encrypted, key []byte) []byte {
// AesCbcEncrypt encrypt data with key use AES CBC algorithm // AesCbcEncrypt encrypt data with key use AES CBC algorithm
// len(key) should be 16, 24 or 32 // len(key) should be 16, 24 or 32
func AesCbcEncrypt(data, key []byte) []byte { func AesCbcEncrypt(data, key []byte) []byte {
// len(key) should be 16, 24 or 32
block, _ := aes.NewCipher(key) block, _ := aes.NewCipher(key)
blockSize := block.BlockSize() data = pkcs7Padding(data, block.BlockSize())
data = pkcs7Padding(data, blockSize)
blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) encrypted := make([]byte, aes.BlockSize+len(data))
iv := encrypted[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(encrypted[aes.BlockSize:], data)
encrypted := make([]byte, len(data))
blockMode.CryptBlocks(encrypted, data)
return encrypted return encrypted
} }
@@ -69,12 +73,14 @@ func AesCbcEncrypt(data, key []byte) []byte {
// len(key) should be 16, 24 or 32 // len(key) should be 16, 24 or 32
func AesCbcDecrypt(encrypted, key []byte) []byte { func AesCbcDecrypt(encrypted, key []byte) []byte {
block, _ := aes.NewCipher(key) block, _ := aes.NewCipher(key)
blockSize := block.BlockSize()
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
decrypted := make([]byte, len(encrypted)) iv := encrypted[:aes.BlockSize]
blockMode.CryptBlocks(decrypted, encrypted) encrypted = encrypted[aes.BlockSize:]
decrypted = pkcs7UnPadding(decrypted)
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(encrypted, encrypted)
decrypted := pkcs7UnPadding(encrypted)
return decrypted return decrypted
} }

View File

@@ -55,12 +55,16 @@ func DesEcbDecrypt(encrypted, key []byte) []byte {
// len(key) should be 8 // len(key) should be 8
func DesCbcEncrypt(data, key []byte) []byte { func DesCbcEncrypt(data, key []byte) []byte {
block, _ := des.NewCipher(key) block, _ := des.NewCipher(key)
blockSize := block.BlockSize() data = pkcs7Padding(data, block.BlockSize())
data = pkcs7Padding(data, blockSize)
blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
encrypted := make([]byte, len(data)) encrypted := make([]byte, des.BlockSize+len(data))
blockMode.CryptBlocks(encrypted, data) iv := encrypted[:des.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(encrypted[des.BlockSize:], data)
return encrypted return encrypted
} }
@@ -69,13 +73,14 @@ func DesCbcEncrypt(data, key []byte) []byte {
// len(key) should be 8 // len(key) should be 8
func DesCbcDecrypt(encrypted, key []byte) []byte { func DesCbcDecrypt(encrypted, key []byte) []byte {
block, _ := des.NewCipher(key) block, _ := des.NewCipher(key)
blockSize := block.BlockSize()
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
decrypted := make([]byte, len(encrypted)) iv := encrypted[:des.BlockSize]
blockMode.CryptBlocks(decrypted, encrypted) encrypted = encrypted[des.BlockSize:]
decrypted = pkcs7UnPadding(decrypted)
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(encrypted, encrypted)
decrypted := pkcs7UnPadding(encrypted)
return decrypted return decrypted
} }

60
datetime/conversion.go Normal file
View File

@@ -0,0 +1,60 @@
// Copyright 2021 dudaodong@gmail.com. All rights reserved.
// Use of this source code is governed by MIT license.
package datetime
import "time"
type theTime struct {
unix int64
}
// NewUnixNow return unix timestamp of current time
func NewUnixNow() *theTime {
return &theTime{unix: time.Now().Unix()}
}
// NewUnix return unix timestamp of specified time
func NewUnix(unix int64) *theTime {
return &theTime{unix: unix}
}
// NewFormat return unix timestamp of specified time string, t should be "yyyy-mm-dd hh:mm:ss"
func NewFormat(t string) (*theTime, error) {
timeLayout := "2006-01-02 15:04:05"
loc := time.FixedZone("CST", 8*3600)
tt, err := time.ParseInLocation(timeLayout, t, loc)
if err != nil {
return nil, err
}
return &theTime{unix: tt.Unix()}, nil
}
// NewISO8601 return unix timestamp of specified iso8601 time string
func NewISO8601(iso8601 string) (*theTime, error) {
t, err := time.ParseInLocation(time.RFC3339, iso8601, time.UTC)
if err != nil {
return nil, err
}
return &theTime{unix: t.Unix()}, nil
}
// ToUnix return unix timestamp
func (t *theTime) ToUnix() int64 {
return t.unix
}
// ToFormat return the time string 'yyyy-mm-dd hh:mm:ss' of unix time
func (t *theTime) ToFormat() string {
return time.Unix(t.unix, 0).Format("2006-01-02 15:04:05")
}
// ToFormatForTpl return the time string which format is specified tpl
func (t *theTime) ToFormatForTpl(tpl string) string {
return time.Unix(t.unix, 0).Format(tpl)
}
// ToFormatForTpl return iso8601 time string
func (t *theTime) ToIso8601() string {
return time.Unix(t.unix, 0).Format(time.RFC3339)
}

View File

@@ -0,0 +1,54 @@
package datetime
import (
"testing"
"github.com/duke-git/lancet/internal"
)
func TestToUnix(t *testing.T) {
assert := internal.NewAssert(t, "TestToUnix")
tm1 := NewUnixNow()
unixTimestamp := tm1.ToUnix()
tm2 := NewUnix(unixTimestamp)
assert.Equal(tm1, tm2)
}
func TestToFormat(t *testing.T) {
assert := internal.NewAssert(t, "TestToFormat")
tm, err := NewFormat("2022/03/18 17:04:05")
assert.IsNotNil(err)
tm, err = NewFormat("2022-03-18 17:04:05")
assert.IsNil(err)
t.Log("ToFormat -> ", tm.ToFormat())
}
func TestToFormatForTpl(t *testing.T) {
assert := internal.NewAssert(t, "TestToFormatForTpl")
tm, err := NewFormat("2022/03/18 17:04:05")
assert.IsNotNil(err)
tm, err = NewFormat("2022-03-18 17:04:05")
assert.IsNil(err)
t.Log("ToFormatForTpl -> ", tm.ToFormatForTpl("2006/01/02 15:04:05"))
}
func TestToIso8601(t *testing.T) {
assert := internal.NewAssert(t, "TestToIso8601")
tm, err := NewISO8601("2022-03-18 17:04:05")
assert.IsNotNil(err)
tm, err = NewISO8601("2006-01-02T15:04:05.999Z")
assert.IsNil(err)
t.Log("ToIso8601 -> ", tm.ToIso8601())
}

View File

@@ -5,7 +5,7 @@ Package convertor contains some functions for data type convertion.
## Source: ## Source:
[https://github.com/duke-git/lancet/blob/main/convertor/convertor.go](https://github.com/duke-git/lancet/blob/main/convertor/convertor.go) [https://github.com/duke-git/lancet/blob/v1/convertor/convertor.go](https://github.com/duke-git/lancet/blob/v1/convertor/convertor.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -24,10 +24,13 @@ import (
- [ToBool](#ToBool) - [ToBool](#ToBool)
- [ToBytes](#ToBytes) - [ToBytes](#ToBytes)
- [ToChar](#ToChar) - [ToChar](#ToChar)
- [ToChannel](#ToChannel)
- [ToInt](#ToInt) - [ToInt](#ToInt)
- [ToJson](#ToJson) - [ToJson](#ToJson)
- [ToString](#ToString) - [ToString](#ToString)
- [StructToMap](#StructToMap) - [StructToMap](#StructToMap)
- [EncodeByte](#EncodeByte)
- [DecodeByte](#DecodeByte)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -191,6 +194,43 @@ func main() {
``` ```
### <span id="ToChannel">ToChannel</span>
<p>Convert a collection of elements to a read-only channels.</p>
<b>Signature:</b>
```go
func ToChannel(array []interface{}) <-chan interface{}
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/convertor"
)
func main() {
ch := convertor.ToChannel([]int{1, 2, 3})
val1, _ := <-ch
fmt.Println(val1) //1
val2, _ := <-ch
fmt.Println(val2) //2
val3, _ := <-ch
fmt.Println(val3) //3
_, ok := <-ch
fmt.Println(ok) //false
}
```
### <span id="ToFloat">ToFloat</span> ### <span id="ToFloat">ToFloat</span>
@@ -346,4 +386,59 @@ func main() {
fmt.Printf("type: %T, value: %s", pm, pm) //type: map[string]interface {}, value: map[name:test] fmt.Printf("type: %T, value: %s", pm, pm) //type: map[string]interface {}, value: map[name:test]
} }
```
### <span id="EncodeByte">EncodeByte</span>
<p>Encode data to byte slice.</p>
<b>Signature:</b>
```go
func EncodeByte(data any) ([]byte, error)
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/convertor"
)
func main() {
byteData, _ := convertor.EncodeByte("abc")
fmt.Println(byteData) //[]byte{6, 12, 0, 3, 97, 98, 99}
}
```
### <span id="DecodeByte">DecodeByte</span>
<p>Decode byte data to target object. target should be a pointer instance.</p>
<b>Signature:</b>
```go
func DecodeByte(data []byte, target any) error
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/convertor"
)
func main() {
var result string
byteData := []byte{6, 12, 0, 3, 97, 98, 99}
convertor.DecodeByte(byteData, &result)
fmt.Println(result) //"abc"
}
``` ```

View File

@@ -5,7 +5,7 @@ convertor转换器包支持一些常见的数据类型转换
## 源码: ## 源码:
[https://github.com/duke-git/lancet/blob/main/convertor/convertor.go](https://github.com/duke-git/lancet/blob/main/convertor/convertor.go) [https://github.com/duke-git/lancet/blob/v1/convertor/convertor.go](https://github.com/duke-git/lancet/blob/v1/convertor/convertor.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -21,15 +21,25 @@ import (
## 目录 ## 目录
- [ColorHexToRGB](#ColorHexToRGB) - [Convertor](#convertor)
- [ColorRGBToHex](#ColorRGBToHex) - [源码:](#源码)
- [ToBool](#ToBool) - [用法:](#用法)
- [ToBytes](#ToBytes) - [目录](#目录)
- [ToChar](#ToChar) - [文档](#文档)
- [ToInt](#ToInt) - [<span id="ColorHexToRGB">ColorHexToRGB</span>](#colorhextorgb)
- [ToJson](#ToJson) - [<span id="ColorRGBToHex">ColorRGBToHex</span>](#colorrgbtohex)
- [ToString](#ToString) - [<span id="ToBool">ToBool</span>](#tobool)
- [StructToMap](#StructToMap) - [<span id="ToBytes">ToBytes</span>](#tobytes)
- [<span id="ToChar">ToChar</span>](#tochar)
- [<span id="ToChannel">ToChannel</span>](#tochannel)
- [<span id="ToFloat">ToFloat</span>](#tofloat)
- [<span id="ToInt">ToInt</span>](#toint)
- [<span id="ToJson">ToJson</span>](#tojson)
- [<span id="ToString">ToString</span>](#tostring)
- [<span id="StructToMap">StructToMap</span>](#structtomap)
- [<span id="EncodeByte">EncodeByte</span>](#encodebyte)
- [<span id="DecodeByte">DecodeByte</span>](#decodebyte)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -194,6 +204,44 @@ func main() {
### <span id="ToChannel">ToChannel</span>
<p>将切片转为只读channel</p>
<b>函数签名:</b>
```go
func ToChannel(array []interface{}) <-chan interface{}
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/convertor"
)
func main() {
ch := convertor.ToChannel([]int{1, 2, 3})
val1, _ := <-ch
fmt.Println(val1) //1
val2, _ := <-ch
fmt.Println(val2) //2
val3, _ := <-ch
fmt.Println(val3) //3
_, ok := <-ch
fmt.Println(ok) //false
}
```
### <span id="ToFloat">ToFloat</span> ### <span id="ToFloat">ToFloat</span>
<p>将interface转成float64类型如果参数无法转换会返回0和error</p> <p>将interface转成float64类型如果参数无法转换会返回0和error</p>
@@ -348,4 +396,59 @@ func main() {
fmt.Printf("type: %T, value: %s", pm, pm) //type: map[string]interface {}, value: map[name:test] fmt.Printf("type: %T, value: %s", pm, pm) //type: map[string]interface {}, value: map[name:test]
} }
```
### <span id="EncodeByte">EncodeByte</span>
<p>将data编码成字节切片</p>
<b>函数签名:</b>
```go
func EncodeByte(data any) ([]byte, error)
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/convertor"
)
func main() {
byteData, _ := convertor.EncodeByte("abc")
fmt.Println(byteData) //[]byte{6, 12, 0, 3, 97, 98, 99}
}
```
### <span id="DecodeByte">DecodeByte</span>
<p>解码字节切片到目标对象,目标对象需要传入一个指针实例子</p>
<b>函数签名:</b>
```go
func DecodeByte(data []byte, target any) error
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/convertor"
)
func main() {
var result string
byteData := []byte{6, 12, 0, 3, 97, 98, 99}
convertor.DecodeByte(byteData, &result)
fmt.Println(result) //"abc"
}
``` ```

View File

@@ -5,10 +5,10 @@ Package cryptor contains some functions for data encryption and decryption. Supp
## Source: ## Source:
- [https://github.com/duke-git/lancet/blob/main/cryptor/aes.go](https://github.com/duke-git/lancet/blob/main/cryptor/aes.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go](https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go)
- [https://github.com/duke-git/lancet/blob/main/cryptor/des.go](https://github.com/duke-git/lancet/blob/main/cryptor/des.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/des.go](https://github.com/duke-git/lancet/blob/v1/cryptor/des.go)
- [https://github.com/duke-git/lancet/blob/main/cryptor/basic.go](https://github.com/duke-git/lancet/blob/main/cryptor/basic.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go](https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go)
- [https://github.com/duke-git/lancet/blob/main/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/main/cryptor/rsa.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>

View File

@@ -5,10 +5,10 @@ cryptor加密包支持数据加密和解密获取md5hash值。支持base64
## 源码: ## 源码:
- [https://github.com/duke-git/lancet/blob/main/cryptor/aes.go](https://github.com/duke-git/lancet/blob/main/cryptor/aes.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go](https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go)
- [https://github.com/duke-git/lancet/blob/main/cryptor/des.go](https://github.com/duke-git/lancet/blob/main/cryptor/des.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/des.go](https://github.com/duke-git/lancet/blob/v1/cryptor/des.go)
- [https://github.com/duke-git/lancet/blob/main/cryptor/basic.go](https://github.com/duke-git/lancet/blob/main/cryptor/basic.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go](https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go)
- [https://github.com/duke-git/lancet/blob/main/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/main/cryptor/rsa.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>

View File

@@ -5,7 +5,7 @@ Package datetime supports date and time format and compare.
## Source: ## Source:
[https://github.com/duke-git/lancet/blob/main/datetime/datetime.go](https://github.com/duke-git/lancet/blob/main/datetime/datetime.go) [https://github.com/duke-git/lancet/blob/v1/datetime/datetime.go](https://github.com/duke-git/lancet/blob/v1/datetime/datetime.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -43,6 +43,14 @@ import (
- [FormatTimeToStr](#FormatTimeToStr) - [FormatTimeToStr](#FormatTimeToStr)
- [FormatStrToTime](#FormatStrToTime) - [FormatStrToTime](#FormatStrToTime)
- [NewUnixNow](#NewUnixNow)
- [NewUnix](#NewUnix)
- [NewFormat](#NewFormat)
- [NewISO8601](#NewISO8601)
- [ToUnix](#ToUnix)
- [ToFormat](#ToFormat)
- [ToFormatForTpl](#ToFormatForTpl)
- [ToIso8601](#ToIso8601)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -667,3 +675,221 @@ func main() {
### <span id="NewUnixNow">NewUnixNow</span>
<p>Return unix timestamp of current time</p>
<b>Signature:</b>
```go
type theTime struct {
unix int64
}
func NewUnixNow() *theTime
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/datetime"
)
func main() {
tm := datetime.NewUnixNow()
fmt.Println(tm) //&{1647597438}
}
```
### <span id="NewUnix">NewUnix</span>
<p>Return unix timestamp of specified int64 value.</p>
<b>Signature:</b>
```go
type theTime struct {
unix int64
}
func NewUnix(unix int64) *theTime
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/datetime"
)
func main() {
tm := datetime.NewUnix(1647597438)
fmt.Println(tm) //&{1647597438}
}
```
### <span id="NewFormat">NewFormat</span>
<p>Return unix timestamp of specified time string, t should be "yyyy-mm-dd hh:mm:ss".</p>
<b>Signature:</b>
```go
type theTime struct {
unix int64
}
func NewFormat(t string) (*theTime, error)
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/datetime"
)
func main() {
tm, err := datetime.NewFormat("2022-03-18 17:04:05")
fmt.Println(tm) //&{1647594245}
}
```
### <span id="NewISO8601">NewISO8601</span>
<p>Return unix timestamp of specified iso8601 time string.</p>
<b>Signature:</b>
```go
type theTime struct {
unix int64
}
func NewISO8601(iso8601 string) (*theTime, error)
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/datetime"
)
func main() {
tm, err := datetime.NewISO8601("2006-01-02T15:04:05.999Z")
fmt.Println(tm) //&{1136214245}
}
```
### <span id="ToUnix">ToUnix</span>
<p>Return unix timestamp.</p>
<b>Signature:</b>
```go
func (t *theTime) ToUnix() int64
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/datetime"
)
func main() {
tm := datetime.NewUnixNow()
fmt.Println(tm.ToUnix()) //1647597438
}
```
### <span id="ToFormat">ToFormat</span>
<p>Return time string 'yyyy-mm-dd hh:mm:ss'.</p>
<b>Signature:</b>
```go
func (t *theTime) ToFormat() string
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/datetime"
)
func main() {
tm, _ := datetime.NewFormat("2022-03-18 17:04:05")
fmt.Println(tm.ToFormat()) //"2022-03-18 17:04:05"
}
```
### <span id="ToFormatForTpl">ToFormatForTpl</span>
<p>Return the time string which format is specified tpl.</p>
<b>Signature:</b>
```go
func (t *theTime) ToFormatForTpl(tpl string) string
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/datetime"
)
func main() {
tm, _ := datetime.NewFormat("2022-03-18 17:04:05")
ts := tm.ToFormatForTpl("2006/01/02 15:04:05")
fmt.Println(ts) //"2022/03/18 17:04:05"
}
```
### <span id="ToIso8601">ToIso8601</span>
<p>Return iso8601 time string.</p>
<b>Signature:</b>
```go
func (t *theTime) ToIso8601() string
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/datetime"
)
func main() {
tm, _ := datetime.NewISO8601("2006-01-02T15:04:05.999Z")
ts := tm.ToIso8601()
fmt.Println(ts) //"2006-01-02T23:04:05+08:00"
}
```

View File

@@ -5,7 +5,7 @@ datetime日期时间处理包格式化日期比较日期。
## 源码: ## 源码:
[https://github.com/duke-git/lancet/blob/main/datetime/datetime.go](https://github.com/duke-git/lancet/blob/main/datetime/datetime.go) [https://github.com/duke-git/lancet/blob/v1/datetime/datetime.go](https://github.com/duke-git/lancet/blob/v1/datetime/datetime.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -42,6 +42,14 @@ import (
- [GetNightTimestamp](#GetNightTimestamp) - [GetNightTimestamp](#GetNightTimestamp)
- [FormatTimeToStr](#FormatTimeToStr) - [FormatTimeToStr](#FormatTimeToStr)
- [FormatStrToTime](#FormatStrToTime) - [FormatStrToTime](#FormatStrToTime)
- [NewUnixNow](#NewUnixNow)
- [NewUnix](#NewUnix)
- [NewFormat](#NewFormat)
- [NewISO8601](#NewISO8601)
- [ToUnix](#ToUnix)
- [ToFormat](#ToFormat)
- [ToFormatForTpl](#ToFormatForTpl)
- [ToIso8601](#ToIso8601)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -666,3 +674,222 @@ func main() {
### <span id="NewUnixNow">NewUnixNow</span>
<p>创建一个当前时间的unix时间戳</p>
<b>函数签名:</b>
```go
type theTime struct {
unix int64
}
func NewUnixNow() *theTime
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/datetime"
)
func main() {
tm := datetime.NewUnixNow()
fmt.Println(tm) //&{1647597438}
}
```
### <span id="NewUnix">NewUnix</span>
<p>创建一个unix时间戳</p>
<b>函数签名:</b>
```go
type theTime struct {
unix int64
}
func NewUnix(unix int64) *theTime
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/datetime"
)
func main() {
tm := datetime.NewUnix(1647597438)
fmt.Println(tm) //&{1647597438}
}
```
### <span id="NewFormat">NewFormat</span>
<p>创建一个yyyy-mm-dd hh:mm:ss格式时间字符串的unix时间戳</p>
<b>函数签名:</b>
```go
type theTime struct {
unix int64
}
func NewFormat(t string) (*theTime, error)
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/datetime"
)
func main() {
tm, err := datetime.NewFormat("2022-03-18 17:04:05")
fmt.Println(tm) //&{1647594245}
}
```
### <span id="NewISO8601">NewISO8601</span>
<p>创建一个iso8601格式时间字符串的unix时间戳</p>
<b>函数签名:</b>
```go
type theTime struct {
unix int64
}
func NewISO8601(iso8601 string) (*theTime, error)
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/datetime"
)
func main() {
tm, err := datetime.NewISO8601("2006-01-02T15:04:05.999Z")
fmt.Println(tm) //&{1136214245}
}
```
### <span id="ToUnix">ToUnix</span>
<p>返回unix时间戳</p>
<b>函数签名:</b>
```go
func (t *theTime) ToUnix() int64
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/datetime"
)
func main() {
tm := datetime.NewUnixNow()
fmt.Println(tm.ToUnix()) //1647597438
}
```
### <span id="ToFormat">ToFormat</span>
<p>返回格式'yyyy-mm-dd hh:mm:ss'的日期字符串</p>
<b>函数签名:</b>
```go
func (t *theTime) ToFormat() string
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/datetime"
)
func main() {
tm, _ := datetime.NewFormat("2022-03-18 17:04:05")
fmt.Println(tm.ToFormat()) //"2022-03-18 17:04:05"
}
```
### <span id="ToFormatForTpl">ToFormatForTpl</span>
<p>返回tpl格式指定的日期字符串</p>
<b>函数签名:</b>
```go
func (t *theTime) ToFormatForTpl(tpl string) string
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/datetime"
)
func main() {
tm, _ := datetime.NewFormat("2022-03-18 17:04:05")
ts := tm.ToFormatForTpl("2006/01/02 15:04:05")
fmt.Println(ts) //"2022/03/18 17:04:05"
}
```
### <span id="ToIso8601">ToIso8601</span>
<p>返回iso8601日期字符串</p>
<b>函数签名:</b>
```go
func (t *theTime) ToIso8601() string
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/datetime"
)
func main() {
tm, _ := datetime.NewISO8601("2006-01-02T15:04:05.999Z")
ts := tm.ToIso8601()
fmt.Println(ts) //"2006-01-02T23:04:05+08:00"
}
```

View File

@@ -5,7 +5,7 @@ Package fileutil implements some basic functions for file operations.
## Source: ## Source:
[https://github.com/duke-git/lancet/blob/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/fileutil/file.go) [https://github.com/duke-git/lancet/blob/v1/fileutil/file.go](https://github.com/duke-git/lancet/blob/v1/fileutil/file.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -21,6 +21,8 @@ import (
## Index ## Index
- [ClearFile](#ClearFile) - [ClearFile](#ClearFile)
- [CreateFile](#CreateFile) - [CreateFile](#CreateFile)
- [CreateDir](#CreateDir)
- [CopyFile](#CopyFile) - [CopyFile](#CopyFile)
- [FileMode](#FileMode) - [FileMode](#FileMode)
- [MiMeType](#MiMeType) - [MiMeType](#MiMeType)
@@ -32,7 +34,6 @@ import (
- [ReadFileToString](#ReadFileToString) - [ReadFileToString](#ReadFileToString)
- [ReadFileByLine](#ReadFileByLine) - [ReadFileByLine](#ReadFileByLine)
- [Zip](#Zip) - [Zip](#Zip)
- [UnZip](#UnZip) - [UnZip](#UnZip)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -67,6 +68,34 @@ func main() {
} }
``` ```
### <span id="CreateDir">CreateDir</span>
<p>Create directory in absolute path. param `absPath` like /a/, /a/b/.</p>
<b>Signature:</b>
```go
func CreateDir(absPath string) error
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/fileutil"
)
func main() {
err := fileutil.CreateDir("/a/")
fmt.Println(err)
}
```
### <span id="CreateFile">CreateFile</span> ### <span id="CreateFile">CreateFile</span>
<p>Create file in path. return true if create succeed.</p> <p>Create file in path. return true if create succeed.</p>

View File

@@ -5,7 +5,7 @@ fileutil包支持文件基本操作。
## 源码: ## 源码:
[https://github.com/duke-git/lancet/blob/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/fileutil/file.go) [https://github.com/duke-git/lancet/blob/v1/fileutil/file.go](https://github.com/duke-git/lancet/blob/v1/fileutil/file.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -21,6 +21,7 @@ import (
## 目录 ## 目录
- [ClearFile](#ClearFile) - [ClearFile](#ClearFile)
- [CreateFile](#CreateFile) - [CreateFile](#CreateFile)
- [CreateDir](#CreateDir)
- [CopyFile](#CopyFile) - [CopyFile](#CopyFile)
- [FileMode](#FileMode) - [FileMode](#FileMode)
- [MiMeType](#MiMeType) - [MiMeType](#MiMeType)
@@ -67,6 +68,33 @@ func main() {
} }
``` ```
### <span id="CreateDir">CreateDir</span>
<p>使用绝对路径创建嵌套目录,例如/a/, /a/b/</p>
<b>函数签名:</b>
```go
func CreateDir(absPath string) error
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/fileutil"
)
func main() {
err := fileutil.CreateDir("/a/")
fmt.Println(err)
}
```
### <span id="CreateFile">CreateFile</span> ### <span id="CreateFile">CreateFile</span>
<p>创建文件创建成功返回true, 否则返回false</p> <p>创建文件创建成功返回true, 否则返回false</p>

View File

@@ -5,7 +5,7 @@ formatter contains some functions for data formatting.
## Source: ## Source:
[https://github.com/duke-git/lancet/blob/main/formatter/formatter.go](https://github.com/duke-git/lancet/blob/main/formatter/formatter.go) [https://github.com/duke-git/lancet/blob/v1/formatter/formatter.go](https://github.com/duke-git/lancet/blob/v1/formatter/formatter.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>

View File

@@ -5,7 +5,7 @@ formatter格式化器包含一些数据格式化处理方法。
## 源码: ## 源码:
[https://github.com/duke-git/lancet/blob/main/formatter/formatter.go](https://github.com/duke-git/lancet/blob/main/formatter/formatter.go) [https://github.com/duke-git/lancet/blob/v1/formatter/formatter.go](https://github.com/duke-git/lancet/blob/v1/formatter/formatter.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>

View File

@@ -5,8 +5,8 @@ Package function can control the flow of function execution and support part of
## Source: ## Source:
[https://github.com/duke-git/lancet/blob/main/function/function.go](https://github.com/duke-git/lancet/blob/main/function/function.go) [https://github.com/duke-git/lancet/blob/v1/function/function.go](https://github.com/duke-git/lancet/blob/v1/function/function.go)
[https://github.com/duke-git/lancet/blob/main/function/watcher.go](https://github.com/duke-git/lancet/blob/main/function/watcher.go) [https://github.com/duke-git/lancet/blob/v1/function/watcher.go](https://github.com/duke-git/lancet/blob/v1/function/watcher.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>

View File

@@ -5,8 +5,8 @@ function函数包控制函数执行流程包含部分函数式编程。
## 源码: ## 源码:
[https://github.com/duke-git/lancet/blob/main/function/function.go](https://github.com/duke-git/lancet/blob/main/function/function.go) [https://github.com/duke-git/lancet/blob/v1/function/function.go](https://github.com/duke-git/lancet/blob/v1/function/function.go)
[https://github.com/duke-git/lancet/blob/main/function/watcher.go](https://github.com/duke-git/lancet/blob/main/function/watcher.go) [https://github.com/duke-git/lancet/blob/v1/function/watcher.go](https://github.com/duke-git/lancet/blob/v1/function/watcher.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>

View File

@@ -5,7 +5,7 @@ Package mathutil implements some functions for math calculation.
## Source: ## Source:
[https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go) [https://github.com/duke-git/lancet/blob/v1/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/v1/mathutil/mathutil.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>

View File

@@ -5,7 +5,7 @@ mathutil包实现了一些数学计算的函数.
## 源码: ## 源码:
[https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/main/mathutil/mathutil.go) [https://github.com/duke-git/lancet/blob/v1/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/v1/mathutil/mathutil.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>

View File

@@ -5,9 +5,11 @@ Package netutil contains functions to get net information and send http request.
## Source: ## Source:
[https://github.com/duke-git/lancet/blob/main/netutil/net.go](https://github.com/duke-git/lancet/blob/main/netutil/net.go) [https://github.com/duke-git/lancet/blob/v1/netutil/net.go](https://github.com/duke-git/lancet/blob/v1/netutil/net.go)
[https://github.com/duke-git/lancet/blob/main/netutil/http.go](https://github.com/duke-git/lancet/blob/main/netutil/http.go) [https://github.com/duke-git/lancet/blob/v1/netutil/http_client.go](https://github.com/duke-git/lancet/blob/v1/netutil/http_client.go)
[https://github.com/duke-git/lancet/blob/v1/netutil/http.go](https://github.com/duke-git/lancet/blob/v1/netutil/http.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -22,17 +24,25 @@ import (
## Index ## Index
- [ConvertMapToQueryString](#ConvertMapToQueryString) - [ConvertMapToQueryString](#ConvertMapToQueryString)
- [EncodeUrl](#EncodeUrl)
- [GetInternalIp](#GetInternalIp) - [GetInternalIp](#GetInternalIp)
- [GetIps](#GetIps) - [GetIps](#GetIps)
- [GetMacAddrs](#GetMacAddrs) - [GetMacAddrs](#GetMacAddrs)
- [GetPublicIpInfo](#GetPublicIpInfo) - [GetPublicIpInfo](#GetPublicIpInfo)
- [GetRequestPublicIp](#GetRequestPublicIp)
- [IsPublicIP](#IsPublicIP) - [IsPublicIP](#IsPublicIP)
- [HttpGet](#HttpGet) - [IsInternalIP](#IsInternalIP)
- [HttpDelete](#HttpDelete) - [HttpRequest](#HttpRequest)
- [HttpPost](#HttpPost) - [HttpClient](#HttpClient)
- [HttpPut](#HttpPut) - [SendRequest](#SendRequest)
- [DecodeResponse](#DecodeResponse)
- [StructToUrlValues](#StructToUrlValues)
- [HttpPatch](#HttpPatch) - [HttpGet<sup>Deprecated</sup>](#HttpGet)
- [HttpDelete<sup>Deprecated</sup>](#HttpDelete)
- [HttpPost<sup>Deprecated</sup>](#HttpPost)
- [HttpPut<sup>Deprecated</sup>](#HttpPut)
- [HttpPatch<sup>Deprecated</sup>](#HttpPatch)
- [ParseHttpResponse](#ParseHttpResponse) - [ParseHttpResponse](#ParseHttpResponse)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -72,6 +82,35 @@ func main() {
### <span id="EncodeUrl">EncodeUrl</span>
<p>Encode url query string values.</p>
<b>Signature:</b>
```go
func EncodeUrl(urlStr string) (string, error)
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/netutil"
)
func main() {
urlAddr := "http://www.lancet.com?a=1&b=[2]"
encodedUrl, err := netutil.EncodeUrl(urlAddr)
if err != nil {
fmt.Println(err)
}
fmt.Println(encodedUrl) //http://www.lancet.com?a=1&b=%5B2%5D
}
```
### <span id="GetInternalIp">GetInternalIp</span> ### <span id="GetInternalIp">GetInternalIp</span>
<p>Get internal ip information.</p> <p>Get internal ip information.</p>
@@ -198,6 +237,48 @@ func main() {
``` ```
### <span id="GetRequestPublicIp">GetRequestPublicIp</span>
<p>Get http request public ip.</p>
<b>Signature:</b>
```go
func GetRequestPublicIp(req *http.Request) string
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/netutil"
)
func main() {
ip := "36.112.24.10"
request1 := http.Request{
Method: "GET",
Header: http.Header{
"X-Forwarded-For": {ip},
},
}
publicIp1 := netutil.GetRequestPublicIp(&request1)
fmt.Println(publicIp1) //36.112.24.10
request2 := http.Request{
Method: "GET",
Header: http.Header{
"X-Real-Ip": {ip},
},
}
publicIp2 := netutil.GetRequestPublicIp(&request2)
fmt.Println(publicIp2) //36.112.24.10
}
```
### <span id="IsPublicIP">IsPublicIP</span> ### <span id="IsPublicIP">IsPublicIP</span>
<p>Checks if a ip is public or not.</p> <p>Checks if a ip is public or not.</p>
@@ -229,8 +310,261 @@ func main() {
### <span id="IsInternalIP">IsInternalIP</span>
<p>Checks if an ip is intranet or not.</p>
### <span id="HttpGet">HttpGet</span> <b>Signature:</b>
```go
func IsInternalIP(IP net.IP) bool
```
<b>Example:</b>
```go
package main
import (
"fmt"
"net"
"github.com/duke-git/lancet/netutil"
)
func main() {
ip1 := net.ParseIP("127.0.0.1")
ip2 := net.ParseIP("36.112.24.10")
fmt.Println(netutil.IsInternalIP(ip1)) //true
fmt.Println(netutil.IsInternalIP(ip2)) //false
}
```
### <span id="HttpRequest">HttpRequest</span>
<p>HttpRequest is a struct used to abstract HTTP request entity.</p>
<b>Signature:</b>
```go
type HttpRequest struct {
RawURL string
Method string
Headers http.Header
QueryParams url.Values
FormData url.Values
Body []byte
}
```
<b>Example:</b>
```go
package main
import (
"fmt"
"net"
"github.com/duke-git/lancet/netutil"
)
func main() {
header := http.Header{}
header.Add("Content-Type", "multipart/form-data")
postData := url.Values{}
postData.Add("userId", "1")
postData.Add("title", "testItem")
request := &netutil.HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos",
Method: "POST",
Headers: header,
FormData: postData,
}
}
```
### <span id="HttpClient">HttpClient</span>
<p>HttpClient is a struct used to send HTTP request. It can be instanced with some configurations or none config.</p>
<b>Signature:</b>
```go
type HttpClient struct {
*http.Client
TLS *tls.Config
Request *http.Request
Config HttpClientConfig
}
type HttpClientConfig struct {
SSLEnabled bool
TLSConfig *tls.Config
Compressed bool
HandshakeTimeout time.Duration
ResponseTimeout time.Duration
Verbose bool
}
func NewHttpClient() *HttpClient
func NewHttpClientWithConfig(config *HttpClientConfig) *HttpClient
```
<b>Example:</b>
```go
package main
import (
"fmt"
"net"
"time"
"github.com/duke-git/lancet/netutil"
)
func main() {
httpClientCfg := netutil.HttpClientConfig{
SSLEnabled: true,
HandshakeTimeout:10 * time.Second
}
httpClient := netutil.NewHttpClientWithConfig(&httpClientCfg)
}
```
### <span id="SendRequest">SendRequest</span>
<p>Use HttpClient to send HTTP request.</p>
<b>Signature:</b>
```go
func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, error)
```
<b>Example:</b>
```go
package main
import (
"fmt"
"net"
"time"
"github.com/duke-git/lancet/netutil"
)
func main() {
request := &netutil.HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
Method: "GET",
}
httpClient := netutil.NewHttpClient()
resp, err := httpClient.SendRequest(request)
if err != nil || resp.StatusCode != 200 {
log.Fatal(err)
}
type Todo struct {
UserId int `json:"userId"`
Id int `json:"id"`
Title string `json:"title"`
Completed bool `json:"completed"`
}
var todo Todo
httpClient.DecodeResponse(resp, &todo)
fmt.Println(todo.Id) //1
}
```
### <span id="DecodeResponse">DecodeResponse</span>
<p>Decode http response into target object.</p>
<b>Signature:</b>
```go
func (client *HttpClient) DecodeResponse(resp *http.Response, target interface{}) error
```
<b>Example:</b>
```go
package main
import (
"fmt"
"net"
"time"
"github.com/duke-git/lancet/netutil"
)
func main() {
request := &netutil.HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
Method: "GET",
}
httpClient := netutil.NewHttpClient()
resp, err := httpClient.SendRequest(request)
if err != nil || resp.StatusCode != 200 {
log.Fatal(err)
}
type Todo struct {
UserId int `json:"userId"`
Id int `json:"id"`
Title string `json:"title"`
Completed bool `json:"completed"`
}
var todo Todo
httpClient.DecodeResponse(resp, &todo)
fmt.Println(todo.Id) //1
}
```
### <span id="StructToUrlValues">StructToUrlValues</span>
<p>Convert struct to url values, only convert the field which is exported and has `json` tag.</p>
<b>Signature:</b>
```go
func StructToUrlValues(targetStruct interface{}) url.Values
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/netutil"
)
func main() {
type TodoQuery struct {
Id int `json:"id"`
UserId int `json:"userId"`
}
todoQuery := TodoQuery{
Id: 1,
UserId: 2,
}
todoValues := netutil.StructToUrlValues(todoQuery)
fmt.Println(todoValues.Get("id")) //1
fmt.Println(todoValues.Get("userId")) //2
}
```
### <span id="HttpGet">HttpGet (Deprecated: use SendRequest for replacement)</span>
<p>Send http get request.</p> <p>Send http get request.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -272,7 +606,7 @@ func main() {
### <span id="HttpPost">HttpPost</span> ### <span id="HttpPost">HttpPost (Deprecated: use SendRequest for replacement)</span>
<p>Send http post request.</p> <p>Send http post request.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -321,7 +655,7 @@ func main() {
### <span id="HttpPut">HttpPut</span> ### <span id="HttpPut">HttpPut (Deprecated: use SendRequest for replacement)</span>
<p>Send http put request.</p> <p>Send http put request.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -371,7 +705,7 @@ func main() {
### <span id="HttpDelete">HttpDelete</span> ### <span id="HttpDelete">HttpDelete (Deprecated: use SendRequest for replacement)</span>
<p>Send http delete request.</p> <p>Send http delete request.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -410,7 +744,7 @@ func main() {
### <span id="HttpPatch">HttpPatch</span> ### <span id="HttpPatch">HttpPatch (Deprecated: use SendRequest for replacement)</span>
<p>Send http patch request.</p> <p>Send http patch request.</p>
<b>Signature:</b> <b>Signature:</b>

View File

@@ -5,9 +5,10 @@ netutil网络包支持获取ip地址发送http请求。
## 源码: ## 源码:
[https://github.com/duke-git/lancet/blob/main/netutil/net.go](https://github.com/duke-git/lancet/blob/main/netutil/net.go) [https://github.com/duke-git/lancet/blob/v1/netutil/net.go](https://github.com/duke-git/lancet/blob/v1/netutil/net.go)
[https://github.com/duke-git/lancet/blob/main/netutil/http.go](https://github.com/duke-git/lancet/blob/main/netutil/http.go) [https://github.com/duke-git/lancet/blob/v1/netutil/http_client.go](https://github.com/duke-git/lancet/blob/v1/netutil/http_client.go)
[https://github.com/duke-git/lancet/blob/v1/netutil/http.go](https://github.com/duke-git/lancet/blob/v1/netutil/http.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -22,17 +23,25 @@ import (
## 目录 ## 目录
- [ConvertMapToQueryString](#ConvertMapToQueryString) - [ConvertMapToQueryString](#ConvertMapToQueryString)
- [EncodeUrl](#EncodeUrl)
- [GetInternalIp](#GetInternalIp) - [GetInternalIp](#GetInternalIp)
- [GetIps](#GetIps) - [GetIps](#GetIps)
- [GetMacAddrs](#GetMacAddrs) - [GetMacAddrs](#GetMacAddrs)
- [GetPublicIpInfo](#GetPublicIpInfo) - [GetPublicIpInfo](#GetPublicIpInfo)
- [GetRequestPublicIp](#GetRequestPublicIp)
- [IsPublicIP](#IsPublicIP) - [IsPublicIP](#IsPublicIP)
- [HttpGet](#HttpGet) - [IsInternalIP](#IsInternalIP)
- [HttpDelete](#HttpDelete) - [HttpRequest](#HttpRequest)
- [HttpPost](#HttpPost) - [HttpClient](#HttpClient)
- [HttpPut](#HttpPut) - [SendRequest](#SendRequest)
- [DecodeResponse](#DecodeResponse)
- [StructToUrlValues](#StructToUrlValues)
- [HttpPatch](#HttpPatch) - [HttpGet<sup>Deprecated</sup>](#HttpGet)
- [HttpDelete<sup>Deprecated</sup>](#HttpDelete)
- [HttpPost<sup>Deprecated</sup>](#HttpPost)
- [HttpPut<sup>Deprecated</sup>](#HttpPut)
- [HttpPatch<sup>Deprecated</sup>](#HttpPatch)
- [ParseHttpResponse](#ParseHttpResponse) - [ParseHttpResponse](#ParseHttpResponse)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -72,6 +81,36 @@ func main() {
### <span id="EncodeUrl">EncodeUrl</span>
<p>编码url query string的值</p>
<b>函数签名:</b>
```go
func EncodeUrl(urlStr string) (string, error)
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/netutil"
)
func main() {
urlAddr := "http://www.lancet.com?a=1&b=[2]"
encodedUrl, err := netutil.EncodeUrl(urlAddr)
if err != nil {
fmt.Println(err)
}
fmt.Println(encodedUrl) //http://www.lancet.com?a=1&b=%5B2%5D
}
```
### <span id="GetInternalIp">GetInternalIp</span> ### <span id="GetInternalIp">GetInternalIp</span>
<p>获取内部ip</p> <p>获取内部ip</p>
@@ -198,6 +237,49 @@ func main() {
### <span id="GetRequestPublicIp">GetRequestPublicIp</span>
<p>获取http请求ip</p>
<b>函数签名:</b>
```go
func GetRequestPublicIp(req *http.Request) string
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/netutil"
)
func main() {
ip := "36.112.24.10"
request1 := http.Request{
Method: "GET",
Header: http.Header{
"X-Forwarded-For": {ip},
},
}
publicIp1 := netutil.GetRequestPublicIp(&request1)
fmt.Println(publicIp1) //36.112.24.10
request2 := http.Request{
Method: "GET",
Header: http.Header{
"X-Real-Ip": {ip},
},
}
publicIp2 := netutil.GetRequestPublicIp(&request2)
fmt.Println(publicIp2) //36.112.24.10
}
```
### <span id="IsPublicIP">IsPublicIP</span> ### <span id="IsPublicIP">IsPublicIP</span>
<p>判断ip是否是公共ip</p> <p>判断ip是否是公共ip</p>
@@ -228,8 +310,261 @@ func main() {
### <span id="IsInternalIP">IsInternalIP</span>
<p>判断ip是否是局域网ip.</p>
### <span id="HttpGet">HttpGet</span> <b>函数签名:</b>
```go
func IsInternalIP(IP net.IP) bool
```
<b>例子:</b>
```go
package main
import (
"fmt"
"net"
"github.com/duke-git/lancet/netutil"
)
func main() {
ip1 := net.ParseIP("127.0.0.1")
ip2 := net.ParseIP("36.112.24.10")
fmt.Println(netutil.IsInternalIP(ip1)) //true
fmt.Println(netutil.IsInternalIP(ip2)) //false
}
```
### <span id="HttpRequest">HttpRequest</span>
<p>HttpRequest用于抽象HTTP请求实体的结构</p>
<b>函数签名:</b>
```go
type HttpRequest struct {
RawURL string
Method string
Headers http.Header
QueryParams url.Values
FormData url.Values
Body []byte
}
```
<b>例子:</b>
```go
package main
import (
"fmt"
"net"
"github.com/duke-git/lancet/netutil"
)
func main() {
header := http.Header{}
header.Add("Content-Type", "multipart/form-data")
postData := url.Values{}
postData.Add("userId", "1")
postData.Add("title", "testItem")
request := &netutil.HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos",
Method: "POST",
Headers: header,
FormData: postData,
}
}
```
### <span id="HttpClient">HttpClient</span>
<p>HttpClient是用于发送HTTP请求的结构体。它可以用一些配置参数或无配置实例化.</p>
<b>函数签名:</b>
```go
type HttpClient struct {
*http.Client
TLS *tls.Config
Request *http.Request
Config HttpClientConfig
}
type HttpClientConfig struct {
SSLEnabled bool
TLSConfig *tls.Config
Compressed bool
HandshakeTimeout time.Duration
ResponseTimeout time.Duration
Verbose bool
}
func NewHttpClient() *HttpClient
func NewHttpClientWithConfig(config *HttpClientConfig) *HttpClient
```
<b>例子:</b>
```go
package main
import (
"fmt"
"net"
"time"
"github.com/duke-git/lancet/netutil"
)
func main() {
httpClientCfg := netutil.HttpClientConfig{
SSLEnabled: true,
HandshakeTimeout:10 * time.Second
}
httpClient := netutil.NewHttpClientWithConfig(&httpClientCfg)
}
```
### <span id="SendRequest">SendRequest</span>
<p>HttpClient发送http请求</p>
<b>函数签名:</b>
```go
func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, error)
```
<b>例子:</b>
```go
package main
import (
"fmt"
"net"
"time"
"github.com/duke-git/lancet/netutil"
)
func main() {
request := &netutil.HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
Method: "GET",
}
httpClient := netutil.NewHttpClient()
resp, err := httpClient.SendRequest(request)
if err != nil || resp.StatusCode != 200 {
log.Fatal(err)
}
type Todo struct {
UserId int `json:"userId"`
Id int `json:"id"`
Title string `json:"title"`
Completed bool `json:"completed"`
}
var todo Todo
httpClient.DecodeResponse(resp, &todo)
fmt.Println(todo.Id) //1
}
```
### <span id="DecodeResponse">DecodeResponse</span>
<p>解析http响应体到目标结构体</p>
<b>函数签名:</b>
```go
func (client *HttpClient) DecodeResponse(resp *http.Response, target interface{}) error
```
<b>例子:</b>
```go
package main
import (
"fmt"
"net"
"time"
"github.com/duke-git/lancet/netutil"
)
func main() {
request := &netutil.HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
Method: "GET",
}
httpClient := netutil.NewHttpClient()
resp, err := httpClient.SendRequest(request)
if err != nil || resp.StatusCode != 200 {
log.Fatal(err)
}
type Todo struct {
UserId int `json:"userId"`
Id int `json:"id"`
Title string `json:"title"`
Completed bool `json:"completed"`
}
var todo Todo
httpClient.DecodeResponse(resp, &todo)
fmt.Println(todo.Id) //1
}
```
### <span id="StructToUrlValues">StructToUrlValues</span>
<p>将结构体转为url values, 仅转化结构体导出字段并且包含`json` tag.</p>
<b>函数签名:</b>
```go
func StructToUrlValues(targetStruct interface{}) url.Values
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/netutil"
)
func main() {
type TodoQuery struct {
Id int `json:"id"`
UserId int `json:"userId"`
}
todoQuery := TodoQuery{
Id: 1,
UserId: 2,
}
todoValues := netutil.StructToUrlValues(todoQuery)
fmt.Println(todoValues.Get("id")) //1
fmt.Println(todoValues.Get("userId")) //2
}
```
### <span id="HttpGet">HttpGet (Deprecated: use SendRequest for replacement)</span>
<p>发送http get请求</p> <p>发送http get请求</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -271,7 +606,7 @@ func main() {
### <span id="HttpPost">HttpPost</span> ### <span id="HttpPost">HttpPost (Deprecated: use SendRequest for replacement)</span>
<p>发送http post请求</p> <p>发送http post请求</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -320,7 +655,7 @@ func main() {
### <span id="HttpPut">HttpPut</span> ### <span id="HttpPut">HttpPut (Deprecated: use SendRequest for replacement)</span>
<p>发送http put请求</p> <p>发送http put请求</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -370,7 +705,7 @@ func main() {
### <span id="HttpDelete">HttpDelete</span> ### <span id="HttpDelete">HttpDelete (Deprecated: use SendRequest for replacement)</span>
<p>发送http delete请求</p> <p>发送http delete请求</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -409,7 +744,7 @@ func main() {
### <span id="HttpPatch">HttpPatch</span> ### <span id="HttpPatch">HttpPatch (Deprecated: use SendRequest for replacement)</span>
<p>发送http patch请求</p> <p>发送http patch请求</p>
<b>函数签名:</b> <b>函数签名:</b>

View File

@@ -5,7 +5,7 @@ Package random implements some basic functions to generate random int and string
## Source: ## Source:
[https://github.com/duke-git/lancet/blob/main/random/random.go](https://github.com/duke-git/lancet/blob/main/random/random.go) [https://github.com/duke-git/lancet/blob/v1/random/random.go](https://github.com/duke-git/lancet/blob/v1/random/random.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>

View File

@@ -5,7 +5,7 @@ random随机数生成器包可以生成随机[]bytes, int, string。
## 源码: ## 源码:
[https://github.com/duke-git/lancet/blob/main/random/random.go](https://github.com/duke-git/lancet/blob/main/random/random.go) [https://github.com/duke-git/lancet/blob/v1/random/random.go](https://github.com/duke-git/lancet/blob/v1/random/random.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>

View File

@@ -5,7 +5,7 @@ Package retry is for executing a function repeatedly until it was successful or
## Source: ## Source:
[https://github.com/duke-git/lancet/blob/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/retry/retry.go) [https://github.com/duke-git/lancet/blob/v1/retry/retry.go](https://github.com/duke-git/lancet/blob/v1/retry/retry.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>

View File

@@ -5,7 +5,7 @@ retry重试执行函数直到函数运行成功或被context cancel。
## 源码: ## 源码:
[https://github.com/duke-git/lancet/blob/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/retry/retry.go) [https://github.com/duke-git/lancet/blob/v1/retry/retry.go](https://github.com/duke-git/lancet/blob/v1/retry/retry.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>

View File

@@ -5,7 +5,7 @@ Package slice implements some functions to manipulate slice.
## Source: ## Source:
[https://github.com/duke-git/lancet/blob/main/slice/slice.go](https://github.com/duke-git/lancet/blob/main/slice/slice.go) [https://github.com/duke-git/lancet/blob/v1/slice/slice.go](https://github.com/duke-git/lancet/blob/v1/slice/slice.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -20,6 +20,7 @@ import (
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Index ## Index
- [AppendIfAbsent](#AppendIfAbsent)
- [Contain](#Contain) - [Contain](#Contain)
- [ContainSubSlice](#ContainSubSlice) - [ContainSubSlice](#ContainSubSlice)
- [Chunk](#Chunk) - [Chunk](#Chunk)
@@ -30,6 +31,8 @@ import (
- [DifferenceBy](#DifferenceBy) - [DifferenceBy](#DifferenceBy)
- [DeleteByIndex](#DeleteByIndex) - [DeleteByIndex](#DeleteByIndex)
- [Drop](#Drop) - [Drop](#Drop)
- [Equal](#Equal)
- [EqualWith](#EqualWith)
- [Every](#Every) - [Every](#Every)
- [Filter](#Filter) - [Filter](#Filter)
- [Find](#Find) - [Find](#Find)
@@ -42,6 +45,8 @@ import (
- [InterfaceSlice](#InterfaceSlice) - [InterfaceSlice](#InterfaceSlice)
- [Intersection](#Intersection) - [Intersection](#Intersection)
- [InsertByIndex](#InsertByIndex) - [InsertByIndex](#InsertByIndex)
- [IndexOf](#IndexOf)
- [LastIndexOf](#LastIndexOf)
- [Map](#Map) - [Map](#Map)
- [ReverseSlice](#ReverseSlice) - [ReverseSlice](#ReverseSlice)
- [Reduce](#Reduce) - [Reduce](#Reduce)
@@ -49,7 +54,10 @@ import (
- [SortByField](#SortByField) - [SortByField](#SortByField)
- [Some](#Some) - [Some](#Some)
- [StringSlice](#StringSlice) - [StringSlice](#StringSlice)
- [ToSlice](#ToSlice)
- [ToSlicePointer](#ToSlicePointer)
- [Unique](#Unique) - [Unique](#Unique)
- [UniqueBy](#UniqueBy)
- [Union](#Union) - [Union](#Union)
- [UpdateByIndex](#UpdateByIndex) - [UpdateByIndex](#UpdateByIndex)
- [Without](#Without) - [Without](#Without)
@@ -61,6 +69,35 @@ import (
## Note: ## Note:
1. param which type is interface{} in below functions should be slice. 1. param which type is interface{} in below functions should be slice.
### <span id="AppendIfAbsent">AppendIfAbsent</span>
<p>If slice doesn't contain the value, append it to the slice.</p>
<b>Signature:</b>
```go
func AppendIfAbsent(slice interface{}, value interface{}) interface{}
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
strs := []string{"a", "b"}
res1 := slice.AppendIfAbsent(strs, "a")
fmt.Println(res1) //[]string{"a", "b"}
res2 := slice.AppendIfAbsent(strs, "cannot")
fmt.Println(res2"}
}
```
### <span id="Contain">Contain</span> ### <span id="Contain">Contain</span>
<p>Check if the value is in the slice or not. iterableType param can be string, map or slice.</p> <p>Check if the value is in the slice or not. iterableType param can be string, map or slice.</p>
@@ -332,6 +369,68 @@ func main() {
### <span id="Equal">Equal</span>
<p>Check if two slices are equal: the same length and all elements' order and value are equal.</p>
<b>Signature:</b>
```go
func Equal(slice1, slice2 interface{}) bool
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
slice1 := []int{1, 2, 3}
slice2 := []int{1, 2, 3}
slice3 := []int{3, 2, 1}
res1 := slice.Equal(slice1, slice2)
res2 := slice.Equal(slice1, slice3)
fmt.Println(res1) //true
fmt.Println(res2) //false
}
```
### <span id="EqualWith">EqualWith</span>
<p>Check if two slices are equal with comparator funcation.comparator signature: func(a interface{}, b interface{}) bool</p>
<b>Signature:</b>
```go
func EqualWith(slice1, slice2 interface{}, comparator interface{}) bool
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
slice1 := []int{1, 2, 3}
slice2 := []int{2, 4, 6}
isDouble := func(a, b int) bool {
return b == a*2
}
res := slice.EqualWith(slice1, slice2, isDouble)
fmt.Println(res) //true
}
```
### <span id="Every">Every</span> ### <span id="Every">Every</span>
<p>Return true if all of the values in the slice pass the predicate function. The function signature should be func(index int, value interface{}) bool.</p> <p>Return true if all of the values in the slice pass the predicate function. The function signature should be func(index int, value interface{}) bool.</p>
@@ -478,8 +577,6 @@ func main() {
### <span id="ForEach">ForEach</span> ### <span id="ForEach">ForEach</span>
<p>Iterates over elements of slice and invokes function for each element, function signature should be func(index int, value interface{}).</p> <p>Iterates over elements of slice and invokes function for each element, function signature should be func(index int, value interface{}).</p>
@@ -619,6 +716,60 @@ func main() {
### <span id="IndexOf">IndexOf</span>
<p>Returns the index at which the first occurrence of a value is found in a slice or return -1 if the value cannot be found.</p>
<b>Signature:</b>
```go
func IndexOf(slice, value interface{}) int
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
arr := []string{"a", "a", "b", "c"}
res1 := slice.IndexOf(arr, "a")
fmt.Println(res1) //0
res2 := slice.IndexOf(arr, "d")
fmt.Println(res2) //-1
}
```
### <span id="LastIndexOf">LastIndexOf</span>
<p>Returns the index at which the last occurrence of a value is found in a slice or return -1 if the value cannot be found.</p>
<b>Signature:</b>
```go
func LastIndexOf(slice, value interface{}) int
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
arr := []string{"a", "a", "b", "c"}
res1 := slice.LastIndexOf(arr, "a")
fmt.Println(res1) //1
res2 := slice.LastIndexOf(arr, "d")
fmt.Println(res2) //-1
}
```
### <span id="InsertByIndex">InsertByIndex</span> ### <span id="InsertByIndex">InsertByIndex</span>
<p>insert the element into slice at index.</p> <p>insert the element into slice at index.</p>
@@ -855,6 +1006,55 @@ func main() {
### <span id="ToSlice">ToSlice</span>
<p>Returns a slices of a variable parameter transformation</p>
<b>Signature:</b>
```go
func ToSlice(value ...interface{}) interface{}
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
res := slice.ToSlice("a", "b")
fmt.Println(res) //{"a", "b"}
}
```
### <span id="ToSlicePointer">ToSlicePointer</span>
<p>Returns a pointer to the slices of a variable parameter transformation</p>
<b>Signature:</b>
```go
func ToSlicePointer(value ...interface{}) []*interface{}
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
str1 := "a"
str2 := "b"
res := slice.ToSlicePointer(str1, str2)
fmt.Println(res) // res -> []*string{&str1, &str2}
}
```
### <span id="Unique">Unique</span> ### <span id="Unique">Unique</span>
<p>Remove duplicate elements in slice.</p> <p>Remove duplicate elements in slice.</p>
@@ -880,7 +1080,33 @@ func main() {
### <span id="Union">Unique</span> ### <span id="UniqueBy">UniqueBy</span>
<p>Call iteratee func with every item of slice, then remove duplicated.</p>
<b>Signature:</b>
```go
func UniqueBy(slice, iteratee interface{}) interface{}
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
res := slice.UniqueBy([]int{1, 2, 3, 4, 5, 6}, func(val int) int {
return val % 4
})
fmt.Println(res) //[]int{1, 2, 3, 0}
}
```
### <span id="Union">Union</span>
<p>Creates a slice of unique values, in order, from all given slices. using == for equality comparisons.</p> <p>Creates a slice of unique values, in order, from all given slices. using == for equality comparisons.</p>
<b>Signature:</b> <b>Signature:</b>

View File

@@ -5,7 +5,7 @@ slice包包含操作切片的方法集合。
## 源码: ## 源码:
[https://github.com/duke-git/lancet/blob/main/slice/slice.go](https://github.com/duke-git/lancet/blob/main/slice/slice.go) [https://github.com/duke-git/lancet/blob/v1/slice/slice.go](https://github.com/duke-git/lancet/blob/v1/slice/slice.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -20,6 +20,7 @@ import (
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 目录 ## 目录
- [AppendIfAbsent](#AppendIfAbsent)
- [Contain](#Contain) - [Contain](#Contain)
- [ContainSubSlice](#ContainSubSlice) - [ContainSubSlice](#ContainSubSlice)
- [Chunk](#Chunk) - [Chunk](#Chunk)
@@ -30,6 +31,8 @@ import (
- [DifferenceBy](#DifferenceBy) - [DifferenceBy](#DifferenceBy)
- [DeleteByIndex](#DeleteByIndex) - [DeleteByIndex](#DeleteByIndex)
- [Drop](#Drop) - [Drop](#Drop)
- [Equal](#Equal)
- [EqualWith](#EqualWith)
- [Every](#Every) - [Every](#Every)
- [Filter](#Filter) - [Filter](#Filter)
- [Find](#Find) - [Find](#Find)
@@ -42,6 +45,8 @@ import (
- [InterfaceSlice](#InterfaceSlice) - [InterfaceSlice](#InterfaceSlice)
- [Intersection](#Intersection) - [Intersection](#Intersection)
- [InsertByIndex](#InsertByIndex) - [InsertByIndex](#InsertByIndex)
- [IndexOf](#IndexOf)
- [LastIndexOf](#LastIndexOf)
- [Map](#Map) - [Map](#Map)
- [ReverseSlice](#ReverseSlice) - [ReverseSlice](#ReverseSlice)
- [Reduce](#Reduce) - [Reduce](#Reduce)
@@ -49,7 +54,10 @@ import (
- [SortByField](#SortByField) - [SortByField](#SortByField)
- [Some](#Some) - [Some](#Some)
- [StringSlice](#StringSlice) - [StringSlice](#StringSlice)
- [ToSlice](#ToSlice)
- [ToSlicePointer](#ToSlicePointer)
- [Unique](#Unique) - [Unique](#Unique)
- [UniqueBy](#UniqueBy)
- [Union](#Union) - [Union](#Union)
- [UpdateByIndex](#UpdateByIndex) - [UpdateByIndex](#UpdateByIndex)
- [Without](#Without) - [Without](#Without)
@@ -58,6 +66,34 @@ import (
## 文档 ## 文档
### <span id="AppendIfAbsent">AppendIfAbsent</span>
<p>当前切片中不包含值时,将该值追加到切片中</p>
<b>函数签名:</b>
```go
func AppendIfAbsent(slice interface{}, value interface{}) interface{}
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
strs := []string{"a", "b"}
res1 := slice.AppendIfAbsent(strs, "a")
fmt.Println(res1) //[]string{"a", "b"}
res2 := slice.AppendIfAbsent(strs, "cannot")
fmt.Println(res2"}
}
```
### <span id="Contain">Contain</span> ### <span id="Contain">Contain</span>
<p>判断slice是否包含value</p> <p>判断slice是否包含value</p>
@@ -329,6 +365,68 @@ func main() {
### <span id="Equal">Equal</span>
<p>检查两个切片是否相等,相等条件:切片长度相同,元素顺序和值都相同</p>
<b>函数签名:</b>
```go
func Equal(slice1, slice2 interface{}) bool
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
slice1 := []int{1, 2, 3}
slice2 := []int{1, 2, 3}
slice3 := []int{3, 2, 1}
res1 := slice.Equal(slice1, slice2)
res2 := slice.Equal(slice1, slice3)
fmt.Println(res1) //true
fmt.Println(res2) //false
}
```
### <span id="EqualWith">EqualWith</span>
<p>检查两个切片是否相等相等条件对两个切片的元素调用比较函数comparator返回true。 comparator函数签名: func(a interface{}, b interface{}) bool</p>
<b>函数签名:</b>
```go
func EqualWith(slice1, slice2 interface{}, comparator interface{}) bool
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
slice1 := []int{1, 2, 3}
slice2 := []int{2, 4, 6}
isDouble := func(a, b int) bool {
return b == a*2
}
res := slice.EqualWith(slice1, slice2, isDouble)
fmt.Println(res) //true
}
```
### <span id="Every">Every</span> ### <span id="Every">Every</span>
<p>如果切片中的所有值都通过谓词函数则返回true。 函数签名应该是func(index int, value interface{}) bool</p> <p>如果切片中的所有值都通过谓词函数则返回true。 函数签名应该是func(index int, value interface{}) bool</p>
@@ -616,6 +714,61 @@ func main() {
### <span id="IndexOf">IndexOf</span>
<p>返回在切片中找到值的第一个匹配项的索引,如果找不到值,则返回-1</p>
<b>函数签名:</b>
```go
func IndexOf(slice, value interface{}) int
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
arr := []string{"a", "a", "b", "c"}
res1 := slice.IndexOf(arr, "a")
fmt.Println(res1) //0
res2 := slice.IndexOf(arr, "d")
fmt.Println(res2) //-1
}
```
### <span id="LastIndexOf">LastIndexOf</span>
<p>返回在切片中找到最后一个值的索引,如果找不到该值,则返回-1</p>
<b>函数签名:</b>
```go
func LastIndexOf(slice, value interface{}) int
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
arr := []string{"a", "a", "b", "c"}
res1 := slice.LastIndexOf(arr, "a")
fmt.Println(res1) //1
res2 := slice.LastIndexOf(arr, "d")
fmt.Println(res2) //-1
}
```
### <span id="InsertByIndex">InsertByIndex</span> ### <span id="InsertByIndex">InsertByIndex</span>
<p>将元素插入到索引处的切片中</p> <p>将元素插入到索引处的切片中</p>
@@ -852,6 +1005,55 @@ func main() {
### <span id="ToSlice">ToSlice</span>
<p>将可变参数转为切片</p>
<b>函数签名:</b>
```go
func ToSlice(value ...interface{}) interface{}
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
res := slice.ToSlice("a", "b")
fmt.Println(res) //{"a", "b"}
}
```
### <span id="ToSlicePointer">ToSlicePointer</span>
<p>将可变参数转为指针切片</p>
<b>函数签名:</b>
```go
func ToSlicePointer(value ...interface{}) []*interface{}
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
str1 := "a"
str2 := "b"
res := slice.ToSlicePointer(str1, str2)
fmt.Println(res) // res -> []*string{&str1, &str2}
}
```
### <span id="Unique">Unique</span> ### <span id="Unique">Unique</span>
<p>删除切片中的重复元素</p> <p>删除切片中的重复元素</p>
@@ -877,7 +1079,32 @@ func main() {
### <span id="Union">Unique</span> ### <span id="UniqueBy">UniqueBy</span>
<p>对切片的每个项目调用iteratee函数然后删除重复的</p>
<b>函数签名:</b>
```go
func UniqueBy(slice, iteratee interface{}) interface{}
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/slice"
)
func main() {
res := slice.UniqueBy([]int{1, 2, 3, 4, 5, 6}, func(val int) int {
return val % 4
})
fmt.Println(res) //[]int{1, 2, 3, 0}
}
```
### <span id="Union">Union</span>
<p>从所有给定的切片按顺序创建一个唯一值切片。 使用 == 进行相等比较。</p> <p>从所有给定的切片按顺序创建一个唯一值切片。 使用 == 进行相等比较。</p>
<b>函数签名:</b> <b>函数签名:</b>

View File

@@ -5,7 +5,7 @@ Package strutil contains some functions to manipulate string.
## Source: ## Source:
[https://github.com/duke-git/lancet/blob/main/strutil/string.go](https://github.com/duke-git/lancet/blob/main/strutil/string.go) [https://github.com/duke-git/lancet/blob/v1/strutil/string.go](https://github.com/duke-git/lancet/blob/v1/strutil/string.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -35,8 +35,9 @@ import (
- [ReverseStr](#ReverseStr) - [ReverseStr](#ReverseStr)
- [SnakeCase](#SnakeCase) - [SnakeCase](#SnakeCase)
- [Wrap](#Wrap) - [Wrap](#Wrap)
- [Unwrap](#Unwrap) - [Unwrap](#Unwrap)
- [SplitEx](#SplitEx)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -566,7 +567,39 @@ func main() {
### <span id="SplitEx">SplitEx</span>
<p>Split a given string whether the result contains empty string.</p>
<b>Signature:</b>
```go
func SplitEx(s, sep string, removeEmptyString bool) []string
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/strutil"
)
func main() {
arr1 := strutil.SplitEx(" a b c ", "", true)
fmt.Println(arr1) //[]string{}
arr2 := strutil.SplitEx(" a b c ", " ", false)
fmt.Println(arr2) //[]string{"", "a", "b", "c", ""}
arr3 := strutil.SplitEx(" a b c ", " ", true)
fmt.Println(arr3) //[]string{"a", "b", "c"}
arr4 := strutil.SplitEx(" a = b = c = ", " = ", false)
fmt.Println(arr4) //[]string{" a", "b", "c", ""}
arr5 := strutil.SplitEx(" a = b = c = ", " = ", true)
fmt.Println(arr5) //[]string{" a", "b", "c"}
}
```

View File

@@ -5,7 +5,7 @@ strutil包含处理字符串的相关函数。
## 源码: ## 源码:
[https://github.com/duke-git/lancet/blob/main/strutil/string.go](https://github.com/duke-git/lancet/blob/main/strutil/string.go) [https://github.com/duke-git/lancet/blob/v1/strutil/string.go](https://github.com/duke-git/lancet/blob/v1/strutil/string.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -37,6 +37,7 @@ import (
- [Wrap](#Wrap) - [Wrap](#Wrap)
- [Unwrap](#Unwrap) - [Unwrap](#Unwrap)
- [SplitEx](#SplitEx)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -567,6 +568,39 @@ func main() {
### <span id="SplitEx">SplitEx</span>
<p>分割字符串为切片removeEmptyString参数指定是否去除空字符串</p>
<b>函数签名:</b>
```go
func SplitEx(s, sep string, removeEmptyString bool) []string
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/strutil"
)
func main() {
arr1 := strutil.SplitEx(" a b c ", "", true)
fmt.Println(arr1) //[]string{}
arr2 := strutil.SplitEx(" a b c ", " ", false)
fmt.Println(arr2) //[]string{"", "a", "b", "c", ""}
arr3 := strutil.SplitEx(" a b c ", " ", true)
fmt.Println(arr3) //[]string{"a", "b", "c"}
arr4 := strutil.SplitEx(" a = b = c = ", " = ", false)
fmt.Println(arr4) //[]string{" a", "b", "c", ""}
arr5 := strutil.SplitEx(" a = b = c = ", " = ", true)
fmt.Println(arr5) //[]string{" a", "b", "c"}
}
```

View File

@@ -5,7 +5,7 @@ Package system contains some functions about os, runtime, shell command.
## Source: ## Source:
[https://github.com/duke-git/lancet/blob/main/system/os.go](https://github.com/duke-git/lancet/blob/main/system/os.go) [https://github.com/duke-git/lancet/blob/v1/system/os.go](https://github.com/duke-git/lancet/blob/v1/system/os.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -28,6 +28,7 @@ import (
- [RemoveOsEnv](#RemoveOsEnv) - [RemoveOsEnv](#RemoveOsEnv)
- [CompareOsEnv](#CompareOsEnv) - [CompareOsEnv](#CompareOsEnv)
- [ExecCommand](#ExecCommand) - [ExecCommand](#ExecCommand)
- [GetOsBits](#GetOsBits)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -235,7 +236,27 @@ func main() {
### <span id="GetOsBits">GetOsBits</span>
<p>获取当前操作系统位数返回32或64</p>
<b>函数签名:</b>
```go
func GetOsBits() int
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/system"
)
func main() {
osBit := system.GetOsBits()
fmt.Println(osBit)
}
```

View File

@@ -5,7 +5,7 @@ system包含os, runtime, shell command相关函数。
## 源码: ## 源码:
[https://github.com/duke-git/lancet/blob/main/system/os.go](https://github.com/duke-git/lancet/blob/main/system/os.go) [https://github.com/duke-git/lancet/blob/v1/system/os.go](https://github.com/duke-git/lancet/blob/v1/system/os.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -28,6 +28,7 @@ import (
- [RemoveOsEnv](#RemoveOsEnv) - [RemoveOsEnv](#RemoveOsEnv)
- [CompareOsEnv](#CompareOsEnv) - [CompareOsEnv](#CompareOsEnv)
- [ExecCommand](#ExecCommand) - [ExecCommand](#ExecCommand)
- [GetOsBits](#GetOsBits)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -235,7 +236,27 @@ func main() {
### <span id="GetOsBits">GetOsBits</span>
<p>Get current os bits, 32bit or 64bit. return 32 or 64</p>
<b>Signature:</b>
```go
func GetOsBits() int
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/system"
)
func main() {
osBit := system.GetOsBits()
fmt.Println(osBit)
}
```

View File

@@ -5,7 +5,7 @@ Package validator contains some functions for data validation.
## Source: ## Source:
[https://github.com/duke-git/lancet/blob/main/validator/validator.go](https://github.com/duke-git/lancet/blob/main/validator/validator.go) [https://github.com/duke-git/lancet/blob/v1/validator/validator.go](https://github.com/duke-git/lancet/blob/v1/validator/validator.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -47,6 +47,7 @@ import (
- [IsStrongPassword](#IsStrongPassword) - [IsStrongPassword](#IsStrongPassword)
- [IsUrl](#IsUrl) - [IsUrl](#IsUrl)
- [IsWeakPassword](#IsWeakPassword) - [IsWeakPassword](#IsWeakPassword)
- [IsZeroValue](#IsZeroValue)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -789,6 +790,37 @@ func main() {
} }
``` ```
### <span id="IsZeroValue">IsZeroValue</span>
<p>Checks if passed value is a zero value.</p>
<b>Signature:</b>
```go
func IsZeroValue(value any) bool
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/validator"
)
func main() {
fmt.Println(validator.IsZeroValue(nil)) //true
fmt.Println(validator.IsZeroValue(0)) //true
fmt.Println(validator.IsZeroValue("")) //true
fmt.Println(validator.IsZeroValue([]int)) //true
fmt.Println(validator.IsZeroValue(interface{})) //true
fmt.Println(validator.IsZeroValue("0")) //false
fmt.Println(validator.IsZeroValue("nil")) //false
}
```

View File

@@ -5,7 +5,7 @@ validator验证器包包含常用字符串格式验证函数。
## 源码: ## 源码:
[https://github.com/duke-git/lancet/blob/main/validator/validator.go](https://github.com/duke-git/lancet/blob/main/validator/validator.go) [https://github.com/duke-git/lancet/blob/v1/validator/validator.go](https://github.com/duke-git/lancet/blob/v1/validator/validator.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -47,6 +47,7 @@ import (
- [IsStrongPassword](#IsStrongPassword) - [IsStrongPassword](#IsStrongPassword)
- [IsUrl](#IsUrl) - [IsUrl](#IsUrl)
- [IsWeakPassword](#IsWeakPassword) - [IsWeakPassword](#IsWeakPassword)
- [IsZeroValue](#IsZeroValue)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -791,6 +792,33 @@ func main() {
### <span id="IsZeroValue">IsZeroValue</span>
<p>判断传入的参数值是否为零值</p>
<b>函数签名:</b>
```go
func IsZeroValue(value any) bool
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/validator"
)
func main() {
fmt.Println(validator.IsZeroValue(nil)) //true
fmt.Println(validator.IsZeroValue(0)) //true
fmt.Println(validator.IsZeroValue("")) //true
fmt.Println(validator.IsZeroValue([]int)) //true
fmt.Println(validator.IsZeroValue(interface{})) //true
fmt.Println(validator.IsZeroValue("0")) //false
fmt.Println(validator.IsZeroValue("nil")) //false
}
```

View File

@@ -13,6 +13,7 @@ import (
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"os" "os"
"path"
"path/filepath" "path/filepath"
"strings" "strings"
) )
@@ -40,6 +41,11 @@ func CreateFile(path string) bool {
return true return true
} }
// CreateDir create directory in absolute path. param `absPath` like /a/, /a/b/
func CreateDir(absPath string) error {
return os.MkdirAll(path.Dir(absPath), os.ModePerm)
}
// IsDir checks if the path is directory or not // IsDir checks if the path is directory or not
func IsDir(path string) bool { func IsDir(path string) bool {
file, err := os.Stat(path) file, err := os.Stat(path)

View File

@@ -33,6 +33,27 @@ func TestCreateFile(t *testing.T) {
os.Remove(f) os.Remove(f)
} }
func TestCreateDir(t *testing.T) {
assert := internal.NewAssert(t, "TestCreateDir")
pwd, err := os.Getwd()
if err != nil {
t.Error(err)
t.FailNow()
}
dirPath := pwd + "/a/"
err = CreateDir(dirPath)
if err != nil {
t.Error(err)
t.FailNow()
}
assert.Equal(true, IsExist(dirPath))
os.Remove(dirPath)
assert.Equal(false, IsExist(dirPath))
}
func TestIsDir(t *testing.T) { func TestIsDir(t *testing.T) {
assert := internal.NewAssert(t, "TestIsDir") assert := internal.NewAssert(t, "TestIsDir")
@@ -79,7 +100,7 @@ func TestListFileNames(t *testing.T) {
filesInPath, err := ListFileNames("../datetime/") filesInPath, err := ListFileNames("../datetime/")
assert.IsNil(err) assert.IsNil(err)
expected := []string{"datetime.go", "datetime_test.go"} expected := []string{"conversion.go", "conversion_test.go", "datetime.go", "datetime_test.go"}
assert.Equal(expected, filesInPath) assert.Equal(expected, filesInPath)
} }

View File

@@ -6,7 +6,8 @@
// HttpGet, HttpPost, HttpDelete, HttpPut, HttpPatch, function param `url` is required. // HttpGet, HttpPost, HttpDelete, HttpPut, HttpPatch, function param `url` is required.
// HttpGet, HttpPost, HttpDelete, HttpPut, HttpPatch, function param `params` is variable, the order is: // HttpGet, HttpPost, HttpDelete, HttpPut, HttpPatch, function param `params` is variable, the order is:
// params[0] is header which type should be http.Header or map[string]string, // params[0] is header which type should be http.Header or map[string]string,
// params[1] is query param which type should be url.Values or map[string]interface{}, // params[1] is query string param which type should be url.Values or map[string]string, when content-type header is
// multipart/form-data or application/x-www-form-urlencoded
// params[2] is post body which type should be []byte. // params[2] is post body which type should be []byte.
// params[3] is http client which type should be http.Client. // params[3] is http client which type should be http.Client.
package netutil package netutil

228
netutil/http_client.go Normal file
View File

@@ -0,0 +1,228 @@
package netutil
import (
"bytes"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"reflect"
"regexp"
"strings"
"time"
"github.com/duke-git/lancet/slice"
)
// HttpRequest struct is a composed http request
type HttpRequest struct {
RawURL string
Method string
Headers http.Header
QueryParams url.Values
FormData url.Values
Body []byte
}
// HttpClientConfig contains some configurations for http client
type HttpClientConfig struct {
SSLEnabled bool
TLSConfig *tls.Config
Compressed bool
HandshakeTimeout time.Duration
ResponseTimeout time.Duration
Verbose bool
}
// defaultHttpClientConfig defalut client config
var defaultHttpClientConfig = &HttpClientConfig{
Compressed: false,
HandshakeTimeout: 20 * time.Second,
ResponseTimeout: 40 * time.Second,
}
// HttpClient is used for sending http request
type HttpClient struct {
*http.Client
TLS *tls.Config
Request *http.Request
Config HttpClientConfig
}
// NewHttpClient make a HttpClient instance
func NewHttpClient() *HttpClient {
client := &HttpClient{
Client: &http.Client{
Transport: &http.Transport{
TLSHandshakeTimeout: defaultHttpClientConfig.HandshakeTimeout,
ResponseHeaderTimeout: defaultHttpClientConfig.ResponseTimeout,
DisableCompression: !defaultHttpClientConfig.Compressed,
},
},
Config: *defaultHttpClientConfig,
}
return client
}
// NewHttpClientWithConfig make a HttpClient instance with pass config
func NewHttpClientWithConfig(config *HttpClientConfig) *HttpClient {
if config == nil {
config = defaultHttpClientConfig
}
client := &HttpClient{
Client: &http.Client{
Transport: &http.Transport{
TLSHandshakeTimeout: config.HandshakeTimeout,
ResponseHeaderTimeout: config.ResponseTimeout,
DisableCompression: !config.Compressed,
},
},
Config: *config,
}
if config.SSLEnabled {
client.TLS = config.TLSConfig
}
return client
}
// SendRequest send http request
func (client *HttpClient) SendRequest(request *HttpRequest) (*http.Response, error) {
err := validateRequest(request)
if err != nil {
return nil, err
}
rawUrl := request.RawURL
req, err := http.NewRequest(request.Method, rawUrl, bytes.NewBuffer(request.Body))
if err != nil {
return nil, err
}
client.setTLS(rawUrl)
client.setHeader(req, request.Headers)
client.setQueryParam(req, rawUrl, request.QueryParams)
if request.FormData != nil {
client.setFormData(req, request.FormData)
}
client.Request = req
resp, err := client.Client.Do(req)
if err != nil {
return nil, err
}
return resp, nil
}
// DecodeResponse decode response into target object
func (client *HttpClient) DecodeResponse(resp *http.Response, target interface{}) error {
if resp == nil {
return errors.New("invalid target param")
}
defer resp.Body.Close()
return json.NewDecoder(resp.Body).Decode(target)
}
// setTLS set http client transport TLSClientConfig
func (client *HttpClient) setTLS(rawUrl string) {
if strings.HasPrefix(rawUrl, "https") {
if transport, ok := client.Client.Transport.(*http.Transport); ok {
transport.TLSClientConfig = client.TLS
}
}
}
// setHeader set http rquest header
func (client *HttpClient) setHeader(req *http.Request, headers http.Header) {
if headers == nil {
headers = make(http.Header)
}
if _, ok := headers["Accept"]; !ok {
headers["Accept"] = []string{"*/*"}
}
if _, ok := headers["Accept-Encoding"]; !ok && client.Config.Compressed {
headers["Accept-Encoding"] = []string{"deflate, gzip"}
}
req.Header = headers
}
// setQueryParam set http request query string param
func (client *HttpClient) setQueryParam(req *http.Request, reqUrl string, queryParam url.Values) error {
if queryParam != nil {
if !strings.Contains(reqUrl, "?") {
reqUrl = reqUrl + "?" + queryParam.Encode()
} else {
reqUrl = reqUrl + "&" + queryParam.Encode()
}
u, err := url.Parse(reqUrl)
if err != nil {
return err
}
req.URL = u
}
return nil
}
func (client *HttpClient) setFormData(req *http.Request, values url.Values) {
formData := []byte(values.Encode())
req.Body = ioutil.NopCloser(bytes.NewReader(formData))
req.ContentLength = int64(len(formData))
}
// validateRequest check if a request has url, and valid method.
func validateRequest(req *HttpRequest) error {
if req.RawURL == "" {
return errors.New("invalid request url")
}
// common HTTP methods
methods := []string{"GET", "POST", "PUT", "DELETE", "PATCH",
"HEAD", "CONNECT", "OPTIONS", "TRACE"}
if !slice.Contain(methods, strings.ToUpper(req.Method)) {
return errors.New("invalid request method")
}
return nil
}
// StructToUrlValues convert struct to url valuse,
// only convert the field which is exported and has `json` tag
func StructToUrlValues(targetStruct interface{}) url.Values {
rv := reflect.ValueOf(targetStruct)
rt := reflect.TypeOf(targetStruct)
if rt.Kind() == reflect.Ptr {
rt = rt.Elem()
}
if rt.Kind() != reflect.Struct {
panic(fmt.Errorf("data type %T not support, shuld be struct or pointer to struct", targetStruct))
}
result := url.Values{}
fieldNum := rt.NumField()
pattern := `^[A-Z]`
regex := regexp.MustCompile(pattern)
for i := 0; i < fieldNum; i++ {
name := rt.Field(i).Name
tag := rt.Field(i).Tag.Get("json")
if regex.MatchString(name) && tag != "" {
result.Add(tag, fmt.Sprintf("%v", rv.Field(i).Interface()))
}
}
return result
}

View File

@@ -0,0 +1,95 @@
package netutil
import (
"io/ioutil"
"log"
"net/http"
"net/url"
"testing"
"github.com/duke-git/lancet/internal"
)
func TestHttpClient_Get(t *testing.T) {
assert := internal.NewAssert(t, "TestHttpClient_Get")
request := &HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos/1",
Method: "GET",
}
httpClient := NewHttpClient()
resp, err := httpClient.SendRequest(request)
if err != nil || resp.StatusCode != 200 {
log.Fatal(err)
}
type Todo struct {
UserId int `json:"userId"`
Id int `json:"id"`
Title string `json:"title"`
Completed bool `json:"completed"`
}
var todo Todo
httpClient.DecodeResponse(resp, &todo)
assert.Equal(1, todo.Id)
}
func TestHttpClent_Post(t *testing.T) {
header := http.Header{}
header.Add("Content-Type", "multipart/form-data")
postData := url.Values{}
postData.Add("userId", "1")
postData.Add("title", "testItem")
request := &HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos",
Method: "POST",
Headers: header,
FormData: postData,
}
httpClient := NewHttpClient()
resp, err := httpClient.SendRequest(request)
if err != nil {
log.Fatal(err)
}
body, _ := ioutil.ReadAll(resp.Body)
t.Log("response: ", resp.StatusCode, string(body))
}
func TestStructToUrlValues(t *testing.T) {
assert := internal.NewAssert(t, "TestStructToUrlValues")
type TodoQuery struct {
Id int `json:"id"`
UserId int `json:"userId"`
}
todoQuery := TodoQuery{
Id: 1,
UserId: 1,
}
todoValues := StructToUrlValues(todoQuery)
assert.Equal("1", todoValues.Get("id"))
assert.Equal("1", todoValues.Get("userId"))
request := &HttpRequest{
RawURL: "https://jsonplaceholder.typicode.com/todos",
Method: "GET",
QueryParams: todoValues,
}
httpClient := NewHttpClient()
resp, err := httpClient.SendRequest(request)
if err != nil || resp.StatusCode != 200 {
log.Fatal(err)
}
body, _ := ioutil.ReadAll(resp.Body)
t.Log("response: ", string(body))
}

View File

@@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"log" "log"
"net/url"
"testing" "testing"
"github.com/duke-git/lancet/internal" "github.com/duke-git/lancet/internal"
@@ -46,6 +47,29 @@ func TestHttpPost(t *testing.T) {
t.Log("response: ", resp.StatusCode, string(body)) t.Log("response: ", resp.StatusCode, string(body))
} }
func TestHttpPostFormData(t *testing.T) {
apiUrl := "https://jsonplaceholder.typicode.com/todos"
header := map[string]string{
// "Content-Type": "application/x-www-form-urlencoded",
"Content-Type": "multipart/form-data",
}
type Todo struct {
UserId int `json:"userId"`
Title string `json:"title"`
}
postData := url.Values{}
postData.Add("userId", "1")
postData.Add("title", "TestAddToDo")
resp, err := HttpPost(apiUrl, header, postData, nil)
if err != nil {
log.Fatal(err)
t.FailNow()
}
body, _ := ioutil.ReadAll(resp.Body)
t.Log("response: ", resp.StatusCode, string(body))
}
func TestHttpPut(t *testing.T) { func TestHttpPut(t *testing.T) {
url := "https://jsonplaceholder.typicode.com/todos/1" url := "https://jsonplaceholder.typicode.com/todos/1"
header := map[string]string{ header := map[string]string{

View File

@@ -5,6 +5,8 @@ import (
"io/ioutil" "io/ioutil"
"net" "net"
"net/http" "net/http"
"net/url"
"strings"
) )
// GetInternalIp return internal ipv4 // GetInternalIp return internal ipv4
@@ -47,6 +49,26 @@ func GetPublicIpInfo() (*PublicIpInfo, error) {
return &ip, nil return &ip, nil
} }
// GetRequestPublicIp return the requested public ip
func GetRequestPublicIp(req *http.Request) string {
var ip string
for _, ip = range strings.Split(req.Header.Get("X-Forwarded-For"), ",") {
if ip = strings.TrimSpace(ip); ip != "" && !IsInternalIP(net.ParseIP(ip)) {
return ip
}
}
if ip = strings.TrimSpace(req.Header.Get("X-Real-Ip")); ip != "" && !IsInternalIP(net.ParseIP(ip)) {
return ip
}
if ip, _, _ = net.SplitHostPort(req.RemoteAddr); !IsInternalIP(net.ParseIP(ip)) {
return ip
}
return ip
}
// GetIps return all ipv4 of system // GetIps return all ipv4 of system
func GetIps() []string { func GetIps() []string {
var ips []string var ips []string
@@ -122,3 +144,29 @@ func IsPublicIP(IP net.IP) bool {
} }
return false return false
} }
// IsInternalIP verify an ip is intranet or not
func IsInternalIP(IP net.IP) bool {
if IP.IsLoopback() {
return true
}
if ip4 := IP.To4(); ip4 != nil {
return ip4[0] == 10 ||
(ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31) ||
(ip4[0] == 169 && ip4[1] == 254) ||
(ip4[0] == 192 && ip4[1] == 168)
}
return false
}
// EncodeUrl encode url
func EncodeUrl(urlStr string) (string, error) {
URL, err := url.Parse(urlStr)
if err != nil {
return "", err
}
URL.RawQuery = URL.Query().Encode()
return URL.String(), nil
}

View File

@@ -41,6 +41,7 @@ func doHttpRequest(method, reqUrl string, params ...interface{}) (*http.Response
return nil, err return nil, err
} }
case 3: case 3:
err := setHeaderAndQueryAndBody(req, reqUrl, params[0], params[1], params[2]) err := setHeaderAndQueryAndBody(req, reqUrl, params[0], params[1], params[2])
if err != nil { if err != nil {
return nil, err return nil, err
@@ -81,7 +82,21 @@ func setHeaderAndQueryAndBody(req *http.Request, reqUrl string, header, queryPar
if err != nil { if err != nil {
return err return err
} }
err = setBodyByte(req, body) if strings.Contains(req.Header.Get("Content-Type"), "multipart/form-data") || req.Header.Get("Content-Type") == "application/x-www-form-urlencoded" {
if formData, ok := queryParam.(url.Values); ok {
err = setBodyByte(req, []byte(formData.Encode()))
}
if formData, ok := queryParam.(map[string]string); ok {
postData := url.Values{}
for k, v := range formData {
postData.Set(k, v)
}
err = setBodyByte(req, []byte(postData.Encode()))
}
} else {
err = setBodyByte(req, body)
}
if err != nil { if err != nil {
return err return err
} }

View File

@@ -167,15 +167,15 @@ func Difference(slice1, slice2 interface{}) interface{} {
// DifferenceBy it accepts iteratee which is invoked for each element of slice // DifferenceBy it accepts iteratee which is invoked for each element of slice
// and values to generate the criterion by which they're compared. // and values to generate the criterion by which they're compared.
// like lodash.js differenceBy: https://lodash.com/docs/4.17.15#differenceBy, // like lodash.js differenceBy: https://lodash.com/docs/4.17.15#differenceBy,
// the iterateeFn function signature should be func(index int, value interface{}) interface{}. // the iteratee function signature should be func(index int, value interface{}) interface{}.
func DifferenceBy(slice interface{}, comparedSlice interface{}, iterateeFn interface{}) interface{} { func DifferenceBy(slice interface{}, comparedSlice interface{}, iteratee interface{}) interface{} {
sv := sliceValue(slice) sv := sliceValue(slice)
smv := sliceValue(comparedSlice) smv := sliceValue(comparedSlice)
fn := functionValue(iterateeFn) fn := functionValue(iteratee)
elemType := sv.Type().Elem() elemType := sv.Type().Elem()
if checkSliceCallbackFuncSignature(fn, elemType, nil) { if checkSliceCallbackFuncSignature(fn, elemType, nil) {
panic("function param should be of type func(" + elemType.String() + ")" + elemType.String()) panic("iteratee function signature should be func(" + elemType.String() + ")" + elemType.String())
} }
slice1 := reflect.MakeSlice(sv.Type(), sv.Len(), sv.Len()) slice1 := reflect.MakeSlice(sv.Type(), sv.Len(), sv.Len())
@@ -203,15 +203,57 @@ func DifferenceBy(slice interface{}, comparedSlice interface{}, iterateeFn inter
return res.Interface() return res.Interface()
} }
// Equal checks if two slices are equal: the same length and all elements' order and value are equal
func Equal(slice1, slice2 interface{}) bool {
sv1 := sliceValue(slice1)
sv2 := sliceValue(slice2)
if sv1.Type().Elem() != sv2.Type().Elem() {
return false
}
if sv1.Len() != sv2.Len() {
return false
}
for i := 0; i < sv1.Len(); i++ {
if sv1.Index(i).Interface() != sv2.Index(i).Interface() {
return false
}
}
return true
}
// EqualWith checks if two slices are equal with comparator func
func EqualWith(slice1, slice2 interface{}, comparator interface{}) bool {
sv1 := sliceValue(slice1)
sv2 := sliceValue(slice2)
fn := functionValue(comparator)
// elemType1 := sv1.Type().Elem()
// elemType2 := sv2.Type().Elem()
// todo: check fn signature: func(a elemType1.Kind(), b elemType2.Kind()) bool
for i := 0; i < sv1.Len(); i++ {
flag := fn.Call([]reflect.Value{sv1.Index(i), sv2.Index(i)})[0]
if !flag.Bool() {
return false
}
}
return true
}
// Every return true if all of the values in the slice pass the predicate function. // Every return true if all of the values in the slice pass the predicate function.
// The function signature should be func(index int, value interface{}) bool . // The iteratee function signature should be func(index int, value interface{}) bool .
func Every(slice, function interface{}) bool { func Every(slice, function interface{}) bool {
sv := sliceValue(slice) sv := sliceValue(slice)
fn := functionValue(function) fn := functionValue(function)
elemType := sv.Type().Elem() elemType := sv.Type().Elem()
if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) { if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) {
panic("function param should be of type func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String()) panic("iteratee function signature should be func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String())
} }
var currentLength int var currentLength int
@@ -226,14 +268,14 @@ func Every(slice, function interface{}) bool {
} }
// None return true if all the values in the slice mismatch the criteria // None return true if all the values in the slice mismatch the criteria
// The function signature should be func(index int, value interface{}) bool . // The iteratee function signature should be func(index int, value interface{}) bool .
func None(slice, function interface{}) bool { func None(slice, iteratee interface{}) bool {
sv := sliceValue(slice) sv := sliceValue(slice)
fn := functionValue(function) fn := functionValue(iteratee)
elemType := sv.Type().Elem() elemType := sv.Type().Elem()
if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) { if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) {
panic("function param should be of type func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String()) panic("iteratee function signature should be func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String())
} }
var currentLength int var currentLength int
@@ -248,14 +290,14 @@ func None(slice, function interface{}) bool {
} }
// Some return true if any of the values in the list pass the predicate function. // Some return true if any of the values in the list pass the predicate function.
// The function signature should be func(index int, value interface{}) bool . // The iteratee function signature should be func(index int, value interface{}) bool .
func Some(slice, function interface{}) bool { func Some(slice, iteratee interface{}) bool {
sv := sliceValue(slice) sv := sliceValue(slice)
fn := functionValue(function) fn := functionValue(iteratee)
elemType := sv.Type().Elem() elemType := sv.Type().Elem()
if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) { if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) {
panic("function param should be of type func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String()) panic("iteratee function signature should be func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String())
} }
has := false has := false
@@ -270,14 +312,14 @@ func Some(slice, function interface{}) bool {
} }
// Filter iterates over elements of slice, returning an slice of all elements `signature` returns truthy for. // Filter iterates over elements of slice, returning an slice of all elements `signature` returns truthy for.
// The function signature should be func(index int, value interface{}) bool . // The iteratee function signature should be func(index int, value interface{}) bool .
func Filter(slice, function interface{}) interface{} { func Filter(slice, iteratee interface{}) interface{} {
sv := sliceValue(slice) sv := sliceValue(slice)
fn := functionValue(function) fn := functionValue(iteratee)
elemType := sv.Type().Elem() elemType := sv.Type().Elem()
if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) { if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) {
panic("function param should be of type func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String()) panic("iteratee function signature should be func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String())
} }
res := reflect.MakeSlice(sv.Type(), 0, 0) res := reflect.MakeSlice(sv.Type(), 0, 0)
@@ -292,14 +334,14 @@ func Filter(slice, function interface{}) interface{} {
} }
// Count iterates over elements of slice, returns a count of all matched elements // Count iterates over elements of slice, returns a count of all matched elements
// The function signature should be func(index int, value interface{}) bool . // The iteratee function signature should be func(index int, value interface{}) bool .
func Count(slice, function interface{}) int { func Count(slice, iteratee interface{}) int {
sv := sliceValue(slice) sv := sliceValue(slice)
fn := functionValue(function) fn := functionValue(iteratee)
elemType := sv.Type().Elem() elemType := sv.Type().Elem()
if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) { if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) {
panic("function param should be of type func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String()) panic("iteratee function signature should be func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String())
} }
var counter int var counter int
@@ -314,14 +356,14 @@ func Count(slice, function interface{}) int {
} }
// GroupBy iterate over elements of the slice, each element will be group by criteria, returns two slices // GroupBy iterate over elements of the slice, each element will be group by criteria, returns two slices
// The function signature should be func(index int, value interface{}) bool . // The iteratee function signature should be func(index int, value interface{}) bool .
func GroupBy(slice, function interface{}) (interface{}, interface{}) { func GroupBy(slice, iteratee interface{}) (interface{}, interface{}) {
sv := sliceValue(slice) sv := sliceValue(slice)
fn := functionValue(function) fn := functionValue(iteratee)
elemType := sv.Type().Elem() elemType := sv.Type().Elem()
if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) { if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) {
panic("function param should be of type func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String()) panic("iteratee function signature should be func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String())
} }
groupB := reflect.MakeSlice(sv.Type(), 0, 0) groupB := reflect.MakeSlice(sv.Type(), 0, 0)
@@ -340,14 +382,14 @@ func GroupBy(slice, function interface{}) (interface{}, interface{}) {
} }
// Find iterates over elements of slice, returning the first one that passes a truth test on function. // Find iterates over elements of slice, returning the first one that passes a truth test on function.
// The function signature should be func(index int, value interface{}) bool . // The predicate function signature should be func(index int, value interface{}) bool .
func Find(slice, function interface{}) (interface{}, bool) { func Find(slice, predicate interface{}) (interface{}, bool) {
sv := sliceValue(slice) sv := sliceValue(slice)
fn := functionValue(function) fn := functionValue(predicate)
elemType := sv.Type().Elem() elemType := sv.Type().Elem()
if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) { if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) {
panic("function param should be of type func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String()) panic("predicate function signature should be func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String())
} }
index := -1 index := -1
@@ -369,13 +411,13 @@ func Find(slice, function interface{}) (interface{}, bool) {
// FindLast iterates over elements of slice from end to begin, returning the first one that passes a truth test on function. // FindLast iterates over elements of slice from end to begin, returning the first one that passes a truth test on function.
// The function signature should be func(index int, value interface{}) bool . // The function signature should be func(index int, value interface{}) bool .
func FindLast(slice, function interface{}) (interface{}, bool) { func FindLast(slice, predicate interface{}) (interface{}, bool) {
sv := sliceValue(slice) sv := sliceValue(slice)
fn := functionValue(function) fn := functionValue(predicate)
elemType := sv.Type().Elem() elemType := sv.Type().Elem()
if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) { if checkSliceCallbackFuncSignature(fn, elemType, reflect.ValueOf(true).Type()) {
panic("function param should be of type func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String()) panic("predicate function signature should be func(int, " + elemType.String() + ")" + reflect.ValueOf(true).Type().String())
} }
index := -1 index := -1
@@ -420,14 +462,14 @@ func flattenRecursive(value reflect.Value, result reflect.Value) reflect.Value {
} }
// ForEach iterates over elements of slice and invokes function for each element // ForEach iterates over elements of slice and invokes function for each element
// The function signature should be func(index int, value interface{}). // The iteratee function signature should be func(index int, value interface{}).
func ForEach(slice, function interface{}) { func ForEach(slice, iteratee interface{}) {
sv := sliceValue(slice) sv := sliceValue(slice)
fn := functionValue(function) fn := functionValue(iteratee)
elemType := sv.Type().Elem() elemType := sv.Type().Elem()
if checkSliceCallbackFuncSignature(fn, elemType, nil) { if checkSliceCallbackFuncSignature(fn, elemType, nil) {
panic("function param should be of type func(int, " + elemType.String() + ")" + elemType.String()) panic("iteratee function signature should be func(int, " + elemType.String() + ")" + elemType.String())
} }
for i := 0; i < sv.Len(); i++ { for i := 0; i < sv.Len(); i++ {
@@ -436,14 +478,14 @@ func ForEach(slice, function interface{}) {
} }
// Map creates an slice of values by running each element of `slice` thru `function`. // Map creates an slice of values by running each element of `slice` thru `function`.
// The function signature should be func(index int, value interface{}) interface{}. // The iteratee function signature should be func(index int, value interface{}) interface{}.
func Map(slice, function interface{}) interface{} { func Map(slice, iteratee interface{}) interface{} {
sv := sliceValue(slice) sv := sliceValue(slice)
fn := functionValue(function) fn := functionValue(iteratee)
elemType := sv.Type().Elem() elemType := sv.Type().Elem()
if checkSliceCallbackFuncSignature(fn, elemType, nil) { if checkSliceCallbackFuncSignature(fn, elemType, nil) {
panic("function param should be of type func(int, " + elemType.String() + ")" + elemType.String()) panic("iteratee function signature should be func(int, " + elemType.String() + ")" + elemType.String())
} }
res := reflect.MakeSlice(sv.Type(), sv.Len(), sv.Len()) res := reflect.MakeSlice(sv.Type(), sv.Len(), sv.Len())
@@ -599,7 +641,6 @@ func InsertByIndex(slice interface{}, index int, value interface{}) (interface{}
return slice, errors.New("InvalidSliceIndex") return slice, errors.New("InvalidSliceIndex")
} }
// value is slice
vv := reflect.ValueOf(value) vv := reflect.ValueOf(value)
if vv.Kind() == reflect.Slice { if vv.Kind() == reflect.Slice {
if reflect.TypeOf(slice).Elem() != reflect.TypeOf(value).Elem() { if reflect.TypeOf(slice).Elem() != reflect.TypeOf(value).Elem() {
@@ -609,7 +650,6 @@ func InsertByIndex(slice interface{}, index int, value interface{}) (interface{}
return v.Interface(), nil return v.Interface(), nil
} }
// value is not slice
if reflect.TypeOf(slice).Elem() != reflect.TypeOf(value) { if reflect.TypeOf(slice).Elem() != reflect.TypeOf(value) {
return slice, errors.New("InvalidValueType") return slice, errors.New("InvalidValueType")
} }
@@ -667,21 +707,28 @@ func Unique(slice interface{}) interface{} {
for i := 0; i < len(temp); i++ { for i := 0; i < len(temp); i++ {
res.Index(i).Set(reflect.ValueOf(temp[i])) res.Index(i).Set(reflect.ValueOf(temp[i]))
} }
return res.Interface() return res.Interface()
}
// if use map filter, the result slice element order is random, not same as origin slice // UniqueBy call iteratee func with every item of slice, then remove duplicated.
//mp := make(map[interface{}]bool) // The iteratee function signature should be func(value interface{}) interface{}.
//for i := 0; i < sv.Len(); i++ { func UniqueBy(slice, iteratee interface{}) interface{} {
// v := sv.Index(i).Interface() sv := sliceValue(slice)
// mp[v] = true fn := functionValue(iteratee)
//}
//
//var res []interface{}
//for k := range mp {
// res = append(res, mp[k])
//}
//return res
if sv.Len() == 0 {
return slice
}
res := reflect.MakeSlice(sv.Type(), sv.Len(), sv.Len())
for i := 0; i < sv.Len(); i++ {
val := fn.Call([]reflect.Value{sv.Index(i)})[0]
res.Index(i).Set(val)
}
return Unique(res.Interface())
} }
// Union creates a slice of unique values, in order, from all given slices. using == for equality comparisons. // Union creates a slice of unique values, in order, from all given slices. using == for equality comparisons.
@@ -860,3 +907,64 @@ func Without(slice interface{}, values ...interface{}) interface{} {
return res.Interface() return res.Interface()
} }
// IndexOf returns the index at which the first occurrence of a value is found in a slice or return -1
// if the value cannot be found.
func IndexOf(slice, value interface{}) int {
sv := sliceValue(slice)
for i := 0; i < sv.Len(); i++ {
if reflect.DeepEqual(sv.Index(i).Interface(), value) {
return i
}
}
return -1
}
// LastIndexOf returns the index at which the last occurrence of a value is found in a slice or return -1
// if the value cannot be found.
func LastIndexOf(slice, value interface{}) int {
sv := sliceValue(slice)
for i := sv.Len() - 1; i > 0; i-- {
if reflect.DeepEqual(sv.Index(i).Interface(), value) {
return i
}
}
return -1
}
// ToSlicePointer returns a pointer to the slices of a variable parameter transformation
func ToSlicePointer(value ...interface{}) []*interface{} {
out := make([]*interface{}, len(value))
for i := range value {
out[i] = &value[i]
}
return out
}
// ToSlice returns a slices of a variable parameter transformation
func ToSlice(value ...interface{}) interface{} {
rv := reflect.ValueOf(value)
out := reflect.MakeSlice(rv.Type(), len(value), len(value))
for i := range value {
out.Index(i).Set(reflect.ValueOf(value[i]))
}
return out.Interface()
}
// AppendIfAbsent only absent append the value
func AppendIfAbsent(slice interface{}, value interface{}) interface{} {
sv := sliceValue(slice)
out := reflect.MakeSlice(sv.Type(), sv.Len(), sv.Len())
for i := 0; i < sv.Len(); i++ {
out.Index(i).Set(sv.Index(i))
}
if !Contain(slice, value) {
out = reflect.Append(out, reflect.ValueOf(value))
}
return out.Interface()
}

View File

@@ -73,6 +73,30 @@ func TestConcat(t *testing.T) {
assert.Equal([]int{1, 2, 3, 4, 5}, Concat([]int{1, 2, 3}, []int{4}, 5)) assert.Equal([]int{1, 2, 3, 4, 5}, Concat([]int{1, 2, 3}, []int{4}, 5))
} }
func TestEqual(t *testing.T) {
assert := internal.NewAssert(t, "TestEqual")
slice1 := []int{1, 2, 3}
slice2 := []int{1, 2, 3}
slice3 := []int{3, 2, 1}
assert.Equal(true, Equal(slice1, slice2))
assert.Equal(false, Equal(slice1, slice3))
}
func TestEqualWith(t *testing.T) {
assert := internal.NewAssert(t, "TestEqualWith")
slice1 := []int{1, 2, 3}
slice2 := []int{2, 4, 6}
isDouble := func(a, b int) bool {
return b == a*2
}
assert.Equal(true, EqualWith(slice1, slice2, isDouble))
}
func TestEvery(t *testing.T) { func TestEvery(t *testing.T) {
nums := []int{1, 2, 3, 5} nums := []int{1, 2, 3, 5}
isEven := func(i, num int) bool { isEven := func(i, num int) bool {
@@ -394,6 +418,15 @@ func TestUnique(t *testing.T) {
assert.Equal([]string{"a", "b", "c"}, Unique([]string{"a", "a", "b", "c"})) assert.Equal([]string{"a", "b", "c"}, Unique([]string{"a", "a", "b", "c"}))
} }
func TestUniqueBy(t *testing.T) {
assert := internal.NewAssert(t, "TestUniqueBy")
actual := UniqueBy([]int{1, 2, 3, 4, 5, 6}, func(val int) int {
return val % 4
})
assert.Equal([]int{1, 2, 3, 0}, actual)
}
func TestUnion(t *testing.T) { func TestUnion(t *testing.T) {
assert := internal.NewAssert(t, "TestUnion") assert := internal.NewAssert(t, "TestUnion")
@@ -543,3 +576,51 @@ func TestShuffle(t *testing.T) {
assert.Equal(true, Contain(res, 4)) assert.Equal(true, Contain(res, 4))
assert.Equal(true, Contain(res, 5)) assert.Equal(true, Contain(res, 5))
} }
func TestIndexOf(t *testing.T) {
assert := internal.NewAssert(t, "TestIndexOf")
arr := []string{"a", "a", "b", "c"}
assert.Equal(0, IndexOf(arr, "a"))
assert.Equal(-1, IndexOf(arr, "d"))
}
func TestLastIndexOf(t *testing.T) {
assert := internal.NewAssert(t, "TestLastIndexOf")
arr := []string{"a", "a", "b", "c"}
assert.Equal(1, LastIndexOf(arr, "a"))
assert.Equal(-1, LastIndexOf(arr, "d"))
}
func TestToSlice(t *testing.T) {
assert := internal.NewAssert(t, "TestToSlice")
str1 := "a"
str2 := "b"
out1 := ToSlice(str1)
out2 := ToSlice(str1, str2)
assert.Equal([]string{"a"}, StringSlice(out1))
assert.Equal([]string{"a", "b"}, StringSlice(out2))
}
func TestToSlicePointer(t *testing.T) {
assert := internal.NewAssert(t, "TestToSlicePointer")
var str1 interface{}
str1 = "a"
var str2 interface{}
str2 = "b"
assert.Equal([]*interface{}{&str1}, ToSlicePointer(str1))
assert.Equal([]*interface{}{&str1, &str2}, ToSlicePointer(str1, str2))
}
func TestAppendIfAbsent(t *testing.T) {
assert := internal.NewAssert(t, "TestToAppendIfAbsent")
str1 := []string{"a", "b"}
assert.Equal([]string{"a", "b"}, AppendIfAbsent(str1, "a"))
assert.Equal([]string{"a", "b", "c"}, AppendIfAbsent(str1, "c"))
}

View File

@@ -209,8 +209,8 @@ func IsString(v interface{}) bool {
} }
} }
// ReverseStr return string whose char order is reversed to the given string // Reverse return string whose char order is reversed to the given string
func ReverseStr(s string) string { func Reverse(s string) string {
r := []rune(s) r := []rune(s)
for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 { for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i] r[i], r[j] = r[j], r[i]
@@ -248,3 +248,52 @@ func Unwrap(str string, wrapToken string) string {
return str return str
} }
// SplitEx split a given string whether the result contains empty string
func SplitEx(s, sep string, removeEmptyString bool) []string {
if sep == "" {
return []string{}
}
n := strings.Count(s, sep) + 1
a := make([]string, n)
n--
i := 0
sepSave := 0
ignore := false
for i < n {
m := strings.Index(s, sep)
if m < 0 {
break
}
ignore = false
if removeEmptyString {
if s[:m+sepSave] == "" {
ignore = true
}
}
if !ignore {
a[i] = s[:m+sepSave]
s = s[m+len(sep):]
i++
} else {
s = s[m+len(sep):]
}
}
var ret []string
if removeEmptyString {
if s != "" {
a[i] = s
ret = a[:i+1]
} else {
ret = a[:i]
}
} else {
a[i] = s
ret = a[:i+1]
}
return ret
}

View File

@@ -143,11 +143,11 @@ func TestIsString(t *testing.T) {
assert.Equal(false, IsString([]string{})) assert.Equal(false, IsString([]string{}))
} }
func TestReverseStr(t *testing.T) { func TestReverse(t *testing.T) {
assert := internal.NewAssert(t, "TestReverseStr") assert := internal.NewAssert(t, "TestReverse")
assert.Equal("cba", ReverseStr("abc")) assert.Equal("cba", Reverse("abc"))
assert.Equal("54321", ReverseStr("12345")) assert.Equal("54321", Reverse("12345"))
} }
func TestWrap(t *testing.T) { func TestWrap(t *testing.T) {
@@ -177,3 +177,15 @@ func TestUnwrap(t *testing.T) {
assert.Equal("***", Unwrap("***", "**")) assert.Equal("***", Unwrap("***", "**"))
assert.Equal("**", Unwrap("**", "**")) assert.Equal("**", Unwrap("**", "**"))
} }
func TestSplitEx(t *testing.T) {
assert := internal.NewAssert(t, "TestSplitEx")
assert.Equal([]string{}, SplitEx(" a b c ", "", true))
assert.Equal([]string{"", "a", "b", "c", ""}, SplitEx(" a b c ", " ", false))
assert.Equal([]string{"a", "b", "c"}, SplitEx(" a b c ", " ", true))
assert.Equal([]string{" a", "b", "c", ""}, SplitEx(" a = b = c = ", " = ", false))
assert.Equal([]string{" a", "b", "c"}, SplitEx(" a = b = c = ", " = ", true))
}

View File

@@ -70,3 +70,9 @@ func ExecCommand(command string) (stdout, stderr string, err error) {
return return
} }
// GetOsBits get this system bits 32bit or 64bit
// return bit int (32/64)
func GetOsBits() int {
return 32 << (^uint(0) >> 63)
}

View File

@@ -60,3 +60,13 @@ func TestExecCommand(t *testing.T) {
assert.IsNotNil(err) assert.IsNotNil(err)
} }
} }
func TestGetOsBits(t *testing.T) {
osBits := GetOsBits()
switch osBits {
case 32, 64:
t.Logf("os is %d", osBits)
default:
t.Error("os is not 32 or 64 bits")
}
}

View File

@@ -8,6 +8,7 @@ import (
"encoding/json" "encoding/json"
"net" "net"
"net/url" "net/url"
"reflect"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
@@ -258,3 +259,32 @@ func IsWeakPassword(password string) bool {
return (num || letter) && !special return (num || letter) && !special
} }
// IsZeroValue checks if value is a zero value
func IsZeroValue(value interface{}) bool {
if value == nil {
return true
}
rv := reflect.ValueOf(value)
if !rv.IsValid() {
return true
}
switch rv.Kind() {
case reflect.String:
return rv.Len() == 0
case reflect.Bool:
return !rv.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return rv.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return rv.Uint() == 0
case reflect.Float32, reflect.Float64:
return rv.Float() == 0
case reflect.Ptr, reflect.Chan, reflect.Func, reflect.Interface, reflect.Slice, reflect.Map:
return rv.IsNil()
}
return reflect.DeepEqual(rv.Interface(), reflect.Zero(rv.Type()).Interface())
}

View File

@@ -1,7 +1,9 @@
package validator package validator
import ( import (
"fmt"
"testing" "testing"
"time"
"github.com/duke-git/lancet/internal" "github.com/duke-git/lancet/internal"
) )
@@ -279,3 +281,110 @@ func TestIsWeakPassword(t *testing.T) {
assert.Equal(true, IsWeakPassword("abcABC123")) assert.Equal(true, IsWeakPassword("abcABC123"))
assert.Equal(false, IsWeakPassword("abc123@#$")) assert.Equal(false, IsWeakPassword("abc123@#$"))
} }
func TestIsZeroValue(t *testing.T) {
assert := internal.NewAssert(t, "TestIsZeroValue")
var (
zeroPtr *string
zeroSlice []int
zeroFunc func() string
zeroMap map[string]string
nilIface interface{}
zeroIface fmt.Formatter
)
zeroValues := []interface{}{
nil,
false,
0,
int8(0),
int16(0),
int32(0),
int64(0),
uint(0),
uint8(0),
uint16(0),
uint32(0),
uint64(0),
0.0,
float32(0.0),
float64(0.0),
"",
// func
zeroFunc,
// array / slice
[0]int{},
zeroSlice,
// map
zeroMap,
// interface
nilIface,
zeroIface,
// pointer
zeroPtr,
// struct
time.Time{},
}
for _, value := range zeroValues {
assert.Equal(true, IsZeroValue(value))
}
var nonZeroIface fmt.Stringer = time.Now()
nonZeroValues := []interface{}{
// bool
true,
// int
1,
int8(1),
int16(1),
int32(1),
int64(1),
uint8(1),
uint16(1),
uint32(1),
uint64(1),
// float
1.0,
float32(1.0),
float64(1.0),
// string
"test",
// func
time.Now,
// array / slice
[]int{},
[]int{42},
[1]int{42},
// map
make(map[string]string, 1),
// interface
nonZeroIface,
// pointer
&nonZeroIface,
// struct
time.Now(),
}
for _, value := range nonZeroValues {
assert.Equal(false, IsZeroValue(value))
}
}