From 349f8b6c97f535243ddcda5ed569ba96b0c324c8 Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Thu, 27 Jan 2022 10:55:37 +0800
Subject: [PATCH 01/34] test: add some cases for convertor test
---
.gitignore | 3 ++-
convertor/convertor_test.go | 4 ++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/.gitignore b/.gitignore
index fce5a7c..6210f5f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,4 +6,5 @@ fileutil/*.txt
fileutil/*.zip
fileutil/*.link
fileutil/unzip/*
-cryptor/*.pem
\ No newline at end of file
+cryptor/*.pem
+docs/*
\ No newline at end of file
diff --git a/convertor/convertor_test.go b/convertor/convertor_test.go
index b7fedca..90b0d6d 100644
--- a/convertor/convertor_test.go
+++ b/convertor/convertor_test.go
@@ -24,8 +24,8 @@ func TestToChar(t *testing.T) {
func TestToBool(t *testing.T) {
assert := internal.NewAssert(t, "TestToBool")
- cases := []string{"true", "True", "false", "False", "0", "1", "123"}
- expected := []bool{true, true, false, false, false, true, false}
+ cases := []string{"1", "true", "True", "false", "False", "0", "123", "0.0", "abc"}
+ expected := []bool{true, true, true, false, false, false, false, false, false}
for i := 0; i < len(cases); i++ {
actual, _ := ToBool(cases[i])
From 0b93fbffd9edb0ba86ede6ed9c61fd965f95ad2a Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Thu, 27 Jan 2022 11:13:19 +0800
Subject: [PATCH 02/34] fix: fix misspell in readme file
---
README.md | 2 +-
README_zh-CN.md | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 1d10615..2c2844d 100644
--- a/README.md
+++ b/README.md
@@ -96,7 +96,7 @@ func StructToMap(value interface{}) (map[string]interface{}, error) //convert st
### 2. cryptor is for data encryption and decryption
-- Support md5, hmac, aes, des, ras.
+- Support md5, hmac, aes, des, rsa.
- Usage: import "github.com/duke-git/lancet/cryptor"
```go
diff --git a/README_zh-CN.md b/README_zh-CN.md
index 6c65093..97b6474 100644
--- a/README_zh-CN.md
+++ b/README_zh-CN.md
@@ -96,7 +96,7 @@ func StructToMap(value interface{}) (map[string]interface{}, error) //struct串
### 2. cryptor加解密包
-- 加密函数支持md5, hmac, aes, des, ras
+- 加密函数支持md5, hmac, aes, des, rsa
- 导入包:import "github.com/duke-git/lancet/cryptor"
```go
From 51bd974cc968e24f4476a73129a66559f579c8eb Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Thu, 27 Jan 2022 20:09:42 +0800
Subject: [PATCH 03/34] refactor: make some code cleaner
---
cryptor/des.go | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/cryptor/des.go b/cryptor/des.go
index bb537fd..3c238b4 100644
--- a/cryptor/des.go
+++ b/cryptor/des.go
@@ -19,10 +19,12 @@ func DesEcbEncrypt(data, key []byte) []byte {
length := (len(data) + des.BlockSize) / des.BlockSize
plain := make([]byte, length*des.BlockSize)
copy(plain, data)
+
pad := byte(len(plain) - len(data))
for i := len(data); i < len(plain); i++ {
plain[i] = pad
}
+
encrypted := make([]byte, len(plain))
for bs, be := 0, cipher.BlockSize(); bs <= len(data); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
cipher.Encrypt(encrypted[bs:be], plain[bs:be])
@@ -36,7 +38,7 @@ func DesEcbEncrypt(data, key []byte) []byte {
func DesEcbDecrypt(encrypted, key []byte) []byte {
cipher, _ := des.NewCipher(generateDesKey(key))
decrypted := make([]byte, len(encrypted))
- //
+
for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
cipher.Decrypt(decrypted[bs:be], encrypted[bs:be])
}
@@ -59,6 +61,7 @@ func DesCbcEncrypt(data, key []byte) []byte {
encrypted := make([]byte, len(data))
blockMode.CryptBlocks(encrypted, data)
+
return encrypted
}
@@ -72,6 +75,7 @@ func DesCbcDecrypt(encrypted, key []byte) []byte {
decrypted := make([]byte, len(encrypted))
blockMode.CryptBlocks(decrypted, encrypted)
decrypted = pkcs7UnPadding(decrypted)
+
return decrypted
}
@@ -105,6 +109,7 @@ func DesCfbEncrypt(data, key []byte) []byte {
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(encrypted[des.BlockSize:], data)
+
return encrypted
}
@@ -120,6 +125,7 @@ func DesCfbDecrypt(encrypted, key []byte) []byte {
stream := cipher.NewCFBDecrypter(block, iv)
stream.XORKeyStream(encrypted, encrypted)
+
return encrypted
}
@@ -139,6 +145,7 @@ func DesOfbEncrypt(data, key []byte) []byte {
stream := cipher.NewOFB(block, iv)
stream.XORKeyStream(encrypted[des.BlockSize:], data)
+
return encrypted
}
@@ -161,6 +168,6 @@ func DesOfbDecrypt(data, key []byte) []byte {
mode.XORKeyStream(decrypted, data)
decrypted = pkcs7UnPadding(decrypted)
- return decrypted
+ return decrypted
}
From c40ac9bb9b0df1e04d14a3e39498becf5ae72c9d Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Fri, 28 Jan 2022 10:51:40 +0800
Subject: [PATCH 04/34] refactor: add error value return for GenerateRsaKey
func
---
README.md | 2 +-
README_zh-CN.md | 2 +-
cryptor/rsa.go | 10 ++++++----
cryptor/rsa_test.go | 5 ++++-
4 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/README.md b/README.md
index 2c2844d..5be795c 100644
--- a/README.md
+++ b/README.md
@@ -147,7 +147,7 @@ func Md5File(filename string) (string, error) //return the md5 value of file
func Sha1(data string) string //get sha1 value
func Sha256(data string) string //getsha256 value
func Sha512(data string) string //get sha512 value
-func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) //generate RSA pem file
+func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) error //generate RSA pem file
func RsaEncrypt(data []byte, pubKeyFileName string) []byte //RSA encrypt
func RsaDecrypt(data []byte, privateKeyFileName string) []byte //RSA decrypt
diff --git a/README_zh-CN.md b/README_zh-CN.md
index 97b6474..86ca0ac 100644
--- a/README_zh-CN.md
+++ b/README_zh-CN.md
@@ -147,7 +147,7 @@ func Md5File(filename string) (string, error) //获取文件md5值
func Sha1(data string) string //获取sha1值
func Sha256(data string) string //获取sha256值
func Sha512(data string) string //获取sha512值
-func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) //生成RSA私钥文件
+func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) error //生成RSA私钥文件
func RsaEncrypt(data []byte, pubKeyFileName string) []byte //RSA加密
func RsaDecrypt(data []byte, privateKeyFileName string) []byte //RSA解密
diff --git a/cryptor/rsa.go b/cryptor/rsa.go
index ae3e22c..4b8440a 100644
--- a/cryptor/rsa.go
+++ b/cryptor/rsa.go
@@ -14,11 +14,11 @@ import (
// GenerateRsaKey make a rsa private key, and return key file name
// Generated key file is `rsa_private.pem` and `rsa_public.pem` in current path
-func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) {
+func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) error {
// private key
privateKey, err := rsa.GenerateKey(rand.Reader, keySize)
if err != nil {
- panic(err)
+ return err
}
derText := x509.MarshalPKCS1PrivateKey(privateKey)
@@ -41,7 +41,7 @@ func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) {
derpText, err := x509.MarshalPKIXPublicKey(&publicKey)
if err != nil {
- panic(err)
+ return err
}
block = pem.Block{
@@ -52,10 +52,12 @@ func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) {
//file,err = os.Create("rsa_public.pem")
file, err = os.Create(pubKeyFile)
if err != nil {
- panic(err)
+ return err
}
pem.Encode(file, &block)
file.Close()
+
+ return nil
}
// RsaEncrypt encrypt data with ras algorithm
diff --git a/cryptor/rsa_test.go b/cryptor/rsa_test.go
index 8ed2a34..1a87c84 100644
--- a/cryptor/rsa_test.go
+++ b/cryptor/rsa_test.go
@@ -7,7 +7,10 @@ import (
)
func TestRsaEncrypt(t *testing.T) {
- GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
+ err := GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
+ if err != nil {
+ t.FailNow()
+ }
data := []byte("hello world")
encrypted := RsaEncrypt(data, "rsa_public.pem")
decrypted := RsaDecrypt(encrypted, "rsa_private.pem")
From 35780d9dc1521119cbe035facdd062e82a07171a Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Fri, 28 Jan 2022 10:53:14 +0800
Subject: [PATCH 05/34] update: add DesEcbEncrypt and DesEcbDecrypt comment
---
README.md | 2 ++
README_zh-CN.md | 2 ++
2 files changed, 4 insertions(+)
diff --git a/README.md b/README.md
index 5be795c..00cc575 100644
--- a/README.md
+++ b/README.md
@@ -131,6 +131,8 @@ func AesOfbEncrypt(data, key []byte) []byte //AES OFB encrypt
func AesOfbDecrypt(data, key []byte) []byte //AES OFB decrypt
func Base64StdEncode(s string) string //base64 encode
func Base64StdDecode(s string) string //base64 decode
+func DesEcbEncrypt(data, key []byte) []byte //DES ECB encrypt
+func DesEcbDecrypt(encrypted, key []byte) []byte //DES ECB decrypt
func DesCbcEncrypt(data, key []byte) []byte //DES CBC encrypt
func DesCbcDecrypt(encrypted, key []byte) []byte //DES CBC decrypt
func DesCtrCrypt(data, key []byte) []byte //DES CTR encrypt/decrypt
diff --git a/README_zh-CN.md b/README_zh-CN.md
index 86ca0ac..4a51389 100644
--- a/README_zh-CN.md
+++ b/README_zh-CN.md
@@ -131,6 +131,8 @@ func AesOfbEncrypt(data, key []byte) []byte //AES OFB模式加密
func AesOfbDecrypt(data, key []byte) []byte //AES OFB模式解密
func Base64StdEncode(s string) string //base64编码
func Base64StdDecode(s string) string //base64解码
+func DesEcbEncrypt(data, key []byte) []byte //DES ECB模式加密
+func DesEcbDecrypt(encrypted, key []byte) []byte //DES ECB模式解密
func DesCbcEncrypt(data, key []byte) []byte //DES CBC模式加密
func DesCbcDecrypt(encrypted, key []byte) []byte //DES CBC模式解密
func DesCtrCrypt(data, key []byte) []byte //DES CTR模式加密/解密
From 134aded4d8bb057c6ee4fb259c9947ba72ab286b Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Fri, 28 Jan 2022 11:45:50 +0800
Subject: [PATCH 06/34] docs: add md doc for every package
---
.gitignore | 3 +-
docs/convertor.md | 349 +++++++++++++
docs/convertor_zh-CN.md | 351 ++++++++++++++
docs/cryptor.md | 1026 +++++++++++++++++++++++++++++++++++++++
docs/cryptor_zh-CN.md | 1026 +++++++++++++++++++++++++++++++++++++++
5 files changed, 2753 insertions(+), 2 deletions(-)
create mode 100644 docs/convertor.md
create mode 100644 docs/convertor_zh-CN.md
create mode 100644 docs/cryptor.md
create mode 100644 docs/cryptor_zh-CN.md
diff --git a/.gitignore b/.gitignore
index 6210f5f..fce5a7c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,5 +6,4 @@ fileutil/*.txt
fileutil/*.zip
fileutil/*.link
fileutil/unzip/*
-cryptor/*.pem
-docs/*
\ No newline at end of file
+cryptor/*.pem
\ No newline at end of file
diff --git a/docs/convertor.md b/docs/convertor.md
new file mode 100644
index 0000000..7e72b08
--- /dev/null
+++ b/docs/convertor.md
@@ -0,0 +1,349 @@
+# Convertor
+Package convertor contains some functions for data type convertion.
+
+
+
+## Source:
+
+[https://github.com/duke-git/lancet/blob/main/convertor/convertor.go](!https://github.com/duke-git/lancet/blob/main/convertor/convertor.go)
+
+
+
+## Usage:
+```go
+import (
+ "github.com/duke-git/lancet/convertor"
+)
+```
+
+
+
+## Index
+- [ColorHexToRGB](#ColorHexToRGB)
+- [ColorRGBToHex](#ColorRGBToHex)
+- [ToBool](#ToBool)
+- [ToBytes](#ToBytes)
+- [ToChar](#ToChar)
+- [ToInt](#ToInt)
+- [ToJson](#ToJson)
+- [ToString](#ToString)
+- [StructToMap](#StructToMap)
+
+
+
+## Documentation
+
+
+
+### ColorHexToRGB
+Convert color hex to color rgb.
+
+Signature:
+
+```go
+func ColorHexToRGB(colorHex string) (red, green, blue int)
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/convertor"
+)
+
+func main() {
+ colorHex := "#003366"
+ r, g, b := ColorHexToRGB(colorHex)
+ fmt.Println(r, g, b) //0,51,102
+}
+```
+
+
+
+### ColorRGBToHex
+
+Convert color rgb to color hex.
+
+Signature:
+
+```go
+func ColorRGBToHex(red, green, blue int) string
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/convertor"
+)
+
+func main() {
+ r := 0
+ g := 51
+ b := 102
+ colorHex := ColorRGBToHex(r, g, b)
+
+ fmt.Println(colorHex) //#003366
+}
+```
+
+
+
+### ToBool
+
+Convert string to a boolean value. Use strconv.ParseBool
+
+Signature:
+
+```go
+func ToBool(s string) (bool, error)
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/convertor"
+)
+
+func main() {
+ v1, _ := convertor.ToBool("1")
+ fmt.Println(v1) //true
+
+ v2, _ := convertor.ToBool("true")
+ fmt.Println(v2) //true
+
+ v3, _ := convertor.ToBool("True")
+ fmt.Println(v3) //true
+
+ v4, _ := convertor.ToBool("123")
+ fmt.Println(v4) //false
+}
+```
+
+
+
+### ToBytes
+
+Convert interface to byte slice.
+
+Signature:
+
+```go
+func ToBytes(data interface{}) ([]byte, error)
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/convertor"
+)
+
+func main() {
+ bytesData, err := convertor.ToBytes("0")
+ if err != nil {
+ fmt.Println(err)
+ }
+ fmt.Println(bytesData) //[]bytes{3, 4, 0, 0}
+}
+```
+
+
+
+### ToChar
+
+Convert string to char slice.
+
+Signature:
+
+```go
+func ToChar(s string) []string
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/convertor"
+)
+
+func main() {
+ chars := convertor.ToChar("")
+ fmt.Println(chars) //[]string{""}
+
+ chars = convertor.ToChar("abc")
+ fmt.Println(chars) //[]string{"a", "b", "c"}
+
+ chars = convertor.ToChar("1 2#3")
+ fmt.Println(chars) //[]string{"1", " ", "2", "#", "3"}
+}
+```
+
+
+
+### ToFloat
+
+Convert interface to a float64 value. If param is a invalid floatable, will return 0 and error.
+
+Signature:
+
+```go
+func ToFloat(value interface{}) (float64, error)
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/convertor"
+)
+
+func main() {
+ v, err := convertor.ToFloat("")
+ if err != nil {
+ fmt.Println(err) //strconv.ParseFloat: parsing "": invalid syntax
+ }
+ fmt.Println(v) //0
+
+ v, _ = convertor.ToFloat("-.11")
+ fmt.Println(v) //-0.11
+}
+```
+
+
+
+### ToInt
+
+Convert interface to a int64 value. If param is a invalid intable, will return 0 and error.
+
+Signature:
+
+```go
+func ToInt(value interface{}) (int64, error)
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/convertor"
+)
+
+func main() {
+ v, err := convertor.ToInt("")
+ if err != nil {
+ fmt.Println(err) //strconv.ParseInt: parsing "": invalid syntax
+ }
+ fmt.Println(v) //0
+
+ v, _ = convertor.ToFloat(1.12)
+ fmt.Println(v) //1
+}
+```
+
+
+
+### ToJson
+
+Convert interface to json string. If param can't be converted, will return "" and error.
+
+Signature:
+
+```go
+func ToJson(value interface{}) (string, error)
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/convertor"
+)
+
+func main() {
+ var aMap = map[string]int{"a": 1, "b": 2, "c": 3}
+ jsonStr, _ := convertor.ToJson(aMap)
+ fmt.Printf("%q", jsonStr) //"{\"a\":1,\"b\":2,\"c\":3}"
+}
+```
+
+
+
+### ToString
+
+Convert interface to string.
+
+Signature:
+
+```go
+func ToString(value interface{}) string
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/convertor"
+)
+
+func main() {
+ fmt.Printf("%q", convertor.ToString(1)) //"1"
+ fmt.Printf("%q", convertor.ToString(1.1)) //"1.1"
+ fmt.Printf("%q", convertor.ToString([]int{1, 2, 3})) //"[1,2,3]"
+}
+```
+
+
+
+### StructToMap
+
+Convert struct to map, only convert exported field, struct field tag `json` should be set.
+
+Signature:
+
+```go
+func StructToMap(value interface{}) (map[string]interface{}, error)
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/convertor"
+)
+
+func main() {
+ type People struct {
+ Name string `json:"name"`
+ age int
+ }
+ p := People{
+ "test",
+ 100,
+ }
+ pm, _ := convertor.StructToMap(p)
+
+ fmt.Printf("type: %T, value: %s", pm, pm) //type: map[string]interface {}, value: map[name:test]
+}
+```
\ No newline at end of file
diff --git a/docs/convertor_zh-CN.md b/docs/convertor_zh-CN.md
new file mode 100644
index 0000000..8a3a0b8
--- /dev/null
+++ b/docs/convertor_zh-CN.md
@@ -0,0 +1,351 @@
+# Convertor
+convertor转换器包支持一些常见的数据类型转换
+
+
+
+## 源码:
+
+[https://github.com/duke-git/lancet/blob/main/convertor/convertor.go](!https://github.com/duke-git/lancet/blob/main/convertor/convertor.go)
+
+
+
+## 用法:
+
+```go
+import (
+ "github.com/duke-git/lancet/convertor"
+)
+```
+
+
+
+## 目录
+
+- [ColorHexToRGB](#ColorHexToRGB)
+- [ColorRGBToHex](#ColorRGBToHex)
+- [ToBool](#ToBool)
+- [ToBytes](#ToBytes)
+- [ToChar](#ToChar)
+- [ToInt](#ToInt)
+- [ToJson](#ToJson)
+- [ToString](#ToString)
+- [StructToMap](#StructToMap)
+
+
+
+## 文档
+
+
+
+### ColorHexToRGB
+颜色值十六进制转rgb
+
+函数签名:
+
+```go
+func ColorHexToRGB(colorHex string) (red, green, blue int)
+```
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/convertor"
+)
+
+func main() {
+ colorHex := "#003366"
+ r, g, b := ColorHexToRGB(colorHex)
+ fmt.Println(r, g, b) //0,51,102
+}
+```
+
+
+
+### ColorRGBToHex
+
+颜色值rgb转十六进制
+
+函数签名:
+
+```go
+func ColorRGBToHex(red, green, blue int) string
+```
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/convertor"
+)
+
+func main() {
+ r := 0
+ g := 51
+ b := 102
+ colorHex := ColorRGBToHex(r, g, b)
+
+ fmt.Println(colorHex) //#003366
+}
+```
+
+
+
+### ToBool
+
+字符串转布尔类型,使用strconv.ParseBool
+
+函数签名:
+
+```go
+func ToBool(s string) (bool, error)
+```
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/convertor"
+)
+
+func main() {
+ v1, _ := convertor.ToBool("1")
+ fmt.Println(v1) //true
+
+ v2, _ := convertor.ToBool("true")
+ fmt.Println(v2) //true
+
+ v3, _ := convertor.ToBool("True")
+ fmt.Println(v3) //true
+
+ v4, _ := convertor.ToBool("123")
+ fmt.Println(v4) //false
+}
+```
+
+
+
+### ToBytes
+
+interface转字节切片.
+
+函数签名:
+
+```go
+func ToBytes(data interface{}) ([]byte, error)
+```
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/convertor"
+)
+
+func main() {
+ bytesData, err := convertor.ToBytes("0")
+ if err != nil {
+ fmt.Println(err)
+ }
+ fmt.Println(bytesData) //[]bytes{3, 4, 0, 0}
+}
+```
+
+
+
+### ToChar
+
+字符串转字符切片
+
+函数签名:
+
+```go
+func ToChar(s string) []string
+```
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/convertor"
+)
+
+func main() {
+ chars := convertor.ToChar("")
+ fmt.Println(chars) //[]string{""}
+
+ chars = convertor.ToChar("abc")
+ fmt.Println(chars) //[]string{"a", "b", "c"}
+
+ chars = convertor.ToChar("1 2#3")
+ fmt.Println(chars) //[]string{"1", " ", "2", "#", "3"}
+}
+```
+
+
+
+### ToFloat
+
+将interface转成float64类型,如果参数无法转换,会返回0和error
+
+函数签名:
+
+```go
+func ToFloat(value interface{}) (float64, error)
+```
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/convertor"
+)
+
+func main() {
+ v, err := convertor.ToFloat("")
+ if err != nil {
+ fmt.Println(err) //strconv.ParseFloat: parsing "": invalid syntax
+ }
+ fmt.Println(v) //0
+
+ v, _ = convertor.ToFloat("-.11")
+ fmt.Println(v) //-0.11
+}
+```
+
+
+
+### ToInt
+
+将interface转成intt64类型,如果参数无法转换,会返回0和error
+
+函数签名:
+
+```go
+func ToInt(value interface{}) (int64, error)
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/convertor"
+)
+
+func main() {
+ v, err := convertor.ToInt("")
+ if err != nil {
+ fmt.Println(err) //strconv.ParseInt: parsing "": invalid syntax
+ }
+ fmt.Println(v) //0
+
+ v, _ = convertor.ToFloat(1.12)
+ fmt.Println(v) //1
+}
+```
+
+
+
+### ToJson
+
+将interface转成json字符串,如果参数无法转换,会返回""和error
+
+函数签名:
+
+```go
+func ToJson(value interface{}) (string, error)
+```
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/convertor"
+)
+
+func main() {
+ var aMap = map[string]int{"a": 1, "b": 2, "c": 3}
+ jsonStr, _ := convertor.ToJson(aMap)
+ fmt.Printf("%q", jsonStr) //"{\"a\":1,\"b\":2,\"c\":3}"
+}
+```
+
+
+
+### ToString
+
+将interface转成字符串
+
+函数签名:
+
+```go
+func ToString(value interface{}) string
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/convertor"
+)
+
+func main() {
+ fmt.Printf("%q", convertor.ToString(1)) //"1"
+ fmt.Printf("%q", convertor.ToString(1.1)) //"1.1"
+ fmt.Printf("%q", convertor.ToString([]int{1, 2, 3})) //"[1,2,3]"
+}
+```
+
+
+
+### StructToMap
+
+将struct转成map,只会转换struct中可导出的字段。struct中导出字段需要设置json tag标记
+
+函数签名:
+
+```go
+func StructToMap(value interface{}) (map[string]interface{}, error)
+```
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/convertor"
+)
+
+func main() {
+ type People struct {
+ Name string `json:"name"`
+ age int
+ }
+ p := People{
+ "test",
+ 100,
+ }
+ pm, _ := convertor.StructToMap(p)
+
+ fmt.Printf("type: %T, value: %s", pm, pm) //type: map[string]interface {}, value: map[name:test]
+}
+```
\ No newline at end of file
diff --git a/docs/cryptor.md b/docs/cryptor.md
new file mode 100644
index 0000000..e09a093
--- /dev/null
+++ b/docs/cryptor.md
@@ -0,0 +1,1026 @@
+# Cryptor
+Package cryptor contains some functions for data encryption and decryption. Support base64, md5, hmac, aes, des, rsa.
+
+
+
+## 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/main/cryptor/des.go](!https://github.com/duke-git/lancet/blob/main/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/main/cryptor/rsa.go](!https://github.com/duke-git/lancet/blob/main/cryptor/ras.go)
+
+
+
+## Usage:
+```go
+import (
+ "github.com/duke-git/lancet/cryptor"
+)
+```
+
+
+
+## Index
+
+- [AesEcbEncrypt](#AesEcbEncrypt)
+- [AesEcbDecrypt](#AesEcbDecrypt)
+- [AesCbcEncrypt](#AesCbcEncrypt)
+- [AesCbcDecrypt](#AesCbcDecrypt)
+- [AesCtrCrypt](#AesCtrCrypt)
+- [AesCfbEncrypt](#AesCfbEncrypt)
+- [AesCfbDecrypt](#AesCfbDecrypt)
+- [AesOfbEncrypt](#AesOfbEncrypt)
+- [AesOfbDecrypt](#AesOfbDecrypt)
+- [Base64StdEncode](#Base64StdEncode)
+- [Base64StdDecode](#Base64StdDecode)
+- [DesEcbEncrypt](#DesEcbEncrypt)
+- [DesEcbDecrypt](#DesEcbDecrypt)
+- [DesCbcEncrypt](#DesCbcEncrypt)
+- [DesCbcDecrypt](#DesCbcDecrypt)
+- [DesCtrCrypt](#DesCtrCrypt)
+- [DesCfbEncrypt](#DesCfbEncrypt)
+- [DesCfbDecrypt](#DesCfbDecrypt)
+- [DesOfbEncrypt](#DesOfbEncrypt)
+- [DesOfbDecrypt](#DesOfbDecrypt)
+- [HmacMd5](#HmacMd5)
+- [HmacSha1](#HmacSha1)
+- [HmacSha256](#HmacSha256)
+- [HmacSha512](#HmacSha512)
+
+- [Md5String](#Md5String)
+- [Md5File](#Md5File)
+- [Sha1](#Sha1)
+- [Sha256](#Sha256)
+- [Sha512](#Sha512)
+- [GenerateRsaKey](#GenerateRsaKey)
+- [RsaEncrypt](#RsaEncrypt)
+- [RsaDecrypt](#RsaDecrypt)
+
+
+
+
+## Documentation
+
+
+
+### AesEcbEncrypt
+
+Encrypt data with key use AES ECB algorithm. Length of `key` param should be 16, 24 or 32.
+
+Signature:
+
+```go
+func AesEcbEncrypt(data, key []byte) []byte
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefghijklmnop"
+ encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
+
+ fmt.Println(string(encrypted))
+}
+```
+
+
+
+### AesEcbDecrypt
+
+Decrypt data with key use AES ECB algorithm. Length of `key` param should be 16, 24 or 32.
+
+Signature:
+
+```go
+func AesEcbDecrypt(encrypted, key []byte) []byte
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefghijklmnop"
+ encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
+ decrypted := cryptor.AesEcbDecrypt(encrypted, []byte(key))
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### AesCbcEncrypt
+
+Encrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.
+
+Signature:
+
+```go
+func AesCbcEncrypt(data, key []byte) []byte
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefghijklmnop"
+ encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
+
+ fmt.Println(string(encrypted))
+}
+```
+
+
+
+### AesCbcDecrypt
+
+Decrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.
+
+Signature:
+
+```go
+func AesCbcDecrypt(encrypted, key []byte) []byte
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefghijklmnop"
+ encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
+ decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key))
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### AesCtrCrypt
+
+Encrypt or decrypt data with key use AES CTR algorithm. Length of `key` param should be 16, 24 or 32.
+
+Signature:
+
+```go
+func AesCtrCrypt(data, key []byte) []byte
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefghijklmnop"
+ encrypted := cryptor.AesCtrCrypt([]byte(data), []byte(key))
+ decrypted := cryptor.AesCtrCrypt(encrypted, []byte(key))
+
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### AesCfbEncrypt
+
+Encrypt data with key use AES CFB algorithm. Length of `key` param should be 16, 24 or 32.
+
+Signature:
+
+```go
+func AesCfbEncrypt(data, key []byte) []byte
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefghijklmnop"
+ encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key))
+ fmt.Println(string(encrypted))
+}
+```
+
+
+
+### AesCfbDecrypt
+
+Decrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.
+
+Signature:
+
+```go
+func AesCfbDecrypt(encrypted, key []byte) []byte
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefghijklmnop"
+ encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key))
+ decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key))
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### AesOfbEncrypt
+
+Enecrypt data with key use AES OFB algorithm. Length of `key` param should be 16, 24 or 32.
+
+Signature:
+
+```go
+func AesOfbEncrypt(data, key []byte) []byte
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefghijklmnop"
+ encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key))
+ fmt.Println(string(encrypted))
+}
+```
+
+
+
+### AesOfbDecrypt
+
+Decrypt data with key use AES OFB algorithm. Length of `key` param should be 16, 24 or 32.
+
+Signature:
+
+```go
+func AesOfbDecrypt(encrypted, key []byte) []byte
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefghijklmnop"
+ encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key))
+ decrypted := cryptor.AesOfbDecrypt(encrypted, []byte(key))
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### Base64StdEncode
+
+Encode string with base64 encoding.
+
+Signature:
+
+```go
+func Base64StdEncode(s string) string
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ base64Str := cryptor.Base64StdEncode("hello world")
+ fmt.Println(base64Str) //aGVsbG8gd29ybGQ=
+}
+```
+
+
+
+### Base64StdDecode
+
+Decode a base64 encoded string.
+
+Signature:
+
+```go
+func Base64StdDecode(s string) string
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ str := cryptor.Base64StdDecode("aGVsbG8gd29ybGQ=")
+ fmt.Println(str) //hello world
+}
+```
+
+
+
+### DesEcbEncrypt
+
+Encrypt data with key use DES ECB algorithm. Length of `key` param should be 8.
+
+Signature:
+
+```go
+func DesEcbEncrypt(data, key []byte) []byte
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefgh"
+ encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key))
+
+ fmt.Println(string(encrypted))
+}
+```
+
+
+
+### DesEcbDecrypt
+
+Decrypt data with key use DES ECB algorithm. Length of `key` param should be 8.
+
+Signature:
+
+```go
+func DesEcbDecrypt(encrypted, key []byte) []byte
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefgh"
+ encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key))
+ decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key))
+
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### DesCbcEncrypt
+
+Encrypt data with key use DES CBC algorithm. Length of `key` param should be 8.
+
+Signature:
+
+```go
+func DesCbcEncrypt(data, key []byte) []byte
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefgh"
+ encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key))
+
+ fmt.Println(string(encrypted))
+}
+```
+
+
+
+### DesCbcDecrypt
+
+Decrypt data with key use DES CBC algorithm. Length of `key` param should be 8.
+
+Signature:
+
+```go
+func DesCbcDecrypt(encrypted, key []byte) []byte
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefgh"
+ encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key))
+ decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key))
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### DesCtrCrypt
+
+Encrypt or decrypt data with key use DES CTR algorithm. Length of `key` param should be 8.
+
+Signature:
+
+```go
+func DesCtrCrypt(data, key []byte) []byte
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefgh"
+ encrypted := cryptor.DesCtrCrypt([]byte(data), []byte(key))
+ decrypted := cryptor.DesCtrCrypt(encrypted, []byte(key))
+
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### DesCfbEncrypt
+
+Encrypt data with key use DES CFB algorithm. Length of `key` param should be 8.
+
+Signature:
+
+```go
+func DesCfbEncrypt(data, key []byte) []byte
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefgh"
+ encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key))
+ fmt.Println(string(encrypted))
+}
+```
+
+
+
+### DesCfbDecrypt
+
+Decrypt data with key use DES CBC algorithm. Length of `key` param should be 8.
+
+Signature:
+
+```go
+func DesCfbDecrypt(encrypted, key []byte) []byte
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefgh"
+ encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key))
+ decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key))
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### DesOfbEncrypt
+
+Enecrypt data with key use DES OFB algorithm. Length of `key` param should be 8.
+
+Signature:
+
+```go
+func DesOfbEncrypt(data, key []byte) []byte
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefgh"
+ encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key))
+ fmt.Println(string(encrypted))
+}
+```
+
+
+
+### DesOfbDecrypt
+
+Decrypt data with key use DES OFB algorithm. Length of `key` param should be 8.
+
+Signature:
+
+```go
+func DesOfbDecrypt(encrypted, key []byte) []byte
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefgh"
+ encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key))
+ decrypted := cryptor.DesOfbDecrypt(encrypted, []byte(key))
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### HmacMd5
+
+Get the md5 hmac hash of string.
+
+Signature:
+
+```go
+func HmacMd5(data, key string) string
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ s := cryptor.HmacMd5("hello world", "12345"))
+ fmt.Println(s) //5f4c9faaff0a1ad3007d9ddc06abe36d
+}
+```
+
+
+
+### HmacSha1
+
+Get the sha1 hmac hash of string.
+
+Signature:
+
+```go
+func HmacSha1(data, key string) string
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ s := cryptor.HmacSha1("hello world", "12345"))
+ fmt.Println(s) //3826f812255d8683f051ee97346d1359234d5dbd
+}
+```
+
+
+
+### HmacSha256
+
+Get the sha256 hmac hash of string
+
+Signature:
+
+```go
+func HmacSha256(data, key string) string
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ s := cryptor.HmacSha256("hello world", "12345"))
+ fmt.Println(s) //9dce2609f2d67d41f74c7f9efc8ccd44370d41ad2de52982627588dfe7289ab8
+}
+```
+
+
+
+### HmacSha512
+
+Get the sha512 hmac hash of string.
+
+Signature:
+
+```go
+func HmacSha512(data, key string) string
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ s := cryptor.HmacSha512("hello world", "12345"))
+ fmt.Println(s)
+ //5b1563ac4e9b49c9ada8ccb232588fc4f0c30fd12f756b3a0b95af4985c236ca60925253bae10ce2c6bf9af1c1679b51e5395ff3d2826c0a2c7c0d72225d4175
+}
+```
+
+
+
+### Md5String
+
+Get the md5 value of string.
+
+Signature:
+
+```go
+func Md5String(s string) string
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ s := cryptor.Md5String("hello"))
+ fmt.Println(s) //5d41402abc4b2a76b9719d911017c592
+}
+```
+
+
+
+### Md5File
+
+Get the md5 value of file.
+
+Signature:
+
+```go
+func Md5File(filepath string) (string, error)
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ s := cryptor.Md5File("./main.go"))
+ fmt.Println(s)
+}
+```
+
+
+
+### Sha1
+
+Get the sha1 value of string.
+
+Signature:
+
+```go
+func Sha1(data string) string
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ s := cryptor.Sha1("hello world"))
+ fmt.Println(s) //2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
+}
+```
+
+
+
+### Sha256
+
+Get the sha256 value of string.
+
+Signature:
+
+```go
+func Sha256(data string) string
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ s := cryptor.Sha256("hello world"))
+ fmt.Println(s) //b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
+}
+```
+
+
+
+### Sha512
+
+Get the sha512 value of string.
+
+Signature:
+
+```go
+func Sha512(data string) string
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ s := cryptor.Sha512("hello world"))
+ fmt.Println(s) //309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f
+}
+```
+
+
+
+### GenerateRsaKey
+
+Create the rsa public and private key file in current directory.
+
+Signature:
+
+```go
+func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) error
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
+ if err != nil {
+ fmt.Println(err)
+ }
+}
+```
+
+
+
+### RsaEncrypt
+
+Encrypt data with public key file useing ras algorithm.
+
+Signature:
+
+```go
+func RsaEncrypt(data []byte, pubKeyFileName string) []byte
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
+ if err != nil {
+ fmt.Println(err)
+ }
+ data := []byte("hello world")
+ encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
+ decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### RsaDecrypt
+
+Decrypt data with private key file useing ras algorithm.
+
+Signature:
+
+```go
+func RsaDecrypt(data []byte, privateKeyFileName string) []byte
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
+ if err != nil {
+ fmt.Println(err)
+ }
+ data := []byte("hello world")
+ encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
+ decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
diff --git a/docs/cryptor_zh-CN.md b/docs/cryptor_zh-CN.md
new file mode 100644
index 0000000..e806ee6
--- /dev/null
+++ b/docs/cryptor_zh-CN.md
@@ -0,0 +1,1026 @@
+# Cryptor
+cryptor加密包支持数据加密和解密,获取md5,hash值。支持base64, md5, hmac, aes, des, rsa。
+
+
+
+## 源码:
+
+- [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/main/cryptor/des.go](!https://github.com/duke-git/lancet/blob/main/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/main/cryptor/rsa.go](!https://github.com/duke-git/lancet/blob/main/cryptor/ras.go)
+
+
+
+## 用法:
+```go
+import (
+ "github.com/duke-git/lancet/cryptor"
+)
+```
+
+
+
+## 目录
+
+- [AesEcbEncrypt](#AesEcbEncrypt)
+- [AesEcbDecrypt](#AesEcbDecrypt)
+- [AesCbcEncrypt](#AesCbcEncrypt)
+- [AesCbcDecrypt](#AesCbcDecrypt)
+- [AesCtrCrypt](#AesCtrCrypt)
+- [AesCfbEncrypt](#AesCfbEncrypt)
+- [AesCfbDecrypt](#AesCfbDecrypt)
+- [AesOfbEncrypt](#AesOfbEncrypt)
+- [AesOfbDecrypt](#AesOfbDecrypt)
+- [Base64StdEncode](#Base64StdEncode)
+- [Base64StdDecode](#Base64StdDecode)
+- [DesEcbEncrypt](#DesEcbEncrypt)
+- [DesEcbDecrypt](#DesEcbDecrypt)
+- [DesCbcEncrypt](#DesCbcEncrypt)
+- [DesCbcDecrypt](#DesCbcDecrypt)
+- [DesCtrCrypt](#DesCtrCrypt)
+- [DesCfbEncrypt](#DesCfbEncrypt)
+- [DesCfbDecrypt](#DesCfbDecrypt)
+- [DesOfbEncrypt](#DesOfbEncrypt)
+- [DesOfbDecrypt](#DesOfbDecrypt)
+- [HmacMd5](#HmacMd5)
+- [HmacSha1](#HmacSha1)
+- [HmacSha256](#HmacSha256)
+- [HmacSha512](#HmacSha512)
+
+- [Md5String](#Md5String)
+- [Md5File](#Md5File)
+- [Sha1](#Sha1)
+- [Sha256](#Sha256)
+- [Sha512](#Sha512)
+- [GenerateRsaKey](#GenerateRsaKey)
+- [RsaEncrypt](#RsaEncrypt)
+- [RsaDecrypt](#RsaDecrypt)
+
+
+
+
+## 文档
+
+
+
+### AesEcbEncrypt
+
+使用AES ECB算法模式加密数据. 参数`key`的长度是16, 24 or 32。
+
+函数签名:
+
+```go
+func AesEcbEncrypt(data, key []byte) []byte
+```
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefghijklmnop"
+ encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
+
+ fmt.Println(string(encrypted))
+}
+```
+
+
+
+### AesEcbDecrypt
+
+使用AES ECB算法模式解密数据. 参数`key`的长度是16, 24 or 32。
+
+函数签名:
+
+```go
+func AesEcbDecrypt(encrypted, key []byte) []byte
+```
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefghijklmnop"
+ encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
+ decrypted := cryptor.AesEcbDecrypt(encrypted, []byte(key))
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### AesCbcEncrypt
+
+
使用AES CBC算法模式加密数据. 参数`key`的长度是16, 24 or 32。
+
+函数签名:
+
+```go
+func AesCbcEncrypt(data, key []byte) []byte
+```
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefghijklmnop"
+ encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
+
+ fmt.Println(string(encrypted))
+}
+```
+
+
+
+### AesCbcDecrypt
+
+使用AES CBC算法模式解密数据. 参数`key`的长度是16, 24 or 32。
+
+函数签名:
+
+```go
+func AesCbcDecrypt(encrypted, key []byte) []byte
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefghijklmnop"
+ encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
+ decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key))
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### AesCtrCrypt
+
+使用AES CTR算法模式加密/解密数据. 参数`key`的长度是16, 24 or 32。
+
+函数签名:
+
+```go
+func AesCtrCrypt(data, key []byte) []byte
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefghijklmnop"
+ encrypted := cryptor.AesCtrCrypt([]byte(data), []byte(key))
+ decrypted := cryptor.AesCtrCrypt(encrypted, []byte(key))
+
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### AesCfbEncrypt
+
+使用AES CFB算法模式加密数据. 参数`key`的长度是16, 24 or 32。
+
+函数签名:
+
+```go
+func AesCfbEncrypt(data, key []byte) []byte
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefghijklmnop"
+ encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key))
+ fmt.Println(string(encrypted))
+}
+```
+
+
+
+### AesCfbDecrypt
+
+使用AES CFB算法模式解密数据. 参数`key`的长度是16, 24 or 32。
+
+函数签名:
+
+```go
+func AesCfbDecrypt(encrypted, key []byte) []byte
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefghijklmnop"
+ encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key))
+ decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key))
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### AesOfbEncrypt
+
+使用AES OFB算法模式加密数据. 参数`key`的长度是16, 24 or 32
+
+函数签名:
+
+```go
+func AesOfbEncrypt(data, key []byte) []byte
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefghijklmnop"
+ encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key))
+ fmt.Println(string(encrypted))
+}
+```
+
+
+
+### AesOfbDecrypt
+
+使用AES OFB算法模式解密数据. 参数`key`的长度是16, 24 or 32
+
+函数签名:
+
+```go
+func AesOfbDecrypt(encrypted, key []byte) []byte
+```
+
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefghijklmnop"
+ encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key))
+ decrypted := cryptor.AesOfbDecrypt(encrypted, []byte(key))
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### Base64StdEncode
+
+将字符串base64编码
+
+函数签名:
+
+```go
+func Base64StdEncode(s string) string
+```
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ base64Str := cryptor.Base64StdEncode("hello world")
+ fmt.Println(base64Str) //aGVsbG8gd29ybGQ=
+}
+```
+
+
+
+### Base64StdDecode
+
+解码base64字符串
+
+函数签名:
+
+```go
+func Base64StdDecode(s string) string
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ str := cryptor.Base64StdDecode("aGVsbG8gd29ybGQ=")
+ fmt.Println(str) //hello world
+}
+```
+
+
+
+### DesEcbEncrypt
+
+使用DES ECB算法模式加密数据. 参数`key`的长度是8
+
+函数签名:
+
+```go
+func DesEcbEncrypt(data, key []byte) []byte
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefgh"
+ encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key))
+
+ fmt.Println(string(encrypted))
+}
+```
+
+
+
+### DesEcbDecrypt
+
+使用DES ECB算法模式解密数据. 参数`key`的长度是8
+
+函数签名:
+
+```go
+func DesEcbDecrypt(encrypted, key []byte) []byte
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefgh"
+ encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key))
+ decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key))
+
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### DesCbcEncrypt
+
+使用DES CBC算法模式加密数据. 参数`key`的长度是8
+
+函数签名:
+
+```go
+func DesCbcEncrypt(data, key []byte) []byte
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefgh"
+ encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key))
+
+ fmt.Println(string(encrypted))
+}
+```
+
+
+
+### DesCbcDecrypt
+
+使用DES CBC算法模式解密数据. 参数`key`的长度是8
+
+函数签名:
+
+```go
+func DesCbcDecrypt(encrypted, key []byte) []byte
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefgh"
+ encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key))
+ decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key))
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### DesCtrCrypt
+
+使用DES CTR算法模式加密/解密数据. 参数`key`的长度是8
+
+函数签名:
+
+```go
+func DesCtrCrypt(data, key []byte) []byte
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefgh"
+ encrypted := cryptor.DesCtrCrypt([]byte(data), []byte(key))
+ decrypted := cryptor.DesCtrCrypt(encrypted, []byte(key))
+
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### DesCfbEncrypt
+
+使用DES CFB算法模式加密数据. 参数`key`的长度是8
+
+函数签名:
+
+```go
+func DesCfbEncrypt(data, key []byte) []byte
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefgh"
+ encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key))
+ fmt.Println(string(encrypted))
+}
+```
+
+
+
+### DesCfbDecrypt
+
+使用DES CFB算法模式解密数据. 参数`key`的长度是8
+
+函数签名:
+
+```go
+func DesCfbDecrypt(encrypted, key []byte) []byte
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefgh"
+ encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key))
+ decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key))
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### DesOfbEncrypt
+
+使用DES OFB算法模式加密数据. 参数`key`的长度是8
+
+函数签名:
+
+```go
+func DesOfbEncrypt(data, key []byte) []byte
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefgh"
+ encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key))
+ fmt.Println(string(encrypted))
+}
+```
+
+
+
+### DesOfbDecrypt
+
+使用DES OFB算法模式解密数据. 参数`key`的长度是8
+
+函数签名:
+
+```go
+func DesOfbDecrypt(encrypted, key []byte) []byte
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ data := "hello world"
+ key := "abcdefgh"
+ encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key))
+ decrypted := cryptor.DesOfbDecrypt(encrypted, []byte(key))
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### HmacMd5
+
+获取字符串md5 hmac值
+
+函数签名:
+
+```go
+func HmacMd5(data, key string) string
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ s := cryptor.HmacMd5("hello world", "12345"))
+ fmt.Println(s) //5f4c9faaff0a1ad3007d9ddc06abe36d
+}
+```
+
+
+
+### HmacSha1
+
+获取字符串sha1 hmac值
+
+函数签名:
+
+```go
+func HmacSha1(data, key string) string
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ s := cryptor.HmacSha1("hello world", "12345"))
+ fmt.Println(s) //3826f812255d8683f051ee97346d1359234d5dbd
+}
+```
+
+
+
+### HmacSha256
+
+获取字符串sha256 hmac值
+
+函数签名:
+
+```go
+func HmacSha256(data, key string) string
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ s := cryptor.HmacSha256("hello world", "12345"))
+ fmt.Println(s) //9dce2609f2d67d41f74c7f9efc8ccd44370d41ad2de52982627588dfe7289ab8
+}
+```
+
+
+
+### HmacSha512
+
+获取字符串sha512 hmac值
+
+函数签名:
+
+```go
+func HmacSha512(data, key string) string
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ s := cryptor.HmacSha512("hello world", "12345"))
+ fmt.Println(s)
+ //5b1563ac4e9b49c9ada8ccb232588fc4f0c30fd12f756b3a0b95af4985c236ca60925253bae10ce2c6bf9af1c1679b51e5395ff3d2826c0a2c7c0d72225d4175
+}
+```
+
+
+
+### Md5String
+
+获取字符串md5值
+
+函数签名:
+
+```go
+func Md5String(s string) string
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ s := cryptor.Md5String("hello"))
+ fmt.Println(s) //5d41402abc4b2a76b9719d911017c592
+}
+```
+
+
+
+### Md5File
+
+获取文件md5值.
+
+函数签名:
+
+```go
+func Md5File(filepath string) (string, error)
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ s := cryptor.Md5File("./main.go"))
+ fmt.Println(s)
+}
+```
+
+
+
+### Sha1
+
+获取字符串sha1值
+
+函数签名:
+
+```go
+func Sha1(data string) string
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ s := cryptor.Sha1("hello world"))
+ fmt.Println(s) //2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
+}
+```
+
+
+
+### Sha256
+
+获取字符串sha256值
+
+函数签名:
+
+```go
+func Sha256(data string) string
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ s := cryptor.Sha256("hello world"))
+ fmt.Println(s) //b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
+}
+```
+
+
+
+### Sha512
+
+获取字符串sha512值
+
+函数签名:
+
+```go
+func Sha512(data string) string
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ s := cryptor.Sha512("hello world"))
+ fmt.Println(s) //309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f
+}
+```
+
+
+
+### GenerateRsaKey
+
+在当前目录下创建rsa私钥文件和公钥文件
+
+函数签名:
+
+```go
+func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) error
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
+ if err != nil {
+ fmt.Println(err)
+ }
+}
+```
+
+
+
+### RsaEncrypt
+
+用公钥文件ras加密数据
+
+函数签名:
+
+```go
+func RsaEncrypt(data []byte, pubKeyFileName string) []byte
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
+ if err != nil {
+ fmt.Println(err)
+ }
+ data := []byte("hello world")
+ encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
+ decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
+### RsaDecrypt
+
+用私钥文件rsa解密数据
+
+函数签名:
+
+```go
+func RsaDecrypt(data []byte, privateKeyFileName string) []byte
+```
+
+列子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/cryptor"
+)
+
+func main() {
+ err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
+ if err != nil {
+ fmt.Println(err)
+ }
+ data := []byte("hello world")
+ encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
+ decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
+ fmt.Println(string(decrypted)) //hello world
+}
+```
+
+
+
From 5963830879c2a18a7d16f2c88b5d314a61be2784 Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Fri, 28 Jan 2022 11:50:25 +0800
Subject: [PATCH 07/34] docs: fix source link disabled issue
---
docs/convertor.md | 2 +-
docs/convertor_zh-CN.md | 2 +-
docs/cryptor.md | 8 ++---
docs/cryptor_zh-CN.md | 69 ++++++++++++++++++++++++-----------------
4 files changed, 47 insertions(+), 34 deletions(-)
diff --git a/docs/convertor.md b/docs/convertor.md
index 7e72b08..e11f1c1 100644
--- a/docs/convertor.md
+++ b/docs/convertor.md
@@ -5,7 +5,7 @@ Package convertor contains some functions for data type convertion.
## 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/main/convertor/convertor.go](https://github.com/duke-git/lancet/blob/main/convertor/convertor.go)
diff --git a/docs/convertor_zh-CN.md b/docs/convertor_zh-CN.md
index 8a3a0b8..f22877d 100644
--- a/docs/convertor_zh-CN.md
+++ b/docs/convertor_zh-CN.md
@@ -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/main/convertor/convertor.go](https://github.com/duke-git/lancet/blob/main/convertor/convertor.go)
diff --git a/docs/cryptor.md b/docs/cryptor.md
index e09a093..ff8e4ae 100644
--- a/docs/cryptor.md
+++ b/docs/cryptor.md
@@ -5,10 +5,10 @@ Package cryptor contains some functions for data encryption and decryption. Supp
## 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/main/cryptor/des.go](!https://github.com/duke-git/lancet/blob/main/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/main/cryptor/rsa.go](!https://github.com/duke-git/lancet/blob/main/cryptor/ras.go)
+- [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/main/cryptor/des.go](https://github.com/duke-git/lancet/blob/main/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/main/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/main/cryptor/rsa.go)
diff --git a/docs/cryptor_zh-CN.md b/docs/cryptor_zh-CN.md
index e806ee6..3119559 100644
--- a/docs/cryptor_zh-CN.md
+++ b/docs/cryptor_zh-CN.md
@@ -5,10 +5,10 @@ cryptor加密包支持数据加密和解密,获取md5,hash值。支持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/main/cryptor/des.go](!https://github.com/duke-git/lancet/blob/main/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/main/cryptor/rsa.go](!https://github.com/duke-git/lancet/blob/main/cryptor/ras.go)
+- [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/main/cryptor/des.go](https://github.com/duke-git/lancet/blob/main/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/main/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/main/cryptor/rsa.go)
@@ -23,30 +23,43 @@ import (
## 目录
-- [AesEcbEncrypt](#AesEcbEncrypt)
-- [AesEcbDecrypt](#AesEcbDecrypt)
-- [AesCbcEncrypt](#AesCbcEncrypt)
-- [AesCbcDecrypt](#AesCbcDecrypt)
-- [AesCtrCrypt](#AesCtrCrypt)
-- [AesCfbEncrypt](#AesCfbEncrypt)
-- [AesCfbDecrypt](#AesCfbDecrypt)
-- [AesOfbEncrypt](#AesOfbEncrypt)
-- [AesOfbDecrypt](#AesOfbDecrypt)
-- [Base64StdEncode](#Base64StdEncode)
-- [Base64StdDecode](#Base64StdDecode)
-- [DesEcbEncrypt](#DesEcbEncrypt)
-- [DesEcbDecrypt](#DesEcbDecrypt)
-- [DesCbcEncrypt](#DesCbcEncrypt)
-- [DesCbcDecrypt](#DesCbcDecrypt)
-- [DesCtrCrypt](#DesCtrCrypt)
-- [DesCfbEncrypt](#DesCfbEncrypt)
-- [DesCfbDecrypt](#DesCfbDecrypt)
-- [DesOfbEncrypt](#DesOfbEncrypt)
-- [DesOfbDecrypt](#DesOfbDecrypt)
-- [HmacMd5](#HmacMd5)
-- [HmacSha1](#HmacSha1)
-- [HmacSha256](#HmacSha256)
-- [HmacSha512](#HmacSha512)
+- [Cryptor](#cryptor)
+ - [源码:](#源码)
+ - [用法:](#用法)
+ - [目录](#目录)
+ - [文档](#文档)
+ - [AesEcbEncrypt](#aesecbencrypt)
+ - [AesEcbDecrypt](#aesecbdecrypt)
+ - [AesCbcEncrypt](#aescbcencrypt)
+ - [AesCbcDecrypt](#aescbcdecrypt)
+ - [AesCtrCrypt](#aesctrcrypt)
+ - [AesCfbEncrypt](#aescfbencrypt)
+ - [AesCfbDecrypt](#aescfbdecrypt)
+ - [AesOfbEncrypt](#aesofbencrypt)
+ - [AesOfbDecrypt](#aesofbdecrypt)
+ - [Base64StdEncode](#base64stdencode)
+ - [Base64StdDecode](#base64stddecode)
+ - [DesEcbEncrypt](#desecbencrypt)
+ - [DesEcbDecrypt](#desecbdecrypt)
+ - [DesCbcEncrypt](#descbcencrypt)
+ - [DesCbcDecrypt](#descbcdecrypt)
+ - [DesCtrCrypt](#desctrcrypt)
+ - [DesCfbEncrypt](#descfbencrypt)
+ - [DesCfbDecrypt](#descfbdecrypt)
+ - [DesOfbEncrypt](#desofbencrypt)
+ - [DesOfbDecrypt](#desofbdecrypt)
+ - [HmacMd5](#hmacmd5)
+ - [HmacSha1](#hmacsha1)
+ - [HmacSha256](#hmacsha256)
+ - [HmacSha512](#hmacsha512)
+ - [Md5String](#md5string)
+ - [Md5File](#md5file)
+ - [Sha1](#sha1)
+ - [Sha256](#sha256)
+ - [Sha512](#sha512)
+ - [GenerateRsaKey](#generatersakey)
+ - [RsaEncrypt](#rsaencrypt)
+ - [RsaDecrypt](#rsadecrypt)
- [Md5String](#Md5String)
- [Md5File](#Md5File)
From 6988fdc4515dca921bf530742e3b1d706bdfa938 Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Fri, 28 Jan 2022 15:33:20 +0800
Subject: [PATCH 08/34] docs: fix code fmt issue
---
docs/cryptor.md | 69 ++++++++++++++++++++++++-------------------
docs/cryptor_zh-CN.md | 18 ++++++-----
2 files changed, 48 insertions(+), 39 deletions(-)
diff --git a/docs/cryptor.md b/docs/cryptor.md
index ff8e4ae..5b98e72 100644
--- a/docs/cryptor.md
+++ b/docs/cryptor.md
@@ -117,7 +117,7 @@ func main() {
data := "hello world"
key := "abcdefghijklmnop"
encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
- decrypted := cryptor.AesEcbDecrypt(encrypted, []byte(key))
+ decrypted := cryptor.AesEcbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world
}
```
@@ -178,7 +178,7 @@ func main() {
data := "hello world"
key := "abcdefghijklmnop"
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
- decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key))
+ decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world
}
```
@@ -269,9 +269,9 @@ import (
func main() {
data := "hello world"
- key := "abcdefghijklmnop"
+ key := "abcdefghijklmnop"
encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key))
- decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key))
+ decrypted := cryptor.AesCfbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world
}
```
@@ -332,7 +332,8 @@ func main() {
data := "hello world"
key := "abcdefghijklmnop"
encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key))
- decrypted := cryptor.AesOfbDecrypt(encrypted, []byte(key))
+ decrypted := cryptor.AesOfbDecrypt(encrypted, []byte(key))
+
fmt.Println(string(decrypted)) //hello world
}
```
@@ -387,7 +388,7 @@ import (
)
func main() {
- str := cryptor.Base64StdDecode("aGVsbG8gd29ybGQ=")
+ str := cryptor.Base64StdDecode("aGVsbG8gd29ybGQ=")
fmt.Println(str) //hello world
}
```
@@ -448,8 +449,8 @@ import (
func main() {
data := "hello world"
key := "abcdefgh"
- encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key))
- decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key))
+ encrypted := cryptor.DesEcbEncrypt([]byte(data), []byt(key)
+ decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world
}
@@ -480,7 +481,7 @@ import (
func main() {
data := "hello world"
key := "abcdefgh"
- encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key))
+ encrypted := cryptor.DesCbcEncrypt([]byte(data), []byt(key)
fmt.Println(string(encrypted))
}
@@ -511,8 +512,9 @@ import (
func main() {
data := "hello world"
key := "abcdefgh"
- encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key))
- decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key))
+ encrypted := cryptor.DesCbcEncrypt([]byte(data), []byt(key)
+ decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key))
+
fmt.Println(string(decrypted)) //hello world
}
```
@@ -574,7 +576,7 @@ import (
func main() {
data := "hello world"
key := "abcdefgh"
- encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key))
+ encrypted := cryptor.DesCfbEncrypt([]byte(data), []byt(key)
fmt.Println(string(encrypted))
}
```
@@ -604,8 +606,8 @@ import (
func main() {
data := "hello world"
key := "abcdefgh"
- encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key))
- decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key))
+ encrypted := cryptor.DesCfbEncrypt([]byte(data), []byt(key)
+ decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world
}
```
@@ -666,7 +668,8 @@ func main() {
data := "hello world"
key := "abcdefgh"
encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key))
- decrypted := cryptor.DesOfbDecrypt(encrypted, []byte(key))
+ decrypted := cryptor.DesOfbDecrypt(encrypted, []byte(key))
+
fmt.Println(string(decrypted)) //hello world
}
```
@@ -920,7 +923,7 @@ import (
func main() {
s := cryptor.Sha512("hello world"))
- fmt.Println(s) //309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f
+ fmt.Println(s) //309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f
}
```
@@ -948,8 +951,8 @@ import (
func main() {
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
- if err != nil {
- fmt.Println(err)
+ if err != nil {
+ fmt.Println(err)
}
}
```
@@ -978,13 +981,15 @@ import (
func main() {
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
- if err != nil {
- fmt.Println(err)
- }
- data := []byte("hello world")
- encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
- decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
- fmt.Println(string(decrypted)) //hello world
+ if err != nil {
+ fmt.Println(err)
+ }
+
+ data := []byte("hello world")
+ encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
+ decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
+
+ fmt.Println(string(decrypted)) //hello world
}
```
@@ -1012,13 +1017,15 @@ import (
func main() {
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
- if err != nil {
- fmt.Println(err)
+ if err != nil {
+ fmt.Println(err)
}
- data := []byte("hello world")
- encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
- decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
- fmt.Println(string(decrypted)) //hello world
+
+ data := []byte("hello world")
+ encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
+ decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
+
+ fmt.Println(string(decrypted)) //hello world
}
```
diff --git a/docs/cryptor_zh-CN.md b/docs/cryptor_zh-CN.md
index 3119559..bd52a26 100644
--- a/docs/cryptor_zh-CN.md
+++ b/docs/cryptor_zh-CN.md
@@ -192,6 +192,7 @@ func main() {
key := "abcdefghijklmnop"
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key))
+
fmt.Println(string(decrypted)) //hello world
}
```
@@ -462,7 +463,7 @@ func main() {
data := "hello world"
key := "abcdefgh"
encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key))
- decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key))
+ decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world
}
@@ -525,7 +526,8 @@ func main() {
data := "hello world"
key := "abcdefgh"
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key))
- decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key))
+ decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key))
+
fmt.Println(string(decrypted)) //hello world
}
```
@@ -618,7 +620,7 @@ func main() {
data := "hello world"
key := "abcdefgh"
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key))
- decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key))
+ decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world
}
```
@@ -679,7 +681,7 @@ func main() {
data := "hello world"
key := "abcdefgh"
encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key))
- decrypted := cryptor.DesOfbDecrypt(encrypted, []byte(key))
+ decrypted := cryptor.DesOfbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world
}
```
@@ -995,8 +997,8 @@ func main() {
fmt.Println(err)
}
data := []byte("hello world")
- encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
- decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
+ encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
+ decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
fmt.Println(string(decrypted)) //hello world
}
```
@@ -1029,8 +1031,8 @@ func main() {
fmt.Println(err)
}
data := []byte("hello world")
- encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
- decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
+ encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
+ decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
fmt.Println(string(decrypted)) //hello world
}
```
From 05aefbaa62777019d37b644b719994fdd1dd8d09 Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Fri, 28 Jan 2022 16:25:49 +0800
Subject: [PATCH 09/34] docs: add doc for package datetime
---
docs/datetime.md | 331 +++++++++++++++++++++++++++++++++++++++++
docs/datetime_zh-CN.md | 331 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 662 insertions(+)
create mode 100644 docs/datetime.md
create mode 100644 docs/datetime_zh-CN.md
diff --git a/docs/datetime.md b/docs/datetime.md
new file mode 100644
index 0000000..b3f10bf
--- /dev/null
+++ b/docs/datetime.md
@@ -0,0 +1,331 @@
+# Datetime
+Package datetime supports date and time format and compare.
+
+
+
+## Source:
+
+[https://github.com/duke-git/lancet/blob/main/datetime/datetime.go](https://github.com/duke-git/lancet/blob/main/datetime/datetime.go)
+
+
+
+## Usage:
+```go
+import (
+ "github.com/duke-git/lancet/datetime"
+)
+```
+
+
+
+## Index
+- [AddDay](#AddDay)
+- [AddHour](#AddHour)
+- [AddMinute](#AddMinute)
+- [GetNowDate](#GetNowDate)
+- [GetNowTime](#GetNowTime)
+- [GetNowDateTime](#GetNowDateTime)
+- [GetZeroHourTimestamp](#GetZeroHourTimestamp)
+- [GetNightTimestamp](#GetNightTimestamp)
+- [FormatTimeToStr](#FormatTimeToStr)
+
+- [FormatStrToTime](#FormatStrToTime)
+
+
+
+## Documentation
+
+## Note:
+1. 'format' string param in func FormatTimeToStr and FormatStrToTime function should be one of flows:
+- yyyy-mm-dd hh:mm:ss
+- yyyy-mm-dd hh:mm
+- yyyy-mm-dd hh
+- yyyy-mm-dd
+- yyyy-mm
+- mm-dd
+- dd-mm-yy hh:mm:ss
+- yyyy/mm/dd hh:mm:ss
+- yyyy/mm/dd hh:mm
+- yyyy-mm-dd hh
+- yyyy/mm/dd
+- yyyy/mm
+- mm/dd
+- dd/mm/yy hh:mm:ss
+- yyyy
+- mm
+- hh:mm:ss
+- mm:ss
+
+
+### AddDay
+Add or sub days to time.
+
+Signature:
+
+```go
+func AddDay(t time.Time, day int64) time.Time
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "time"
+ "github.com/duke-git/lancet/datetime"
+)
+
+func main() {
+ now := time.Now()
+ after2Days := datetime.AddDay(now, 2)
+ before2Days := datetime.AddDay(now, -2)
+
+ fmt.Println(after2Days, before2Days)
+}
+```
+
+
+### AddHour
+Add or sub hours to time.
+
+Signature:
+
+```go
+func AddHour(t time.Time, hour int64) time.Time
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "time"
+ "github.com/duke-git/lancet/datetime"
+)
+
+func main() {
+ now := time.Now()
+ after2Hours := datetime.AddHour(now, 2)
+ before2Hours := datetime.AddHour(now, -2)
+
+ fmt.Println(after2Hours, after2Hours)
+}
+```
+
+### AddMinute
+Add or sub minutes to time.
+
+Signature:
+
+```go
+func AddMinute(t time.Time, minute int64) time.Time
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "time"
+ "github.com/duke-git/lancet/datetime"
+)
+
+func main() {
+ now := time.Now()
+ after2Minute := datetime.AddMinute(now, 2)
+ before2Minute := datetime.AddMinute(now, -2)
+
+ fmt.Println(after2Minute, before2Minute)
+}
+```
+
+### GetNowDate
+Get current date string, format is yyyy-mm-dd.
+
+Signature:
+
+```go
+func GetNowDate() string
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "time"
+ "github.com/duke-git/lancet/datetime"
+)
+
+func main() {
+ now := time.Now()
+ currentDate := datetime.GetNowDate()
+ fmt.Println(currentDate) // 2022-01-28
+}
+```
+
+
+### GetNowTime
+Get current time string, format is hh:mm:ss.
+
+Signature:
+
+```go
+func GetNowTime() string
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "time"
+ "github.com/duke-git/lancet/datetime"
+)
+
+func main() {
+ now := time.Now()
+ currentTime := datetime.GetNowTime()
+ fmt.Println(currentDate) // 15:57:33
+}
+```
+
+
+### GetNowDateTime
+Get current date time string, format is yyyy-mm-dd hh:mm:ss.
+
+Signature:
+
+```go
+func GetNowDateTime() string
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "time"
+ "github.com/duke-git/lancet/datetime"
+)
+
+func main() {
+ now := time.Now()
+ current := datetime.GetNowDateTime()
+ fmt.Println(current) // 2022-01-28 15:59:33
+}
+```
+
+
+### GetZeroHourTimestamp
+Return timestamp of zero hour (timestamp of 00:00).
+
+Signature:
+
+```go
+func GetZeroHourTimestamp() int64
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "time"
+ "github.com/duke-git/lancet/datetime"
+)
+
+func main() {
+ now := time.Now()
+ zeroTime := datetime.GetZeroHourTimestamp()
+ fmt.Println(zeroTime) // 1643299200
+}
+```
+
+
+### GetNightTimestamp
+Return timestamp of zero hour (timestamp of 23:59).
+
+Signature:
+
+```go
+func GetNightTimestamp() int64
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "time"
+ "github.com/duke-git/lancet/datetime"
+)
+
+func main() {
+ now := time.Now()
+ nightTime := datetime.GetNightTimestamp()
+ fmt.Println(nightTime) // 1643385599
+}
+```
+
+### FormatTimeToStr
+Format time to string, `format` param specification see note 1.
+
+Signature:
+
+```go
+func FormatTimeToStr(t time.Time, format string) string
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "time"
+ "github.com/duke-git/lancet/datetime"
+)
+
+func main() {
+ now := time.Now()
+ timeStr := datetime.FormatTimeToStr(now, "yyyy/mm/dd hh:mm:ss")
+ fmt.Println(timeStr) //2022/01/28 16:07:44
+}
+```
+
+
+### FormatStrToTime
+Format string to time, `format` param specification see note 1.
+
+Signature:
+
+```go
+func FormatStrToTime(str, format string) (time.Time, error)
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/datetime"
+)
+
+func main() {
+ time := datetime.FormatStrToTime("2006-01-02 15:04:05", "yyyy/mm/dd hh:mm:ss")
+ fmt.Println(time)
+}
+```
+
+
+
diff --git a/docs/datetime_zh-CN.md b/docs/datetime_zh-CN.md
new file mode 100644
index 0000000..665b2d8
--- /dev/null
+++ b/docs/datetime_zh-CN.md
@@ -0,0 +1,331 @@
+# Datetime
+datetime日期时间处理包,格式化日期,比较日期。
+
+
+
+## 源码:
+
+[https://github.com/duke-git/lancet/blob/main/datetime/datetime.go](https://github.com/duke-git/lancet/blob/main/datetime/datetime.go)
+
+
+
+## 用法:
+```go
+import (
+ "github.com/duke-git/lancet/datetime"
+)
+```
+
+
+
+## 目录
+- [AddDay](#AddDay)
+- [AddHour](#AddHour)
+- [AddMinute](#AddMinute)
+- [GetNowDate](#GetNowDate)
+- [GetNowTime](#GetNowTime)
+- [GetNowDateTime](#GetNowDateTime)
+- [GetZeroHourTimestamp](#GetZeroHourTimestamp)
+- [GetNightTimestamp](#GetNightTimestamp)
+
+- [FormatTimeToStr](#FormatTimeToStr)
+- [FormatStrToTime](#FormatStrToTime)
+
+
+
+## 文档
+
+## 注:
+1. 方法FormatTimeToStr和FormatStrToTime中的format参数值需要传以下类型之一:
+- yyyy-mm-dd hh:mm:ss
+- yyyy-mm-dd hh:mm
+- yyyy-mm-dd hh
+- yyyy-mm-dd
+- yyyy-mm
+- mm-dd
+- dd-mm-yy hh:mm:ss
+- yyyy/mm/dd hh:mm:ss
+- yyyy/mm/dd hh:mm
+- yyyy-mm-dd hh
+- yyyy/mm/dd
+- yyyy/mm
+- mm/dd
+- dd/mm/yy hh:mm:ss
+- yyyy
+- mm
+- hh:mm:ss
+- mm:ss
+
+
+### AddDay
+将日期加/减天数
+
+函数签名:
+
+```go
+func AddDay(t time.Time, day int64) time.Time
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "time"
+ "github.com/duke-git/lancet/datetime"
+)
+
+func main() {
+ now := time.Now()
+ after2Days := datetime.AddDay(now, 2)
+ before2Days := datetime.AddDay(now, -2)
+
+ fmt.Println(after2Days, before2Days)
+}
+```
+
+
+### AddHour
+将日期加/减小时数
+
+函数签名:
+
+```go
+func AddHour(t time.Time, hour int64) time.Time
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "time"
+ "github.com/duke-git/lancet/datetime"
+)
+
+func main() {
+ now := time.Now()
+ after2Hours := datetime.AddHour(now, 2)
+ before2Hours := datetime.AddHour(now, -2)
+
+ fmt.Println(after2Hours, after2Hours)
+}
+```
+
+### AddMinute
+将日期加/减分钟数
+
+函数签名:
+
+```go
+func AddMinute(t time.Time, minute int64) time.Time
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "time"
+ "github.com/duke-git/lancet/datetime"
+)
+
+func main() {
+ now := time.Now()
+ after2Minute := datetime.AddMinute(now, 2)
+ before2Minute := datetime.AddMinute(now, -2)
+
+ fmt.Println(after2Minute, before2Minute)
+}
+```
+
+### GetNowDate
+获取当天日期,返回格式:yyyy-mm-dd
+
+函数签名:
+
+```go
+func GetNowDate() string
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "time"
+ "github.com/duke-git/lancet/datetime"
+)
+
+func main() {
+ now := time.Now()
+ currentDate := datetime.GetNowDate()
+ fmt.Println(currentDate) // 2022-01-28
+}
+```
+
+
+### GetNowTime
+获取当时时间,返回格式:hh:mm:ss
+
+函数签名:
+
+```go
+func GetNowTime() string
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "time"
+ "github.com/duke-git/lancet/datetime"
+)
+
+func main() {
+ now := time.Now()
+ currentTime := datetime.GetNowTime()
+ fmt.Println(currentDate) // 15:57:33
+}
+```
+
+
+### GetNowDateTime
+获取当时日期和时间,返回格式:yyyy-mm-dd hh:mm:ss.
+
+函数签名:
+
+```go
+func GetNowDateTime() string
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "time"
+ "github.com/duke-git/lancet/datetime"
+)
+
+func main() {
+ now := time.Now()
+ current := datetime.GetNowDateTime()
+ fmt.Println(current) // 2022-01-28 15:59:33
+}
+```
+
+
+### GetZeroHourTimestamp
+获取零时时间戳(timestamp of 00:00).
+
+函数签名:
+
+```go
+func GetZeroHourTimestamp() int64
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "time"
+ "github.com/duke-git/lancet/datetime"
+)
+
+func main() {
+ now := time.Now()
+ zeroTime := datetime.GetZeroHourTimestamp()
+ fmt.Println(zeroTime) // 1643299200
+}
+```
+
+
+### GetNightTimestamp
+获取午夜时间戳(timestamp of 23:59).
+
+函数签名:
+
+```go
+func GetNightTimestamp() int64
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "time"
+ "github.com/duke-git/lancet/datetime"
+)
+
+func main() {
+ now := time.Now()
+ nightTime := datetime.GetNightTimestamp()
+ fmt.Println(nightTime) // 1643385599
+}
+```
+
+### FormatTimeToStr
+将日期格式化成字符串,`format` 参数格式参考注1
+
+函数签名:
+
+```go
+func FormatTimeToStr(t time.Time, format string) string
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "time"
+ "github.com/duke-git/lancet/datetime"
+)
+
+func main() {
+ now := time.Now()
+ timeStr := datetime.FormatTimeToStr(now, "yyyy/mm/dd hh:mm:ss")
+ fmt.Println(timeStr) //2022/01/28 16:07:44
+}
+```
+
+
+### FormatStrToTime
+将字符串格式化成时间,`format` 参数格式参考注1
+
+函数签名:
+
+```go
+func FormatStrToTime(str, format string) (time.Time, error)
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/datetime"
+)
+
+func main() {
+ time := datetime.FormatStrToTime("2006-01-02 15:04:05", "yyyy/mm/dd hh:mm:ss")
+ fmt.Println(time)
+}
+```
+
+
+
From acce85557f67b98ec2ed9b795e4695de1eee61d2 Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Sat, 29 Jan 2022 22:49:54 +0800
Subject: [PATCH 10/34] fmt: fmt example code in docs
---
docs/datetime.md | 26 +++++++++++++-------------
docs/datetime_zh-CN.md | 20 ++++++++++----------
2 files changed, 23 insertions(+), 23 deletions(-)
diff --git a/docs/datetime.md b/docs/datetime.md
index b3f10bf..f70af0d 100644
--- a/docs/datetime.md
+++ b/docs/datetime.md
@@ -78,8 +78,8 @@ import (
func main() {
now := time.Now()
- after2Days := datetime.AddDay(now, 2)
- before2Days := datetime.AddDay(now, -2)
+ after2Days := datetime.AddDay(now, 2)
+ before2Days := datetime.AddDay(now, -2)
fmt.Println(after2Days, before2Days)
}
@@ -107,8 +107,8 @@ import (
func main() {
now := time.Now()
- after2Hours := datetime.AddHour(now, 2)
- before2Hours := datetime.AddHour(now, -2)
+ after2Hours := datetime.AddHour(now, 2)
+ before2Hours := datetime.AddHour(now, -2)
fmt.Println(after2Hours, after2Hours)
}
@@ -135,8 +135,8 @@ import (
func main() {
now := time.Now()
- after2Minute := datetime.AddMinute(now, 2)
- before2Minute := datetime.AddMinute(now, -2)
+ after2Minute := datetime.AddMinute(now, 2)
+ before2Minute := datetime.AddMinute(now, -2)
fmt.Println(after2Minute, before2Minute)
}
@@ -163,7 +163,7 @@ import (
func main() {
now := time.Now()
- currentDate := datetime.GetNowDate()
+ currentDate := datetime.GetNowDate()
fmt.Println(currentDate) // 2022-01-28
}
```
@@ -190,7 +190,7 @@ import (
func main() {
now := time.Now()
- currentTime := datetime.GetNowTime()
+ currentTime := datetime.GetNowTime()
fmt.Println(currentDate) // 15:57:33
}
```
@@ -217,7 +217,7 @@ import (
func main() {
now := time.Now()
- current := datetime.GetNowDateTime()
+ current := datetime.GetNowDateTime()
fmt.Println(current) // 2022-01-28 15:59:33
}
```
@@ -244,7 +244,7 @@ import (
func main() {
now := time.Now()
- zeroTime := datetime.GetZeroHourTimestamp()
+ zeroTime := datetime.GetZeroHourTimestamp()
fmt.Println(zeroTime) // 1643299200
}
```
@@ -271,7 +271,7 @@ import (
func main() {
now := time.Now()
- nightTime := datetime.GetNightTimestamp()
+ nightTime := datetime.GetNightTimestamp()
fmt.Println(nightTime) // 1643385599
}
```
@@ -297,7 +297,7 @@ import (
func main() {
now := time.Now()
- timeStr := datetime.FormatTimeToStr(now, "yyyy/mm/dd hh:mm:ss")
+ timeStr := datetime.FormatTimeToStr(now, "yyyy/mm/dd hh:mm:ss")
fmt.Println(timeStr) //2022/01/28 16:07:44
}
```
@@ -322,7 +322,7 @@ import (
)
func main() {
- time := datetime.FormatStrToTime("2006-01-02 15:04:05", "yyyy/mm/dd hh:mm:ss")
+ time := datetime.FormatStrToTime("2006-01-02 15:04:05", "yyyy/mm/dd hh:mm:ss")
fmt.Println(time)
}
```
diff --git a/docs/datetime_zh-CN.md b/docs/datetime_zh-CN.md
index 665b2d8..cc5a4af 100644
--- a/docs/datetime_zh-CN.md
+++ b/docs/datetime_zh-CN.md
@@ -107,8 +107,8 @@ import (
func main() {
now := time.Now()
- after2Hours := datetime.AddHour(now, 2)
- before2Hours := datetime.AddHour(now, -2)
+ after2Hours := datetime.AddHour(now, 2)
+ before2Hours := datetime.AddHour(now, -2)
fmt.Println(after2Hours, after2Hours)
}
@@ -135,8 +135,8 @@ import (
func main() {
now := time.Now()
- after2Minute := datetime.AddMinute(now, 2)
- before2Minute := datetime.AddMinute(now, -2)
+ after2Minute := datetime.AddMinute(now, 2)
+ before2Minute := datetime.AddMinute(now, -2)
fmt.Println(after2Minute, before2Minute)
}
@@ -190,7 +190,7 @@ import (
func main() {
now := time.Now()
- currentTime := datetime.GetNowTime()
+ currentTime := datetime.GetNowTime()
fmt.Println(currentDate) // 15:57:33
}
```
@@ -217,7 +217,7 @@ import (
func main() {
now := time.Now()
- current := datetime.GetNowDateTime()
+ current := datetime.GetNowDateTime()
fmt.Println(current) // 2022-01-28 15:59:33
}
```
@@ -244,7 +244,7 @@ import (
func main() {
now := time.Now()
- zeroTime := datetime.GetZeroHourTimestamp()
+ zeroTime := datetime.GetZeroHourTimestamp()
fmt.Println(zeroTime) // 1643299200
}
```
@@ -271,7 +271,7 @@ import (
func main() {
now := time.Now()
- nightTime := datetime.GetNightTimestamp()
+ nightTime := datetime.GetNightTimestamp()
fmt.Println(nightTime) // 1643385599
}
```
@@ -297,7 +297,7 @@ import (
func main() {
now := time.Now()
- timeStr := datetime.FormatTimeToStr(now, "yyyy/mm/dd hh:mm:ss")
+ timeStr := datetime.FormatTimeToStr(now, "yyyy/mm/dd hh:mm:ss")
fmt.Println(timeStr) //2022/01/28 16:07:44
}
```
@@ -322,7 +322,7 @@ import (
)
func main() {
- time := datetime.FormatStrToTime("2006-01-02 15:04:05", "yyyy/mm/dd hh:mm:ss")
+ time := datetime.FormatStrToTime("2006-01-02 15:04:05", "yyyy/mm/dd hh:mm:ss")
fmt.Println(time)
}
```
From 1629b861cd8ec927ed79b34536a947dd57ba8b34 Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Sun, 30 Jan 2022 15:28:33 +0800
Subject: [PATCH 11/34] docs: add doc for package fileutil
---
docs/fileutil.md | 444 +++++++++++++++++++++++++++++++++++++++++
docs/fileutil_zh-CN.md | 444 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 888 insertions(+)
create mode 100644 docs/fileutil.md
create mode 100644 docs/fileutil_zh-CN.md
diff --git a/docs/fileutil.md b/docs/fileutil.md
new file mode 100644
index 0000000..61a7b4d
--- /dev/null
+++ b/docs/fileutil.md
@@ -0,0 +1,444 @@
+# Fileutil
+Package fileutil implements some basic functions for file operations.
+
+
+
+## Source:
+
+[https://github.com/duke-git/lancet/blob/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/fileutil/file.go)
+
+
+
+## Usage:
+```go
+import (
+ "github.com/duke-git/lancet/fileutil"
+)
+```
+
+
+
+## Index
+- [ClearFile](#ClearFile)
+- [CreateFile](#CreateFile)
+- [CopyFile](#CopyFile)
+- [FileMode](#FileMode)
+- [MiMeType](#MiMeType)
+- [IsExist](#IsExist)
+- [IsLink](#IsLink)
+- [IsDir](#IsDir)
+- [ListFileNames](#ListFileNames)
+- [RemoveFile](#RemoveFile)
+- [ReadFileToString](#ReadFileToString)
+- [ReadFileByLine](#ReadFileByLine)
+- [Zip](#Zip)
+
+- [UnZip](#UnZip)
+
+
+
+## Documentation
+
+
+
+### ClearFile
+Clear the file content, write empty string to the file.
+
+Signature:
+
+```go
+func ClearFile(path string) error
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ err := fileutil.ClearFile("./test.txt")
+ if err != nil {
+ fmt.Println(err)
+ }
+}
+```
+
+### CreateFile
+Create file in path. return true if create succeed.
+
+Signature:
+
+```go
+func CreateFile(path string) bool
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ isCreatedSucceed := fileutil.CreateFile("./test.txt")
+ fmt.Println(isCreatedSucceed)
+}
+```
+
+
+### CopyFile
+Copy src file to dest file. If dest file exist will overwrite it.
+
+Signature:
+
+```go
+func CopyFile(srcFilePath string, dstFilePath string) error
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ err := fileutil.CopyFile("./test.txt", "./test_copy.txt")
+ if err != nil {
+ fmt.Println(err)
+ }
+}
+```
+
+
+
+### FileMode
+Return file mode infomation.
+
+Signature:
+
+```go
+func FileMode(path string) (fs.FileMode, error)
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ mode, err := fileutil.FileMode("./test.txt")
+ if err != nil {
+ fmt.Println(err)
+ }
+ fmt.Println(mode)
+}
+```
+
+
+
+### MiMeType
+Get file mime type, 'file' param's type should be string or *os.File.
+
+Signature:
+
+```go
+func MiMeType(file interface{}) string
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "os"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ type1 := fileutil.MiMeType("./test.txt")
+ fmt.Println(type1) //text/plain; charset=utf-8
+
+ f, _ := os.Open("./file.go")
+ type2 := fileutil.MiMeType(f)
+ fmt.Println(type2) //text/plain; charset=utf-8
+}
+```
+
+
+
+
+### IsExist
+Checks if a file or directory exists.
+
+Signature:
+
+```go
+func IsExist(path string) bool
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ fileutil.CreateFile("./test.txt")
+ isFileExist := fileutil.IsExist("./test.txt")
+ fmt.Println(isFileExist) //true
+}
+```
+
+
+
+### IsLink
+Checks if a file is symbol link or not.
+
+Signature:
+
+```go
+func IsLink(path string) bool
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ isLinkFile := fileutil.IsLink("./test.txt")
+ fmt.Println(isLinkFile) //false
+}
+```
+
+
+
+### IsDir
+Checks if the path is directy or not.
+
+Signature:
+
+```go
+func IsDir(path string) bool
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ isDir := fileutil.IsDir("./")
+ fmt.Println(isDir) //true
+
+ isDir = fileutil.IsDir("./test.txt")
+ fmt.Println(isDir) //false
+}
+```
+
+
+
+### ListFileNames
+List all file names in given path.
+
+Signature:
+
+```go
+func ListFileNames(path string) ([]string, error)
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ fileNames, _ := fileutil.ListFileNames("./")
+ fmt.Println(fileNames)
+}
+```
+
+
+
+### RemoveFile
+Remove the file of path.
+
+Signature:
+
+```go
+func RemoveFile(path string) error
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ err := fileutil.RemoveFile("./test.txt")
+ if err != nil {
+ fmt.Println(err)
+ }
+}
+```
+
+
+### ReadFileToString
+Return string of file content.
+
+Signature:
+
+```go
+func ReadFileToString(path string) (string, error)
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "os"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ path := "./test.txt"
+ fileutil.CreateFile(path)
+
+ f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
+ f.WriteString("hello world")
+
+ content, _ := fileutil.ReadFileToString(path)
+ fmt.Println(content) //hello world
+}
+```
+
+
+
+### ReadFileByLine
+Read file line by line, and return slice of lines
+
+Signature:
+
+```go
+func ReadFileByLine(path string)([]string, error)
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "os"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ path := "./text.txt"
+ fileutil.CreateFile(path)
+
+ f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
+ defer f.Close()
+ f.WriteString("hello\nworld")
+
+ contents, _ := fileutil.ReadFileByLine(path)
+ fmt.Println(contents) //[]string{"hello", "world"}
+}
+```
+
+
+
+### Zip
+Create a zip file of fpath, fpath could be a file or a directory.
+
+Signature:
+
+```go
+func Zip(fpath string, destPath string) error
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ err := fileutil.Zip("./test.txt", "./test.zip")
+ if err != nil {
+ fmt.Println(err)
+ }
+}
+```
+
+
+
+
+### UnZip
+Unzip the file and save it to dest path.
+
+Signature:
+
+```go
+func UnZip(zipFile string, destPath string) error
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ err := fileutil.Zip("./test.zip", "./unzip/test.txt")
+ if err != nil {
+ fmt.Println(err)
+ }
+}
+```
+
+
+
+
+
diff --git a/docs/fileutil_zh-CN.md b/docs/fileutil_zh-CN.md
new file mode 100644
index 0000000..d25ce56
--- /dev/null
+++ b/docs/fileutil_zh-CN.md
@@ -0,0 +1,444 @@
+# Fileutil
+fileutil包支持文件基本操作。
+
+
+
+## 源码:
+
+[https://github.com/duke-git/lancet/blob/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/fileutil/file.go)
+
+
+
+## 用法:
+```go
+import (
+ "github.com/duke-git/lancet/fileutil"
+)
+```
+
+
+
+## 目录
+- [ClearFile](#ClearFile)
+- [CreateFile](#CreateFile)
+- [CopyFile](#CopyFile)
+- [FileMode](#FileMode)
+- [MiMeType](#MiMeType)
+- [IsExist](#IsExist)
+- [IsLink](#IsLink)
+- [IsDir](#IsDir)
+
+- [ListFileNames](#ListFileNames)
+- [RemoveFile](#RemoveFile)
+- [ReadFileToString](#ReadFileToString)
+- [ReadFileByLine](#ReadFileByLine)
+- [Zip](#Zip)
+- [UnZip](#UnZip)
+
+
+
+## 文档
+
+
+
+### ClearFile
+清空文件内容
+
+函数签名:
+
+```go
+func ClearFile(path string) error
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ err := fileutil.ClearFile("./test.txt")
+ if err != nil {
+ fmt.Println(err)
+ }
+}
+```
+
+### CreateFile
+创建文件,创建成功返回true, 否则返回false
+
+函数签名:
+
+```go
+func CreateFile(path string) bool
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ isCreatedSucceed := fileutil.CreateFile("./test.txt")
+ fmt.Println(isCreatedSucceed)
+}
+```
+
+
+### CopyFile
+拷贝文件,会覆盖原有的拷贝文件
+
+函数签名:
+
+```go
+func CopyFile(srcFilePath string, dstFilePath string) error
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ err := fileutil.CopyFile("./test.txt", "./test_copy.txt")
+ if err != nil {
+ fmt.Println(err)
+ }
+}
+```
+
+
+
+### FileMode
+获取文件mode信息
+
+函数签名:
+
+```go
+func FileMode(path string) (fs.FileMode, error)
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ mode, err := fileutil.FileMode("./test.txt")
+ if err != nil {
+ fmt.Println(err)
+ }
+ fmt.Println(mode)
+}
+```
+
+
+
+### MiMeType
+获取文件mime类型, 'file'参数的类型必须是string或者*os.File
+
+函数签名:
+
+```go
+func MiMeType(file interface{}) string
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "os"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ type1 := fileutil.MiMeType("./test.txt")
+ fmt.Println(type1) //text/plain; charset=utf-8
+
+ f, _ := os.Open("./file.go")
+ type2 := fileutil.MiMeType(f)
+ fmt.Println(type2) //text/plain; charset=utf-8
+}
+```
+
+
+
+
+### IsExist
+判断文件或目录是否存在
+
+函数签名:
+
+```go
+func IsExist(path string) bool
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ fileutil.CreateFile("./test.txt")
+ isFileExist := fileutil.IsExist("./test.txt")
+ fmt.Println(isFileExist) //true
+}
+```
+
+
+
+### IsLink
+判断文件是否是符号链接
+
+函数签名:
+
+```go
+func IsLink(path string) bool
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ isLinkFile := fileutil.IsLink("./test.txt")
+ fmt.Println(isLinkFile) //false
+}
+```
+
+
+
+### IsDir
+判断目录是否存在
+
+函数签名:
+
+```go
+func IsDir(path string) bool
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ isDir := fileutil.IsDir("./")
+ fmt.Println(isDir) //true
+
+ isDir = fileutil.IsDir("./test.txt")
+ fmt.Println(isDir) //false
+}
+```
+
+
+
+### ListFileNames
+返回目录下所有文件名
+
+函数签名:
+
+```go
+func ListFileNames(path string) ([]string, error)
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ fileNames, _ := fileutil.ListFileNames("./")
+ fmt.Println(fileNames)
+}
+```
+
+
+
+### RemoveFile
+删除文件
+
+函数签名:
+
+```go
+func RemoveFile(path string) error
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ err := fileutil.RemoveFile("./test.txt")
+ if err != nil {
+ fmt.Println(err)
+ }
+}
+```
+
+
+### ReadFileToString
+读取文件内容并返回字符串
+
+函数签名:
+
+```go
+func ReadFileToString(path string) (string, error)
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "os"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ path := "./test.txt"
+ fileutil.CreateFile(path)
+
+ f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
+ f.WriteString("hello world")
+
+ content, _ := fileutil.ReadFileToString(path)
+ fmt.Println(content) //hello world
+}
+```
+
+
+
+### ReadFileByLine
+按行读取文件内容,返回字符串切片包含每一行
+
+函数签名:
+
+```go
+func ReadFileByLine(path string)([]string, error)
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "os"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ path := "./text.txt"
+ fileutil.CreateFile(path)
+
+ f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
+ defer f.Close()
+ f.WriteString("hello\nworld")
+
+ contents, _ := fileutil.ReadFileByLine(path)
+ fmt.Println(contents) //[]string{"hello", "world"}
+}
+```
+
+
+
+### Zip
+zip压缩文件, fpath参数可以是文件或目录
+
+函数签名:
+
+```go
+func Zip(fpath string, destPath string) error
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ err := fileutil.Zip("./test.txt", "./test.zip")
+ if err != nil {
+ fmt.Println(err)
+ }
+}
+```
+
+
+
+
+### UnZip
+zip解压缩文件并保存在目录中
+
+Signature:
+
+```go
+func UnZip(zipFile string, destPath string) error
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/fileutil"
+)
+
+func main() {
+ err := fileutil.Zip("./test.zip", "./unzip/test.txt")
+ if err != nil {
+ fmt.Println(err)
+ }
+}
+```
+
+
+
+
+
From 739113ef9e9359aa745eb5d0b25632a5b5e932d3 Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Sun, 30 Jan 2022 19:04:07 +0800
Subject: [PATCH 12/34] docs: add doc for package formatter
---
docs/formatter.md | 53 +++++++++++++++++++++++++++++++++++++++++
docs/formatter_zh-CN.md | 52 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 105 insertions(+)
create mode 100644 docs/formatter.md
create mode 100644 docs/formatter_zh-CN.md
diff --git a/docs/formatter.md b/docs/formatter.md
new file mode 100644
index 0000000..c07e940
--- /dev/null
+++ b/docs/formatter.md
@@ -0,0 +1,53 @@
+# Formatter
+formatter contains some functions for data formatting.
+
+
+
+## Source:
+
+[https://github.com/duke-git/lancet/blob/main/formatter/formatter.go](https://github.com/duke-git/lancet/blob/main/formatter/formatter.go)
+
+
+
+## Usage:
+```go
+import (
+ "github.com/duke-git/lancet/formatter"
+)
+```
+
+
+
+## Index
+- [Comma](#Comma)
+
+
+
+## Documentation
+
+
+
+### Comma
+Add comma to number by every 3 numbers from right. ahead by symbol char.
+Param should be number or numberic string.
+
+Signature:
+
+```go
+func Comma(v interface{}, symbol string) string
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/formatter"
+)
+
+func main() {
+ fmt.Println(formatter.Comma("12345", "")) // "12,345"
+ fmt.Println(formatter.Comma(12345.67, "¥")) // "¥12,345.67"
+}
+```
diff --git a/docs/formatter_zh-CN.md b/docs/formatter_zh-CN.md
new file mode 100644
index 0000000..4b178ae
--- /dev/null
+++ b/docs/formatter_zh-CN.md
@@ -0,0 +1,52 @@
+# Formatter
+formatter格式化器包含一些数据格式化处理方法。
+
+
+
+## 源码:
+
+[https://github.com/duke-git/lancet/blob/main/formatter/formatter.go](https://github.com/duke-git/lancet/blob/main/formatter/formatter.go)
+
+
+
+## 用法:
+```go
+import (
+ "github.com/duke-git/lancet/formatter"
+)
+```
+
+
+
+## 目录
+- [Comma](#Comma)
+
+
+
+## 文档
+
+
+
+### Comma
+用逗号每隔3位分割数字/字符串,签名添加符号。参数必须是数字或者可以转为数字的字符串
+
+函数签名:
+
+```go
+func Comma(v interface{}, symbol string) string
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/formatter"
+)
+
+func main() {
+ fmt.Println(formatter.Comma("12345", "")) // "12,345"
+ fmt.Println(formatter.Comma(12345.67, "¥")) // "¥12,345.67"
+}
+```
From a4658b2341a82595300a5a2a543843177305aea9 Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Sun, 30 Jan 2022 21:53:25 +0800
Subject: [PATCH 13/34] docs: add doc for package function
---
docs/function.md | 365 +++++++++++++++++++++++++++++++++++++++++
docs/function_zh-CN.md | 365 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 730 insertions(+)
create mode 100644 docs/function.md
create mode 100644 docs/function_zh-CN.md
diff --git a/docs/function.md b/docs/function.md
new file mode 100644
index 0000000..226c948
--- /dev/null
+++ b/docs/function.md
@@ -0,0 +1,365 @@
+# Function
+Package function can control the flow of function execution and support part of functional programming.
+
+
+
+## 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/main/function/watcher.go](https://github.com/duke-git/lancet/blob/main/function/watcher.go)
+
+
+
+## Usage:
+```go
+import (
+ "github.com/duke-git/lancet/function"
+)
+```
+
+
+
+## Index
+- [After](#After)
+- [Before](#Before)
+- [Curry](#Curry)
+- [Compose](#Compose)
+- [Debounced](#Debounced)
+- [Delay](#Delay)
+- [Delay](#Delay)
+- [Watcher](#Watcher)
+
+
+
+## Documentation
+
+
+
+### After
+Creates a function that invokes given func once it's called n or more times.
+
+Signature:
+
+```go
+func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/function"
+)
+
+func main() {
+ arr := []string{"a", "b"}
+ f := function.After(len(arr), func(i int) int {
+ fmt.Println("last print")
+ return i
+ })
+
+ type cb func(args ...interface{}) []reflect.Value
+ print := func(i int, s string, fn cb) {
+ fmt.Printf("arr[%d] is %s \n", i, s)
+ fn(i)
+ }
+
+ fmt.Println("arr is", arr)
+ for i := 0; i < len(arr); i++ {
+ print(i, arr[i], f)
+ }
+
+ //output:
+ // arr is [a b]
+ // arr[0] is a
+ // arr[1] is b
+ // last print
+}
+```
+
+
+
+### Before
+
+creates a function that invokes func once it's called less than n times.
+
+Signature:
+
+```go
+func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/function"
+ "github.com/duke-git/lancet/internal"
+)
+
+func main() {
+ assert := internal.NewAssert(t, "TestBefore")
+
+ arr := []string{"a", "b", "c", "d", "e"}
+ f := function.Before(3, func(i int) int {
+ return i
+ })
+
+ var res []int64
+ type cb func(args ...interface{}) []reflect.Value
+ appendStr := func(i int, s string, fn cb) {
+ v := fn(i)
+ res = append(res, v[0].Int())
+ }
+
+ for i := 0; i < len(arr); i++ {
+ appendStr(i, arr[i], f)
+ }
+
+ expected := []int64{0, 1, 2, 2, 2}
+ assert.Equal(expected, res)
+}
+```
+
+
+
+### Curry
+
+Make a curry function.
+
+Signature:
+
+```go
+type Fn func(...interface{}) interface{}
+func (f Fn) Curry(i interface{}) func(...interface{}) interface{}
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/function"
+)
+
+func main() {
+ add := func(a, b int) int {
+ return a + b
+ }
+ var addCurry function.Fn = func(values ...interface{}) interface{} {
+ return add(values[0].(int), values[1].(int))
+ }
+ add1 := addCurry.Curry(1)
+ result := add1(2)
+ fmt.Println(result) //3
+}
+```
+
+
+
+### Compose
+
+Compose the function list from right to left, then return the composed function.
+
+Signature:
+
+```go
+func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) interface{}
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/function"
+)
+
+func main() {
+ add1 := func(v ...interface{}) interface{} {
+ return v[0].(int) + 1
+ }
+ add2 := func(v ...interface{}) interface{} {
+ return v[0].(int) + 2
+ }
+
+ add3 := function.Compose(add1, add2)
+ result := add3(1)
+
+ fmt.Println(result) //4
+}
+```
+
+
+
+### Debounced
+
+Creates a debounced function that delays invoking fn until after wait duration have elapsed since the last time the debounced function was invoked.
+
+Signature:
+
+```go
+func Debounced(fn func(), duration time.Duration) func()
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/function"
+)
+
+func main() {
+ count := 0
+ add := func() {
+ count++
+ }
+
+ debouncedAdd := function.Debounced(add, 50*time.Microsecond)
+ function.debouncedAdd()
+ function.debouncedAdd()
+ function.debouncedAdd()
+ function.debouncedAdd()
+
+ time.Sleep(100 * time.Millisecond)
+ fmt.Println(count) //1
+
+ function.debouncedAdd()
+ time.Sleep(100 * time.Millisecond)
+ fmt.Println(count) //2
+}
+```
+
+
+
+### Delay
+
+Invoke function after delayed time.
+
+Signature:
+
+```go
+func Delay(delay time.Duration, fn interface{}, args ...interface{})
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/function"
+)
+
+func main() {
+ var print = func(s string) {
+ fmt.Println(count) //test delay
+ }
+ function.Delay(2*time.Second, print, "test delay")
+}
+```
+
+
+
+### Schedule
+
+Invoke function every duration time, until close the returned bool chan.
+
+Signature:
+
+```go
+func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/function"
+)
+
+func main() {
+ var res []string
+ appendStr := func(s string) {
+ res = append(res, s)
+ }
+
+ stop := function.Schedule(1*time.Second, appendStr, "*")
+ time.Sleep(5 * time.Second)
+ close(stop)
+
+ fmt.Println(res) //[* * * * *]
+}
+```
+
+
+
+### Watcher
+
+Watcher is used for record code excution time. can start/stop/reset the watch timer. get the elapsed time of function execution.
+
+Signature:
+
+```go
+type Watcher struct {
+ startTime int64
+ stopTime int64
+ excuting bool
+}
+func (w *Watcher) Start() //start the watcher
+func (w *Watcher) Stop() //stop the watcher
+func (w *Watcher) Reset() //reset the watcher
+func (w *Watcher) GetElapsedTime() time.Duration //get the elapsed time of function execution
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/function"
+)
+
+func main() {
+ w := &function.Watcher{}
+ w.Start()
+
+ longRunningTask()
+
+ fmt.Println(w.excuting) //true
+
+ w.Stop()
+
+ eapsedTime := w.GetElapsedTime().Milliseconds()
+ fmt.Println(eapsedTime)
+
+ w.Reset()
+
+ fmt.Println(w.excuting) //false
+
+ fmt.Println(w.startTime) //0
+ fmt.Println(w.stopTime) //0
+}
+
+func longRunningTask() {
+ var slice []int64
+ for i := 0; i < 10000000; i++ {
+ slice = append(slice, int64(i))
+ }
+}
+
+```
+
+
+
diff --git a/docs/function_zh-CN.md b/docs/function_zh-CN.md
new file mode 100644
index 0000000..cf96bc2
--- /dev/null
+++ b/docs/function_zh-CN.md
@@ -0,0 +1,365 @@
+# Function
+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/main/function/watcher.go](https://github.com/duke-git/lancet/blob/main/function/watcher.go)
+
+
+
+## 用法:
+```go
+import (
+ "github.com/duke-git/lancet/function"
+)
+```
+
+
+
+## 目录
+- [After](#After)
+- [Before](#Before)
+- [Curry](#Curry)
+- [Compose](#Compose)
+- [Debounced](#Debounced)
+- [Delay](#Delay)
+- [Delay](#Delay)
+- [Watcher](#Watcher)
+
+
+
+## 文档
+
+
+
+### After
+创建一个函数,当他被调用n或更多次之后将马上触发fn
+
+函数签名:
+
+```go
+func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/function"
+)
+
+func main() {
+ arr := []string{"a", "b"}
+ f := function.After(len(arr), func(i int) int {
+ fmt.Println("last print")
+ return i
+ })
+
+ type cb func(args ...interface{}) []reflect.Value
+ print := func(i int, s string, fn cb) {
+ fmt.Printf("arr[%d] is %s \n", i, s)
+ fn(i)
+ }
+
+ fmt.Println("arr is", arr)
+ for i := 0; i < len(arr); i++ {
+ print(i, arr[i], f)
+ }
+
+ //output:
+ // arr is [a b]
+ // arr[0] is a
+ // arr[1] is b
+ // last print
+}
+```
+
+
+
+### Before
+
+创建一个函数,调用次数不超过n次,之后再调用这个函数,将返回一次最后调用fn的结果
+
+函数签名:
+
+```go
+func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/function"
+ "github.com/duke-git/lancet/internal"
+)
+
+func main() {
+ assert := internal.NewAssert(t, "TestBefore")
+
+ arr := []string{"a", "b", "c", "d", "e"}
+ f := function.Before(3, func(i int) int {
+ return i
+ })
+
+ var res []int64
+ type cb func(args ...interface{}) []reflect.Value
+ appendStr := func(i int, s string, fn cb) {
+ v := fn(i)
+ res = append(res, v[0].Int())
+ }
+
+ for i := 0; i < len(arr); i++ {
+ appendStr(i, arr[i], f)
+ }
+
+ expected := []int64{0, 1, 2, 2, 2}
+ assert.Equal(expected, res)
+}
+```
+
+
+
+### Curry
+
+创建一个柯里化的函数
+
+函数签名:
+
+```go
+type Fn func(...interface{}) interface{}
+func (f Fn) Curry(i interface{}) func(...interface{}) interface{}
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/function"
+)
+
+func main() {
+ add := func(a, b int) int {
+ return a + b
+ }
+ var addCurry function.Fn = func(values ...interface{}) interface{} {
+ return add(values[0].(int), values[1].(int))
+ }
+ add1 := addCurry.Curry(1)
+ result := add1(2)
+ fmt.Println(result) //3
+}
+```
+
+
+
+### Compose
+
+从右至左组合函数列表fnList, 返回组合后的函数
+
+函数签名:
+
+```go
+func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) interface{}
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/function"
+)
+
+func main() {
+ add1 := func(v ...interface{}) interface{} {
+ return v[0].(int) + 1
+ }
+ add2 := func(v ...interface{}) interface{} {
+ return v[0].(int) + 2
+ }
+
+ add3 := function.Compose(add1, add2)
+ result := add3(1)
+
+ fmt.Println(result) //4
+}
+```
+
+
+
+### Debounced
+
+创建一个 debounced 函数,该函数延迟调用 fn 直到自上次调用 debounced 函数后等待持续时间过去。
+
+函数签名:
+
+```go
+func Debounced(fn func(), duration time.Duration) func()
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/function"
+)
+
+func main() {
+ count := 0
+ add := func() {
+ count++
+ }
+
+ debouncedAdd := function.Debounced(add, 50*time.Microsecond)
+ function.debouncedAdd()
+ function.debouncedAdd()
+ function.debouncedAdd()
+ function.debouncedAdd()
+
+ time.Sleep(100 * time.Millisecond)
+ fmt.Println(count) //1
+
+ function.debouncedAdd()
+ time.Sleep(100 * time.Millisecond)
+ fmt.Println(count) //2
+}
+```
+
+
+
+### Delay
+
+延迟delay时间后调用函数
+
+函数签名:
+
+```go
+func Delay(delay time.Duration, fn interface{}, args ...interface{})
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/function"
+)
+
+func main() {
+ var print = func(s string) {
+ fmt.Println(count) //test delay
+ }
+ function.Delay(2*time.Second, print, "test delay")
+}
+```
+
+
+
+### Schedule
+
+每次持续时间调用函数,直到关闭返回的 bool chan
+
+函数签名:
+
+```go
+func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/function"
+)
+
+func main() {
+ var res []string
+ appendStr := func(s string) {
+ res = append(res, s)
+ }
+
+ stop := function.Schedule(1*time.Second, appendStr, "*")
+ time.Sleep(5 * time.Second)
+ close(stop)
+
+ fmt.Println(res) //[* * * * *]
+}
+```
+
+
+
+### Watcher
+
+Watcher 用于记录代码执行时间。可以启动/停止/重置手表定时器。获取函数执行的时间。
+
+函数签名:
+
+```go
+type Watcher struct {
+ startTime int64
+ stopTime int64
+ excuting bool
+}
+func (w *Watcher) Start() //start the watcher
+func (w *Watcher) Stop() //stop the watcher
+func (w *Watcher) Reset() //reset the watcher
+func (w *Watcher) GetElapsedTime() time.Duration //get the elapsed time of function execution
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/function"
+)
+
+func main() {
+ w := &function.Watcher{}
+ w.Start()
+
+ longRunningTask()
+
+ fmt.Println(w.excuting) //true
+
+ w.Stop()
+
+ eapsedTime := w.GetElapsedTime().Milliseconds()
+ fmt.Println(eapsedTime)
+
+ w.Reset()
+
+ fmt.Println(w.excuting) //false
+
+ fmt.Println(w.startTime) //0
+ fmt.Println(w.stopTime) //0
+}
+
+func longRunningTask() {
+ var slice []int64
+ for i := 0; i < 10000000; i++ {
+ slice = append(slice, int64(i))
+ }
+}
+
+```
+
+
+
From 0f1d3fb553f64dcca03254e8e82398cf1d002ce5 Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Sun, 30 Jan 2022 21:54:24 +0800
Subject: [PATCH 14/34] docs: fix misspell in readme file
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 00cc575..2a1ee30 100644
--- a/README.md
+++ b/README.md
@@ -282,7 +282,7 @@ func (f Fn) Curry(i interface{}) func(...interface{}) interface{} //make a curr
func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) interface{} //compose the functions from right to left
func Debounced(fn func(), duration time.Duration) func() //creates a debounced function that delays invoking fn until after wait duration have elapsed since the last time the debounced function was invoked.
func Delay(delay time.Duration, fn interface{}, args ...interface{}) //invoke function after delayed time
-func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool //invoke function every duration time, util close the returned bool chan
+func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool //invoke function every duration time, until close the returned bool chan
func (w *Watcher) Start() //start the watch timer.
func (w *Watcher) Stop() //stop the watch timer
func (w *Watcher) Reset() {} //reset the watch timer.
From e367123070a794654d3f1f23ff22fb19e8f48915 Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Sun, 30 Jan 2022 22:01:52 +0800
Subject: [PATCH 15/34] docs: fix code fmt issue
---
docs/function.md | 18 +++++++++---------
docs/function_zh-CN.md | 32 ++++++++++++++++----------------
2 files changed, 25 insertions(+), 25 deletions(-)
diff --git a/docs/function.md b/docs/function.md
index 226c948..c05ad53 100644
--- a/docs/function.md
+++ b/docs/function.md
@@ -54,7 +54,7 @@ import (
)
func main() {
- arr := []string{"a", "b"}
+ arr := []string{"a", "b"}
f := function.After(len(arr), func(i int) int {
fmt.Println("last print")
return i
@@ -155,7 +155,7 @@ func main() {
return add(values[0].(int), values[1].(int))
}
add1 := addCurry.Curry(1)
- result := add1(2)
+ result := add1(2)
fmt.Println(result) //3
}
```
@@ -234,7 +234,7 @@ func main() {
function.debouncedAdd()
time.Sleep(100 * time.Millisecond)
- fmt.Println(count) //2
+ fmt.Println(count) //2
}
```
@@ -260,7 +260,7 @@ import (
)
func main() {
- var print = func(s string) {
+ var print = func(s string) {
fmt.Println(count) //test delay
}
function.Delay(2*time.Second, print, "test delay")
@@ -298,7 +298,7 @@ func main() {
time.Sleep(5 * time.Second)
close(stop)
- fmt.Println(res) //[* * * * *]
+ fmt.Println(res) //[* * * * *]
}
```
@@ -342,14 +342,14 @@ func main() {
w.Stop()
eapsedTime := w.GetElapsedTime().Milliseconds()
- fmt.Println(eapsedTime)
+ fmt.Println(eapsedTime)
w.Reset()
- fmt.Println(w.excuting) //false
+ fmt.Println(w.excuting) //false
- fmt.Println(w.startTime) //0
- fmt.Println(w.stopTime) //0
+ fmt.Println(w.startTime) //0
+ fmt.Println(w.stopTime) //0
}
func longRunningTask() {
diff --git a/docs/function_zh-CN.md b/docs/function_zh-CN.md
index cf96bc2..6331be8 100644
--- a/docs/function_zh-CN.md
+++ b/docs/function_zh-CN.md
@@ -54,7 +54,7 @@ import (
)
func main() {
- arr := []string{"a", "b"}
+ arr := []string{"a", "b"}
f := function.After(len(arr), func(i int) int {
fmt.Println("last print")
return i
@@ -102,7 +102,7 @@ import (
)
func main() {
- assert := internal.NewAssert(t, "TestBefore")
+ assert := internal.NewAssert(t, "TestBefore")
arr := []string{"a", "b", "c", "d", "e"}
f := function.Before(3, func(i int) int {
@@ -148,15 +148,15 @@ import (
)
func main() {
- add := func(a, b int) int {
+ add := func(a, b int) int {
return a + b
}
var addCurry function.Fn = func(values ...interface{}) interface{} {
return add(values[0].(int), values[1].(int))
}
add1 := addCurry.Curry(1)
- result := add1(2)
- fmt.Println(result) //3
+ result := add1(2)
+ fmt.Println(result) //3
}
```
@@ -182,17 +182,17 @@ import (
)
func main() {
- add1 := func(v ...interface{}) interface{} {
+ add1 := func(v ...interface{}) interface{} {
return v[0].(int) + 1
}
- add2 := func(v ...interface{}) interface{} {
+ add2 := func(v ...interface{}) interface{} {
return v[0].(int) + 2
}
- add3 := function.Compose(add1, add2)
+ add3 := function.Compose(add1, add2)
result := add3(1)
- fmt.Println(result) //4
+ fmt.Println(result) //4
}
```
@@ -218,7 +218,7 @@ import (
)
func main() {
- count := 0
+ count := 0
add := func() {
count++
}
@@ -234,7 +234,7 @@ func main() {
function.debouncedAdd()
time.Sleep(100 * time.Millisecond)
- fmt.Println(count) //2
+ fmt.Println(count) //2
}
```
@@ -260,7 +260,7 @@ import (
)
func main() {
- var print = func(s string) {
+ var print = func(s string) {
fmt.Println(count) //test delay
}
function.Delay(2*time.Second, print, "test delay")
@@ -342,14 +342,14 @@ func main() {
w.Stop()
eapsedTime := w.GetElapsedTime().Milliseconds()
- fmt.Println(eapsedTime)
+ fmt.Println(eapsedTime)
w.Reset()
- fmt.Println(w.excuting) //false
+ fmt.Println(w.excuting) //false
- fmt.Println(w.startTime) //0
- fmt.Println(w.stopTime) //0
+ fmt.Println(w.startTime) //0
+ fmt.Println(w.stopTime) //0
}
func longRunningTask() {
From a3eb269bdb8bfad1f8b48a2d6ce1f70ea4b69485 Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Mon, 31 Jan 2022 23:34:44 +0800
Subject: [PATCH 16/34] docs: add doc for package netutil
---
docs/netutil.md | 455 ++++++++++++++++++++++++++++++++++++++++++
docs/netutil_zh-CN.md | 455 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 910 insertions(+)
create mode 100644 docs/netutil.md
create mode 100644 docs/netutil_zh-CN.md
diff --git a/docs/netutil.md b/docs/netutil.md
new file mode 100644
index 0000000..ddab77f
--- /dev/null
+++ b/docs/netutil.md
@@ -0,0 +1,455 @@
+# Netutil
+Package netutil contains functions to get net information and send http request.
+
+
+
+## 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/main/netutil/request.go](https://github.com/duke-git/lancet/blob/main/netutil/request.go)
+
+
+
+## Usage:
+```go
+import (
+ "github.com/duke-git/lancet/netutil"
+)
+```
+
+
+
+## Index
+- [ConvertMapToQueryString](#ConvertMapToQueryString)
+- [GetInternalIp](#GetInternalIp)
+- [GetPublicIpInfo](#GetPublicIpInfo)
+- [IsPublicIP](#IsPublicIP)
+- [HttpGet](#HttpGet)
+- [HttpDelete](#HttpDelete)
+- [HttpPost](#HttpPost)
+- [HttpPut](#HttpPut)
+
+- [HttpPatch](#HttpPatch)
+- [ParseHttpResponse](#ParseHttpResponse)
+
+
+
+## Documentation
+
+
+### ConvertMapToQueryString
+Convert map to url query string.
+
+Signature:
+
+```go
+func ConvertMapToQueryString(param map[string]interface{}) string
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/netutil"
+)
+
+func main() {
+ var m = map[string]interface{}{
+ "c": 3,
+ "a": 1,
+ "b": 2,
+ }
+ qs := netutil.ConvertMapToQueryString(m)
+
+ fmt.Println(qs) //a=1&b=2&c=3
+}
+```
+
+
+
+### GetInternalIp
+Get internal ip information.
+
+Signature:
+
+```go
+func GetInternalIp() string
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "net"
+ "github.com/duke-git/lancet/netutil"
+)
+
+func main() {
+ internalIp := netutil.GetInternalIp()
+ ip := net.ParseIP(internalIp)
+
+ fmt.Println(ip) //192.168.1.9
+}
+```
+
+
+
+### GetPublicIpInfo
+Get public ip information.
+
+Signature:
+
+```go
+func GetPublicIpInfo() (*PublicIpInfo, error)
+type PublicIpInfo struct {
+ Status string `json:"status"`
+ Country string `json:"country"`
+ CountryCode string `json:"countryCode"`
+ Region string `json:"region"`
+ RegionName string `json:"regionName"`
+ City string `json:"city"`
+ Lat float64 `json:"lat"`
+ Lon float64 `json:"lon"`
+ Isp string `json:"isp"`
+ Org string `json:"org"`
+ As string `json:"as"`
+ Ip string `json:"query"`
+}
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/netutil"
+)
+
+func main() {
+ publicIpInfo, err := netutil.GetPublicIpInfo()
+ if err != nil {
+ fmt.Println(err)
+ }
+
+ fmt.Println(publicIpInfo)
+}
+```
+
+
+
+### IsPublicIP
+Checks if a ip is public or not.
+
+Signature:
+
+```go
+func IsPublicIP(IP net.IP) bool
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "net"
+ "github.com/duke-git/lancet/netutil"
+)
+
+func main() {
+ ip1 := net.ParseIP("192.168.0.1")
+ ip2 := net.ParseIP("36.112.24.10")
+
+ fmt.Println(netutil.IsPublicIP(ip1)) //false
+ fmt.Println(netutil.IsPublicIP(ip2)) //true
+}
+```
+
+
+
+
+### HttpGet
+Send http get request.
+
+Signature:
+
+```go
+// 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[2] is post body which type should be []byte.
+// params[3] is http client which type should be http.Client.
+func HttpGet(url string, params ...interface{}) (*http.Response, error)
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "io/ioutil"
+ "log"
+ "github.com/duke-git/lancet/netutil"
+)
+
+func main() {
+ url := "https://jsonplaceholder.typicode.com/todos/1"
+ header := map[string]string{
+ "Content-Type": "application/json",
+ }
+
+ resp, err := netutil.HttpGet(url, header)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ body, _ := ioutil.ReadAll(resp.Body)
+ fmt.Println(body)
+}
+```
+
+
+
+### HttpPost
+Send http post request.
+
+Signature:
+
+```go
+// 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[2] is post body which type should be []byte.
+// params[3] is http client which type should be http.Client.
+func HttpPost(url string, params ...interface{}) (*http.Response, error)
+```
+Example:
+
+```go
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "github.com/duke-git/lancet/netutil"
+)
+
+func main() {
+ url := "https://jsonplaceholder.typicode.com/todos"
+ header := map[string]string{
+ "Content-Type": "application/json",
+ }
+ type Todo struct {
+ UserId int `json:"userId"`
+ Title string `json:"title"`
+ }
+ todo := Todo{1, "TestAddToDo"}
+ bodyParams, _ := json.Marshal(todo)
+
+ resp, err := netutil.HttpPost(url, header, nil, bodyParams)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ body, _ := ioutil.ReadAll(resp.Body)
+ fmt.Println(body)
+}
+```
+
+
+
+### HttpPut
+Send http put request.
+
+Signature:
+
+```go
+// 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[2] is post body which type should be []byte.
+// params[3] is http client which type should be http.Client.
+func HttpPut(url string, params ...interface{}) (*http.Response, error)
+```
+Example:
+
+```go
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "github.com/duke-git/lancet/netutil"
+)
+
+func main() {
+ url := "https://jsonplaceholder.typicode.com/todos/1"
+ header := map[string]string{
+ "Content-Type": "application/json",
+ }
+ type Todo struct {
+ Id int `json:"id"`
+ UserId int `json:"userId"`
+ Title string `json:"title"`
+ }
+ todo := Todo{1, 1, "TestPutToDo"}
+ bodyParams, _ := json.Marshal(todo)
+
+ resp, err := netutil.HttpPut(url, header, nil, bodyParams)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ body, _ := ioutil.ReadAll(resp.Body)
+ fmt.Println(body)
+}
+```
+
+
+
+### HttpDelete
+Send http delete request.
+
+Signature:
+
+```go
+// 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[2] is post body which type should be []byte.
+// params[3] is http client which type should be http.Client.
+func HttpDelete(url string, params ...interface{}) (*http.Response, error)
+```
+Example:
+
+```go
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "github.com/duke-git/lancet/netutil"
+)
+
+func main() {
+ url := "https://jsonplaceholder.typicode.com/todos/1"
+ resp, err := netutil.HttpDelete(url)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ body, _ := ioutil.ReadAll(resp.Body)
+ fmt.Println(body)
+}
+```
+
+
+
+### HttpPatch
+Send http patch request.
+
+Signature:
+
+```go
+// 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[2] is post body which type should be []byte.
+// params[3] is http client which type should be http.Client.
+func HttpPatch(url string, params ...interface{}) (*http.Response, error)
+```
+Example:
+
+```go
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "github.com/duke-git/lancet/netutil"
+)
+
+func main() {
+ url := "https://jsonplaceholder.typicode.com/todos/1"
+ header := map[string]string{
+ "Content-Type": "application/json",
+ }
+ type Todo struct {
+ Id int `json:"id"`
+ UserId int `json:"userId"`
+ Title string `json:"title"`
+ }
+ todo := Todo{1, 1, "TestPatchToDo"}
+ bodyParams, _ := json.Marshal(todo)
+
+ resp, err := netutil.HttpPatch(url, header, nil, bodyParams)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ body, _ := ioutil.ReadAll(resp.Body)
+ fmt.Println(body)
+}
+```
+
+
+
+### ParseHttpResponse
+Decode http response to specified interface.
+
+Signature:
+
+```go
+func ParseHttpResponse(resp *http.Response, obj interface{}) error
+```
+Example:
+
+```go
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "github.com/duke-git/lancet/netutil"
+)
+
+func main() {
+ url := "https://jsonplaceholder.typicode.com/todos/1"
+ header := map[string]string{
+ "Content-Type": "application/json",
+ }
+
+ resp, err := netutil.HttpGet(url, header)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ type Todo struct {
+ Id int `json:"id"`
+ UserId int `json:"userId"`
+ Title string `json:"title"`
+ Completed bool `json:"completed"`
+ }
+
+ toDoResp := &Todo{}
+ err = netutil.ParseHttpResponse(resp, toDoResp)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Println(toDoResp)
+}
+```
+
diff --git a/docs/netutil_zh-CN.md b/docs/netutil_zh-CN.md
new file mode 100644
index 0000000..93c4beb
--- /dev/null
+++ b/docs/netutil_zh-CN.md
@@ -0,0 +1,455 @@
+# Netutil
+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/main/netutil/request.go](https://github.com/duke-git/lancet/blob/main/netutil/request.go)
+
+
+
+## 用法:
+```go
+import (
+ "github.com/duke-git/lancet/netutil"
+)
+```
+
+
+
+## 目录
+- [ConvertMapToQueryString](#ConvertMapToQueryString)
+- [GetInternalIp](#GetInternalIp)
+- [GetPublicIpInfo](#GetPublicIpInfo)
+- [IsPublicIP](#IsPublicIP)
+- [HttpGet](#HttpGet)
+- [HttpDelete](#HttpDelete)
+- [HttpPost](#HttpPost)
+- [HttpPut](#HttpPut)
+
+- [HttpPatch](#HttpPatch)
+- [ParseHttpResponse](#ParseHttpResponse)
+
+
+
+## 文档
+
+
+### ConvertMapToQueryString
+将map转换成http查询字符串.
+
+函数签名:
+
+```go
+func ConvertMapToQueryString(param map[string]interface{}) string
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/netutil"
+)
+
+func main() {
+ var m = map[string]interface{}{
+ "c": 3,
+ "a": 1,
+ "b": 2,
+ }
+ qs := netutil.ConvertMapToQueryString(m)
+
+ fmt.Println(qs) //a=1&b=2&c=3
+}
+```
+
+
+
+### GetInternalIp
+获取内部ip
+
+函数签名:
+
+```go
+func GetInternalIp() string
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "net"
+ "github.com/duke-git/lancet/netutil"
+)
+
+func main() {
+ internalIp := netutil.GetInternalIp()
+ ip := net.ParseIP(internalIp)
+
+ fmt.Println(ip) //192.168.1.9
+}
+```
+
+
+
+### GetPublicIpInfo
+获取公网ip信息
+
+函数签名:
+
+```go
+func GetPublicIpInfo() (*PublicIpInfo, error)
+type PublicIpInfo struct {
+ Status string `json:"status"`
+ Country string `json:"country"`
+ CountryCode string `json:"countryCode"`
+ Region string `json:"region"`
+ RegionName string `json:"regionName"`
+ City string `json:"city"`
+ Lat float64 `json:"lat"`
+ Lon float64 `json:"lon"`
+ Isp string `json:"isp"`
+ Org string `json:"org"`
+ As string `json:"as"`
+ Ip string `json:"query"`
+}
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/netutil"
+)
+
+func main() {
+ publicIpInfo, err := netutil.GetPublicIpInfo()
+ if err != nil {
+ fmt.Println(err)
+ }
+
+ fmt.Println(publicIpInfo)
+}
+```
+
+
+
+### IsPublicIP
+判断ip是否是公共ip
+
+函数签名:
+
+```go
+func IsPublicIP(IP net.IP) bool
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "net"
+ "github.com/duke-git/lancet/netutil"
+)
+
+func main() {
+ ip1 := net.ParseIP("192.168.0.1")
+ ip2 := net.ParseIP("36.112.24.10")
+
+ fmt.Println(netutil.IsPublicIP(ip1)) //false
+ fmt.Println(netutil.IsPublicIP(ip2)) //true
+}
+```
+
+
+
+
+### HttpGet
+发送http get请求
+
+函数签名:
+
+```go
+// params[0] http请求header,类型必须是http.Header或者map[string]string
+// params[1] http查询字符串,类型必须是url.Values或者map[string]interface{}
+// params[2] post请求体,类型必须是[]byte
+// params[3] http client,类型必须是http.Client
+func HttpGet(url string, params ...interface{}) (*http.Response, error)
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "io/ioutil"
+ "log"
+ "github.com/duke-git/lancet/netutil"
+)
+
+func main() {
+ url := "https://jsonplaceholder.typicode.com/todos/1"
+ header := map[string]string{
+ "Content-Type": "application/json",
+ }
+
+ resp, err := netutil.HttpGet(url, header)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ body, _ := ioutil.ReadAll(resp.Body)
+ fmt.Println(body)
+}
+```
+
+
+
+### HttpPost
+发送http post请求
+
+函数签名:
+
+```go
+// params[0] http请求header,类型必须是http.Header或者map[string]string
+// params[1] http查询字符串,类型必须是url.Values或者map[string]interface{}
+// params[2] post请求体,类型必须是[]byte
+// params[3] http client,类型必须是http.Client
+func HttpPost(url string, params ...interface{}) (*http.Response, error)
+```
+例子:
+
+```go
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "github.com/duke-git/lancet/netutil"
+)
+
+func main() {
+ url := "https://jsonplaceholder.typicode.com/todos"
+ header := map[string]string{
+ "Content-Type": "application/json",
+ }
+ type Todo struct {
+ UserId int `json:"userId"`
+ Title string `json:"title"`
+ }
+ todo := Todo{1, "TestAddToDo"}
+ bodyParams, _ := json.Marshal(todo)
+
+ resp, err := netutil.HttpPost(url, header, nil, bodyParams)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ body, _ := ioutil.ReadAll(resp.Body)
+ fmt.Println(body)
+}
+```
+
+
+
+### HttpPut
+发送http put请求
+
+函数签名:
+
+```go
+// params[0] http请求header,类型必须是http.Header或者map[string]string
+// params[1] http查询字符串,类型必须是url.Values或者map[string]interface{}
+// params[2] post请求体,类型必须是[]byte
+// params[3] http client,类型必须是http.Client
+func HttpPut(url string, params ...interface{}) (*http.Response, error)
+```
+Example:
+
+```go
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "github.com/duke-git/lancet/netutil"
+)
+
+func main() {
+ url := "https://jsonplaceholder.typicode.com/todos/1"
+ header := map[string]string{
+ "Content-Type": "application/json",
+ }
+ type Todo struct {
+ Id int `json:"id"`
+ UserId int `json:"userId"`
+ Title string `json:"title"`
+ }
+ todo := Todo{1, 1, "TestPutToDo"}
+ bodyParams, _ := json.Marshal(todo)
+
+ resp, err := netutil.HttpPut(url, header, nil, bodyParams)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ body, _ := ioutil.ReadAll(resp.Body)
+ fmt.Println(body)
+}
+```
+
+
+
+### HttpDelete
+发送http delete请求
+
+函数签名:
+
+```go
+// params[0] http请求header,类型必须是http.Header或者map[string]string
+// params[1] http查询字符串,类型必须是url.Values或者map[string]interface{}
+// params[2] post请求体,类型必须是[]byte
+// params[3] http client,类型必须是http.Client
+func HttpDelete(url string, params ...interface{}) (*http.Response, error)
+```
+例子:
+
+```go
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "github.com/duke-git/lancet/netutil"
+)
+
+func main() {
+ url := "https://jsonplaceholder.typicode.com/todos/1"
+ resp, err := netutil.HttpDelete(url)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ body, _ := ioutil.ReadAll(resp.Body)
+ fmt.Println(body)
+}
+```
+
+
+
+### HttpPatch
+发送http patch请求
+
+函数签名:
+
+```go
+// params[0] http请求header,类型必须是http.Header或者map[string]string
+// params[1] http查询字符串,类型必须是url.Values或者map[string]interface{}
+// params[2] post请求体,类型必须是[]byte
+// params[3] http client,类型必须是http.Client
+func HttpPatch(url string, params ...interface{}) (*http.Response, error)
+```
+例子:
+
+```go
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "github.com/duke-git/lancet/netutil"
+)
+
+func main() {
+ url := "https://jsonplaceholder.typicode.com/todos/1"
+ header := map[string]string{
+ "Content-Type": "application/json",
+ }
+ type Todo struct {
+ Id int `json:"id"`
+ UserId int `json:"userId"`
+ Title string `json:"title"`
+ }
+ todo := Todo{1, 1, "TestPatchToDo"}
+ bodyParams, _ := json.Marshal(todo)
+
+ resp, err := netutil.HttpPatch(url, header, nil, bodyParams)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ body, _ := ioutil.ReadAll(resp.Body)
+ fmt.Println(body)
+}
+```
+
+
+
+### ParseHttpResponse
+将http请求响应解码成特定struct值
+
+函数签名:
+
+```go
+func ParseHttpResponse(resp *http.Response, obj interface{}) error
+```
+例子:
+
+```go
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "github.com/duke-git/lancet/netutil"
+)
+
+func main() {
+ url := "https://jsonplaceholder.typicode.com/todos/1"
+ header := map[string]string{
+ "Content-Type": "application/json",
+ }
+
+ resp, err := netutil.HttpGet(url, header)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ type Todo struct {
+ Id int `json:"id"`
+ UserId int `json:"userId"`
+ Title string `json:"title"`
+ Completed bool `json:"completed"`
+ }
+
+ toDoResp := &Todo{}
+ err = netutil.ParseHttpResponse(resp, toDoResp)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Println(toDoResp)
+}
+```
+
From f4881d2f490242c22e4a7e54aea7eecc196d5edf Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Mon, 31 Jan 2022 23:46:59 +0800
Subject: [PATCH 17/34] docs: add doc for package random
---
docs/random.md | 107 +++++++++++++++++++++++++++++++++++++++++++
docs/random_zh-CN.md | 107 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 214 insertions(+)
create mode 100644 docs/random.md
create mode 100644 docs/random_zh-CN.md
diff --git a/docs/random.md b/docs/random.md
new file mode 100644
index 0000000..3f751aa
--- /dev/null
+++ b/docs/random.md
@@ -0,0 +1,107 @@
+# Random
+Package random implements some basic functions to generate random int and string.
+
+
+
+## Source:
+
+[https://github.com/duke-git/lancet/blob/main/random/random.go](https://github.com/duke-git/lancet/blob/main/random/random.go)
+
+
+
+
+## Usage:
+```go
+import (
+ "github.com/duke-git/lancet/random"
+)
+```
+
+
+
+## Index
+- [RandBytes](#RandBytes)
+- [RandInt](#RandInt)
+- [RandString](#RandString)
+
+
+
+## Documentation
+
+
+### RandBytes
+Generate random byte slice.
+
+Signature:
+
+```go
+func RandBytes(length int) []byte
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/random"
+)
+
+func main() {
+ randBytes := random.RandBytes(4)
+ fmt.Println(randBytes)
+}
+```
+
+
+### RandInt
+Generate random int between min and max, may contain min, not max.
+
+Signature:
+
+```go
+func RandInt(min, max int) int
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/random"
+)
+
+func main() {
+ rInt := random.RandInt(1, 10)
+ fmt.Println(rInt)
+}
+```
+
+
+
+### RandInt
+Generate random given length string.
+
+Signature:
+
+```go
+func RandString(length int) string
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/random"
+)
+
+func main() {
+ randStr := random.RandString(6)
+ fmt.Println(randStr)
+}
+```
+
+
diff --git a/docs/random_zh-CN.md b/docs/random_zh-CN.md
new file mode 100644
index 0000000..b69f4aa
--- /dev/null
+++ b/docs/random_zh-CN.md
@@ -0,0 +1,107 @@
+# Random
+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)
+
+
+
+
+## 用法:
+```go
+import (
+ "github.com/duke-git/lancet/random"
+)
+```
+
+
+
+## 目录
+- [RandBytes](#RandBytes)
+- [RandInt](#RandInt)
+- [RandString](#RandString)
+
+
+
+## 文档
+
+
+### RandBytes
+生成随机字节切片
+
+函数签名:
+
+```go
+func RandBytes(length int) []byte
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/random"
+)
+
+func main() {
+ randBytes := random.RandBytes(4)
+ fmt.Println(randBytes)
+}
+```
+
+
+### RandInt
+生成随机int, 范围[min, max)
+
+函数签名:
+
+```go
+func RandInt(min, max int) int
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/random"
+)
+
+func main() {
+ rInt := random.RandInt(1, 10)
+ fmt.Println(rInt)
+}
+```
+
+
+
+### RandInt
+生成随机给定长度的随机字符串
+
+函数签名:
+
+```go
+func RandString(length int) string
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/duke-git/lancet/random"
+)
+
+func main() {
+ randStr := random.RandString(6)
+ fmt.Println(randStr)
+}
+```
+
+
From 961eedda04872859e6d3819fe03737f9fc5654ae Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Tue, 1 Feb 2022 18:57:41 +0800
Subject: [PATCH 18/34] docs: add doc for package retry
---
docs/retry.md | 236 +++++++++++++++++++++++++++++++++++++++++++
docs/retry_zh-CN.md | 238 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 474 insertions(+)
create mode 100644 docs/retry.md
create mode 100644 docs/retry_zh-CN.md
diff --git a/docs/retry.md b/docs/retry.md
new file mode 100644
index 0000000..9e678da
--- /dev/null
+++ b/docs/retry.md
@@ -0,0 +1,236 @@
+# Retry
+Package retry is for executing a function repeatedly until it was successful or canceled by the context.
+
+
+
+## Source:
+
+[https://github.com/duke-git/lancet/blob/main/retry/retry.go](https://github.com/duke-git/lancet/blob/main/retry/retry.go)
+
+
+
+
+## Usage:
+```go
+import (
+ "github.com/duke-git/lancet/retry"
+)
+```
+
+
+
+## Index
+- [Context](#Context)
+- [Retry](#Retry)
+- [RetryFunc](#RetryFunc)
+- [RetryDuration](#RetryDuration)
+- [RetryTimes](#RetryTimes)
+
+
+
+## Documentation
+
+
+### Context
+Set retry context config, can cancel the retry with context.
+
+Signature:
+
+```go
+func Context(ctx context.Context)
+```
+Example:
+
+```go
+import (
+ "context"
+ "errors"
+ "fmt"
+ "lancet-demo/retry"
+ "time"
+)
+
+func main() {
+ ctx, cancel := context.WithCancel(context.TODO())
+ var number int
+ increaseNumber := func() error {
+ number++
+ if number > 3 {
+ cancel()
+ }
+ return errors.New("error occurs")
+ }
+
+ err := retry.Retry(increaseNumber,
+ retry.RetryDuration(time.Microsecond*50),
+ retry.Context(ctx),
+ )
+
+ if err != nil {
+ fmt.Println(err) //retry is cancelled
+ }
+}
+```
+
+
+
+
+### RetryFunc
+Function that retry executes.
+
+Signature:
+
+```go
+type RetryFunc func() error
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "errors"
+ "log"
+ "github.com/duke-git/lancet/retry"
+)
+
+func main() {
+ var number int
+ var increaseNumber retry.RetryFunc
+ increaseNumber = func() error {
+ number++
+ if number == 3 {
+ return nil
+ }
+ return errors.New("error occurs")
+ }
+
+ err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Println(number) //3
+}
+```
+
+
+
+### RetryTimes
+Set times of retry. Default times is 5.
+
+Signature:
+
+```go
+func RetryTimes(n uint)
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "errors"
+ "log"
+ "github.com/duke-git/lancet/retry"
+)
+
+func main() {
+ var number int
+ increaseNumber := func() error {
+ number++
+ if number == 3 {
+ return nil
+ }
+ return errors.New("error occurs")
+ }
+
+ err := retry.Retry(increaseNumber, retry.RetryTimes(2))
+ if err != nil {
+ log.Fatal(err) //2022/02/01 18:42:25 function main.main.func1 run failed after 2 times retry exit status 1
+ }
+}
+```
+
+
+
+### RetryDuration
+Set duration of retries. Default duration is 3 second.
+
+Signature:
+
+```go
+func RetryDuration(d time.Duration)
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "errors"
+ "log"
+ "github.com/duke-git/lancet/retry"
+)
+
+func main() {
+ var number int
+ increaseNumber := func() error {
+ number++
+ if number == 3 {
+ return nil
+ }
+ return errors.New("error occurs")
+ }
+
+ err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Println(number) //3
+}
+```
+
+
+### Retry
+Executes the retryFunc repeatedly until it was successful or canceled by the context.
+
+Signature:
+
+```go
+func Retry(retryFunc RetryFunc, opts ...Option) error
+```
+Example:
+
+```go
+package main
+
+import (
+ "fmt"
+ "errors"
+ "log"
+ "github.com/duke-git/lancet/retry"
+)
+
+func main() {
+ var number int
+ increaseNumber := func() error {
+ number++
+ if number == 3 {
+ return nil
+ }
+ return errors.New("error occurs")
+ }
+
+ err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Println(number) //3
+}
+```
diff --git a/docs/retry_zh-CN.md b/docs/retry_zh-CN.md
new file mode 100644
index 0000000..23f136e
--- /dev/null
+++ b/docs/retry_zh-CN.md
@@ -0,0 +1,238 @@
+# Retry
+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)
+
+
+
+
+## 用法:
+```go
+import (
+ "github.com/duke-git/lancet/retry"
+)
+```
+
+
+
+## 目录
+- [Context](#Context)
+- [Retry](#Retry)
+- [RetryFunc](#RetryFunc)
+- [RetryDuration](#RetryDuration)
+- [RetryTimes](#RetryTimes)
+
+
+
+
+
+## Document文档
+
+
+### Context
+设置重试context参数
+
+函数签名:
+
+```go
+func Context(ctx context.Context)
+```
+例子:
+
+```go
+import (
+ "context"
+ "errors"
+ "fmt"
+ "lancet-demo/retry"
+ "time"
+)
+
+func main() {
+ ctx, cancel := context.WithCancel(context.TODO())
+ var number int
+ increaseNumber := func() error {
+ number++
+ if number > 3 {
+ cancel()
+ }
+ return errors.New("error occurs")
+ }
+
+ err := retry.Retry(increaseNumber,
+ retry.RetryDuration(time.Microsecond*50),
+ retry.Context(ctx),
+ )
+
+ if err != nil {
+ fmt.Println(err) //retry is cancelled
+ }
+}
+```
+
+
+
+
+### RetryFunc
+被重试执行的函数
+
+函数签名:
+
+```go
+type RetryFunc func() error
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "errors"
+ "log"
+ "github.com/duke-git/lancet/retry"
+)
+
+func main() {
+ var number int
+ var increaseNumber retry.RetryFunc
+ increaseNumber = func() error {
+ number++
+ if number == 3 {
+ return nil
+ }
+ return errors.New("error occurs")
+ }
+
+ err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Println(number) //3
+}
+```
+
+
+
+### RetryTimes
+设置重试次数,默认5
+
+函数签名:
+
+```go
+func RetryTimes(n uint)
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "errors"
+ "log"
+ "github.com/duke-git/lancet/retry"
+)
+
+func main() {
+ var number int
+ increaseNumber := func() error {
+ number++
+ if number == 3 {
+ return nil
+ }
+ return errors.New("error occurs")
+ }
+
+ err := retry.Retry(increaseNumber, retry.RetryTimes(2))
+ if err != nil {
+ log.Fatal(err) //2022/02/01 18:42:25 function main.main.func1 run failed after 2 times retry exit status 1
+ }
+}
+```
+
+
+
+### RetryDuration
+设置重试间隔时间,默认3秒
+
+函数签名:
+
+```go
+func RetryDuration(d time.Duration)
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "errors"
+ "log"
+ "github.com/duke-git/lancet/retry"
+)
+
+func main() {
+ var number int
+ increaseNumber := func() error {
+ number++
+ if number == 3 {
+ return nil
+ }
+ return errors.New("error occurs")
+ }
+
+ err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Println(number) //3
+}
+```
+
+
+### Retry
+重试执行函数retryFunc,直到函数运行成功,或被context停止
+
+函数签名:
+
+```go
+func Retry(retryFunc RetryFunc, opts ...Option) error
+```
+例子:
+
+```go
+package main
+
+import (
+ "fmt"
+ "errors"
+ "log"
+ "github.com/duke-git/lancet/retry"
+)
+
+func main() {
+ var number int
+ increaseNumber := func() error {
+ number++
+ if number == 3 {
+ return nil
+ }
+ return errors.New("error occurs")
+ }
+
+ err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Println(number) //3
+}
+```
From 0e0ed316f1ffb94a331cf28e527f253a3f9b4cd6 Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Sat, 5 Feb 2022 09:54:48 +0800
Subject: [PATCH 19/34] docs: fix code issue
---
docs/retry.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/retry.md b/docs/retry.md
index 9e678da..abfd858 100644
--- a/docs/retry.md
+++ b/docs/retry.md
@@ -46,7 +46,7 @@ import (
"context"
"errors"
"fmt"
- "lancet-demo/retry"
+ "github.com/duke-git/lancet/retry"
"time"
)
From 1d71a0ad3ad102a8ef667f268600455afc4bb30c Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Sun, 6 Feb 2022 17:16:16 +0800
Subject: [PATCH 20/34] docs: add doc for slice package
---
docs/slice.md | 968 ++++++++++++++++++++++++++++++++++++++++++++
docs/slice_zh-CN.md | 965 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 1933 insertions(+)
create mode 100644 docs/slice.md
create mode 100644 docs/slice_zh-CN.md
diff --git a/docs/slice.md b/docs/slice.md
new file mode 100644
index 0000000..27cac1a
--- /dev/null
+++ b/docs/slice.md
@@ -0,0 +1,968 @@
+# Slice
+Package slice implements some functions to manipulate slice.
+
+
+
+## Source:
+
+[https://github.com/duke-git/lancet/blob/main/slice/slice.go](https://github.com/duke-git/lancet/blob/main/slice/slice.go)
+
+
+
+
+## Usage:
+```go
+import (
+ "github.com/duke-git/lancet/slice"
+)
+```
+
+
+
+## Index
+- [Contain](#Contain)
+- [ContainSubSlice](#ContainSubSlice)
+- [Chunk](#Chunk)
+- [Compact](#Compact)
+- [Concat](#Concat)
+- [Count](#Count)
+- [Difference](#Difference)
+- [DifferenceBy](#DifferenceBy)
+- [DeleteByIndex](#DeleteByIndex)
+- [Drop](#Drop)
+- [Every](#Every)
+- [Filter](#Filter)
+- [Find](#Find)
+- [FindLast](#FindLast)
+- [FlattenDeep](#FlattenDeep)
+- [ForEach](#ForEach)
+
+- [GroupBy](#GroupBy)
+- [IntSlice](#IntSlice)
+- [InterfaceSlice](#InterfaceSlice)
+- [Intersection](#Intersection)
+- [InsertByIndex](#InsertByIndex)
+- [Map](#Map)
+- [ReverseSlice](#ReverseSlice)
+- [Reduce](#Reduce)
+- [Shuffle](#Shuffle)
+- [SortByField](#SortByField)
+- [Some](#Some)
+- [StringSlice](#StringSlice)
+- [Unique](#Unique)
+- [Union](#Union)
+- [UpdateByIndex](#UpdateByIndex)
+- [Without](#Without)
+
+
+
+## Documentation
+
+## Note:
+1. param which type is interface{} in below functions should be slice.
+
+### Contain
+Check if the value is in the slice or not. iterableType param can be string, map or slice.
+
+Signature:
+
+```go
+func Contain(iterableType interface{}, value interface{}) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ res := slice.Contain([]string{"a", "b", "c"}, "a")
+ fmt.Println(res) //true
+}
+```
+
+
+### ContainSubSlice
+Check if the slice contain subslice or not.
+
+Signature:
+
+```go
+func ContainSubSlice(slice interface{}, subslice interface{}) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ res := slice.ContainSubSlice([]string{"a", "b", "c"}, []string{"a", "b"})
+ fmt.Println(res) //true
+}
+```
+
+
+
+
+### Chunk
+Creates an slice of elements split into groups the length of `size`.
+
+Signature:
+
+```go
+func Chunk(slice []interface{}, size int) [][]interface{}
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ arr := []string{"a", "b", "c", "d", "e"}
+ res := slice.Chunk(InterfaceSlice(arr), 3)
+ fmt.Println(res) //[][]interface{}{{"a", "b", "c"}, {"d", "e"}}
+}
+```
+
+
+
+### Compact
+Creates an slice with all falsey values removed. The values false, nil, 0, and "" are falsey.
+
+Signature:
+
+```go
+func Compact(slice interface{}) interface{}
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ res := slice.Compact([]int{0, 1, 2, 3})
+ fmt.Println(res) //[]int{1, 2, 3}
+}
+```
+
+
+### Concat
+Creates a new slice concatenating slice with any additional slices and/or values.
+
+Signature:
+
+```go
+func Concat(slice interface{}, values ...interface{}) interface{}
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ res1 := slice.Concat([]int{1, 2, 3}, 4, 5)
+ fmt.Println(res1) //[]int{1, 2, 3, 4, 5}
+
+ res2 := slice.Concat([]int{1, 2, 3}, []int{4, 5})
+ fmt.Println(res2) //[]int{1, 2, 3, 4, 5}
+}
+```
+
+
+
+### Count
+Count iterates over elements of slice, returns a count of all matched elements. The function signature should be func(index int, value interface{}) bool.
+
+Signature:
+
+```go
+func Count(slice, function interface{}) int
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 4, 5, 6}
+ evenFunc := func(i, num int) bool {
+ return (num % 2) == 0
+ }
+
+ res := slice.Count(nums, evenFunc)
+ fmt.Println(res) //3
+}
+```
+
+
+
+
+### Difference
+Creates an slice of whose element not included in the other given slice.
+
+Signature:
+
+```go
+func Difference(slice1, slice2 interface{}) interface{}
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ s1 := []int{1, 2, 3, 4, 5}
+ s2 := []int{4, 5, 6}
+
+ res := slice.Difference(s1, s2)
+ fmt.Println(res) //[]int{1, 2, 3}
+}
+```
+
+
+
+
+### DifferenceBy
+DifferenceBy accepts iteratee func which is invoked for each element of slice and values to generate the criterion by which they're compared.
+
+Signature:
+
+```go
+func DifferenceBy(slice interface{}, comparedSlice interface{}, iterateeFn interface{}) interface{}
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ s1 := []int{1, 2, 3, 4, 5}
+ s2 := []int{4, 5, 6}
+ addOne := func(i int, v int) int {
+ return v + 1
+ }
+
+ res := slice.DifferenceBy(s1, s2, addOne)
+ fmt.Println(res) //[]int{1, 2}
+}
+```
+
+
+
+
+### DeleteByIndex
+Delete the element of slice from start index to end index - 1.
+
+Signature:
+
+```go
+func DeleteByIndex(slice interface{}, start int, end ...int) (interface{}, error)
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ res1 := slice.DeleteByIndex([]string{"a", "b", "c", "d", "e"}, 3)
+ fmt.Println(res1) //[]string{"a", "b", "c", "e"}
+
+ res2 := slice.DeleteByIndex([]string{"a", "b", "c", "d", "e"}, 0, 2)
+ fmt.Println(res2) //[]string{"c", "d", "e"}
+
+}
+```
+
+
+
+
+### Drop
+Creates a slice with `n` elements dropped from the beginning when n > 0, or `n` elements dropped from the ending when n < 0.
+
+Signature:
+
+```go
+func Drop(slice interface{}, n int) interface{}
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ res1 := slice.Drop([]int{}, 0)
+ fmt.Println(res1) //[]int{}
+
+ res2 := slice.Drop([]int{1, 2, 3, 4, 5}, 1)
+ fmt.Println(res2) //[]int{2, 3, 4, 5}
+
+ res3 := slice.Drop([]int{1, 2, 3, 4, 5}, -1)
+ fmt.Println(res3) //[]int{1, 2, 3, 4}
+}
+```
+
+
+
+
+### 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.
+
+Signature:
+
+```go
+func Every(slice, function interface{}) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 5}
+ isEven := func(i, num int) bool {
+ return num%2 == 0
+ }
+
+ res := slice.Every(nums, isEven)
+ fmt.Println(res) //false
+}
+```
+
+
+
+
+### Filter
+Return all elements which match the function. Function signature should be func(index int, value interface{}) bool.
+
+Signature:
+
+```go
+func Filter(slice, function interface{}) interface{}
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 5}
+ isEven := func(i, num int) bool {
+ return num%2 == 0
+ }
+
+ res := slice.Filter(nums, isEven)
+ fmt.Println(res) //[]int{2, 4}
+}
+```
+
+
+
+### Find
+Iterates over elements of slice, returning the first one that passes a truth test on function.function signature should be func(index int, value interface{}) bool.
+
+Signature:
+
+```go
+func Find(slice, function interface{}) (interface{}, bool)
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 5}
+ isEven := func(i, num int) bool {
+ return num%2 == 0
+ }
+
+ res, ok := slice.Find(nums, even)
+ fmt.Println(res) //2
+ fmt.Println(ok) //true
+}
+```
+
+
+
+
+### FindLast
+iterates over elements of slice from end to begin, returning the last one that passes a truth test on function. The function signature should be func(index int, value interface{}) bool.
+
+Signature:
+
+```go
+func FindLast(slice, function interface{}) (interface{}, bool)
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 5}
+ isEven := func(i, num int) bool {
+ return num%2 == 0
+ }
+
+ res, ok := slice.FindLast(nums, even)
+ fmt.Println(res) //4
+ fmt.Println(ok) //true
+}
+```
+
+
+
+### FlattenDeep
+flattens slice recursive.
+
+Signature:
+
+```go
+func FlattenDeep(slice interface{}) interface{}
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ arr := [][][]string{{{"a", "b"}}, {{"c", "d"}}}
+ res := slice.FlattenDeep(arr)
+ fmt.Println(res) //[]string{"a", "b", "c", "d"}
+}
+```
+
+
+
+
+
+### ForEach
+Iterates over elements of slice and invokes function for each element, function signature should be func(index int, value interface{}).
+
+Signature:
+
+```go
+func ForEach(slice, function interface{})
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ numbers := []int{1, 2, 3, 4, 5}
+ var numbersAddTwo []int
+ slice.ForEach(numbers, func(index int, value int) {
+ numbersAddTwo = append(numbersAddTwo, value+2)
+ })
+ fmt.Println(numbersAddTwo) //[]int{3, 4, 5, 6, 7}
+}
+```
+
+
+
+
+### GroupBy
+Iterates 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.
+
+Signature:
+
+```go
+func GroupBy(slice, function interface{}) (interface{}, interface{})
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 4, 5, 6}
+ evenFunc := func(i, num int) bool {
+ return (num % 2) == 0
+ }
+ even, odd := slice.GroupBy(nums, evenFunc)
+
+ fmt.Println(even) //[]int{2, 4, 6}
+ fmt.Println(odd) //]int{1, 3, 5}
+}
+```
+
+
+
+
+### IntSlice
+Convert interface slice to int slice.
+
+Signature:
+
+```go
+func IntSlice(slice interface{}) []int
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ var nums = []interface{}{1, 2, 3}
+ res := slice.IntSlice(nums)
+ fmt.Println(res) //[]int{1, 2, 3}
+}
+```
+
+
+
+
+### InterfaceSlice
+Convert value to interface slice.
+
+Signature:
+
+```go
+func InterfaceSlice(slice interface{}) []interface{}
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ var nums = []int{}{1, 2, 3}
+ res := slice.InterfaceSlice(nums)
+ fmt.Println(res) //[]interface{}{1, 2, 3}
+}
+```
+
+
+
+
+### Intersection
+Creates a slice of unique values that included by all slices.
+
+Signature:
+
+```go
+func Intersection(slices ...interface{}) interface{}
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ s1 := []int{1, 2, 2, 3}
+ s2 := []int{1, 2, 3, 4}
+ res := slice.Intersection(s1, s2),
+
+ fmt.Println(res) //[]int{1, 2, 3}
+}
+```
+
+
+
+
+### InsertByIndex
+insert the element into slice at index.
+
+Signature:
+
+```go
+func InsertByIndex(slice interface{}, index int, value interface{}) (interface{}, error)
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ s := []string{"a", "b", "c"}
+
+ res1, _ := slice.InsertByIndex(s, 0, "1")
+ fmt.Println(res1) //[]string{"1", "a", "b", "c"}
+
+ res2, _ := slice.InsertByIndex(s, 3, []string{"1", "2", "3"})
+ fmt.Println(res2) //[]string{"a", "b", "c", "1", "2", "3"}
+}
+```
+
+
+
+
+### Map
+Creates an slice of values by running each element in slice thru function, function signature should be func(index int, value interface{}) interface{}.
+
+Signature:
+
+```go
+func Map(slice, function interface{}) interface{}
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 4}
+ multiplyTwo := func(i, num int) int {
+ return num * 2
+ }
+ res := slice.Map(nums, multiplyTwo)
+ fmt.Println(res) //[]int{2, 4, 6, 8}
+}
+```
+
+
+
+
+### ReverseSlice
+Reverse the elements order in slice.
+
+Signature:
+
+```go
+func ReverseSlice(slice interface{})
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 4}
+ slice.ReverseSlice(nums)
+ fmt.Println(res) //[]int{4, 3, 2, 1}
+}
+```
+
+
+
+### Reduce
+Reduce slice, function signature should be func(index int, value1, value2 interface{}) interface{}.
+
+Signature:
+
+```go
+func Reduce(slice, function, zero interface{}) interface{}
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 4}
+ reduceFunc := func(i, v1, v2 int) int {
+ return v1 + v2
+ }
+ res := slice.Reduce(nums, reduceFunc, 0)
+ fmt.Println(res) //10
+}
+```
+
+
+
+
+### Shuffle
+Creates an slice of shuffled values.
+
+Signature:
+
+```go
+func Shuffle(slice interface{}) interface{}
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 4, 5}
+ res := slice.Shuffle(nums)
+ fmt.Println(res) //3,1,5,4,2
+}
+```
+
+
+
+### SortByField
+Sort struct slice by field. Slice element should be struct, field type should be int, uint, string, or bool. Default sort type is ascending (asc), if descending order, set sortType to desc
+
+Signature:
+
+```go
+func SortByField(slice interface{}, field string, sortType ...string) error
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ type student struct {
+ name string
+ age int
+ }
+ students := []student{
+ {"a", 10},
+ {"b", 15},
+ {"c", 5},
+ {"d", 6},
+ }
+ err := slice.SortByField(students, "age", "desc")
+ if err != nil {
+ fmt.Println(err)
+ }
+ fmt.Println(students)
+ // []students{
+ // {"b", 15},
+ // {"a", 10},
+ // {"d", 6},
+ // {"c", 5},
+ // }
+}
+```
+
+
+
+### Some
+Return true if any of the values in the list pass the predicate function, function signature should be func(index int, value interface{}) bool.
+
+Signature:
+
+```go
+func Some(slice, function interface{}) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 5}
+ isEven := func(i, num int) bool {
+ return num%2 == 0
+ }
+
+ res := slice.Some(nums, isEven)
+ fmt.Println(res) //true
+}
+```
+
+
+
+### StringSlice
+Convert interface slice to string slice.
+
+Signature:
+
+```go
+func StringSlice(slice interface{}) []string
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ var s = []interface{}{"a", "b", "c"}
+ res := slice.StringSlice(s)
+ fmt.Println(res) //[]string{"a", "b", "c"}
+}
+```
+
+
+
+
+### Unique
+Remove duplicate elements in slice.
+
+Signature:
+
+```go
+func Unique(slice interface{}) interface{}
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ res := slice.Unique([]int{1, 2, 2, 3})
+ fmt.Println(res) //[]int{1, 2, 3}
+}
+```
+
+
+
+### Unique
+Creates a slice of unique values, in order, from all given slices. using == for equality comparisons.
+
+Signature:
+
+```go
+func Union(slices ...interface{}) interface{}
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ s1 := []int{1, 3, 4, 6}
+ s2 := []int{1, 2, 5, 6}
+ res := slice.Union(s1, s2)
+
+ fmt.Println(res) //[]int{1, 3, 4, 6, 2, 5}
+}
+```
+
+
+
+### UpdateByIndex
+Update the slice element at index. if param index < 0 or index >= len(slice), will return error.
+
+Signature:
+
+```go
+func UpdateByIndex(slice interface{}, index int, value interface{}) (interface{}, error)
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ s := []string{"a", "b", "c"}
+
+ res1, _ := slice.UpdateByIndex(s, 0, "1")
+ fmt.Println(res1) //[]string{"1", "b", "c"}
+}
+```
+
+
+
+
+### Without
+Creates a slice excluding all given values.
+
+Signature:
+
+```go
+func Without(slice interface{}, values ...interface{}) interface{}
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ res := slice.Without([]int{1, 2, 3, 4, 5}, 1, 2)
+ fmt.Println(res) //[]int{3, 4, 5}
+}
+```
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/slice_zh-CN.md b/docs/slice_zh-CN.md
new file mode 100644
index 0000000..18bab8d
--- /dev/null
+++ b/docs/slice_zh-CN.md
@@ -0,0 +1,965 @@
+# Slice
+slice包包含操作切片的方法集合。
+
+
+
+## 源码:
+
+[https://github.com/duke-git/lancet/blob/main/slice/slice.go](https://github.com/duke-git/lancet/blob/main/slice/slice.go)
+
+
+
+
+## 用法:
+```go
+import (
+ "github.com/duke-git/lancet/slice"
+)
+```
+
+
+
+## 目录
+- [Contain](#Contain)
+- [ContainSubSlice](#ContainSubSlice)
+- [Chunk](#Chunk)
+- [Compact](#Compact)
+- [Concat](#Concat)
+- [Count](#Count)
+- [Difference](#Difference)
+- [DifferenceBy](#DifferenceBy)
+- [DeleteByIndex](#DeleteByIndex)
+- [Drop](#Drop)
+- [Every](#Every)
+- [Filter](#Filter)
+- [Find](#Find)
+- [FindLast](#FindLast)
+- [FlattenDeep](#FlattenDeep)
+- [ForEach](#ForEach)
+
+- [GroupBy](#GroupBy)
+- [IntSlice](#IntSlice)
+- [InterfaceSlice](#InterfaceSlice)
+- [Intersection](#Intersection)
+- [InsertByIndex](#InsertByIndex)
+- [Map](#Map)
+- [ReverseSlice](#ReverseSlice)
+- [Reduce](#Reduce)
+- [Shuffle](#Shuffle)
+- [SortByField](#SortByField)
+- [Some](#Some)
+- [StringSlice](#StringSlice)
+- [Unique](#Unique)
+- [Union](#Union)
+- [UpdateByIndex](#UpdateByIndex)
+- [Without](#Without)
+
+
+
+## 文档
+
+### Contain
+判断slice是否包含value
+
+函数签名:
+
+```go
+func Contain(iterableType interface{}, value interface{}) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ res := slice.Contain([]string{"a", "b", "c"}, "a")
+ fmt.Println(res) //true
+}
+```
+
+
+### ContainSubSlice
+判断slice是否包含subslice
+
+函数签名:
+
+```go
+func ContainSubSlice(slice interface{}, subslice interface{}) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ res := slice.ContainSubSlice([]string{"a", "b", "c"}, []string{"a", "b"})
+ fmt.Println(res) //true
+}
+```
+
+
+
+
+### Chunk
+按照size参数均分slice
+
+函数签名:
+
+```go
+func Chunk(slice []interface{}, size int) [][]interface{}
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ arr := []string{"a", "b", "c", "d", "e"}
+ res := slice.Chunk(InterfaceSlice(arr), 3)
+ fmt.Println(res) //[][]interface{}{{"a", "b", "c"}, {"d", "e"}}
+}
+```
+
+
+
+### Compact
+去除slice中的假值(false values are false, nil, 0, "")
+
+函数签名:
+
+```go
+func Compact(slice interface{}) interface{}
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ res := slice.Compact([]int{0, 1, 2, 3})
+ fmt.Println(res) //[]int{1, 2, 3}
+}
+```
+
+
+### Concat
+连接values到slice中,values类型可以是切片或多个值
+
+函数签名:
+
+```go
+func Concat(slice interface{}, values ...interface{}) interface{}
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ res1 := slice.Concat([]int{1, 2, 3}, 4, 5)
+ fmt.Println(res1) //[]int{1, 2, 3, 4, 5}
+
+ res2 := slice.Concat([]int{1, 2, 3}, []int{4, 5})
+ fmt.Println(res2) //[]int{1, 2, 3, 4, 5}
+}
+```
+
+
+
+### Count
+遍历切片,对每个元素执行函数function. 返回符合函数返回值为true的元素的个数,函数签名必须是func(index int, value interface{}) bool
+
+函数签名:
+
+```go
+func Count(slice, function interface{}) int
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 4, 5, 6}
+ evenFunc := func(i, num int) bool {
+ return (num % 2) == 0
+ }
+
+ res := slice.Count(nums, evenFunc)
+ fmt.Println(res) //3
+}
+```
+
+
+
+
+### Difference
+创建一个切片,其元素不包含在另一个给定切片中
+
+函数签名:
+
+```go
+func Difference(slice1, slice2 interface{}) interface{}
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ s1 := []int{1, 2, 3, 4, 5}
+ s2 := []int{4, 5, 6}
+
+ res := slice.Difference(s1, s2)
+ fmt.Println(res) //[]int{1, 2, 3}
+}
+```
+
+
+
+
+### DifferenceBy
+在slice和comparedSlice中的每个元素调用iteratee函数,并比较它们的返回值,如果不想等返回在slice中对应的值
+
+函数签名:
+
+```go
+func DifferenceBy(slice interface{}, comparedSlice interface{}, iterateeFn interface{}) interface{}
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ s1 := []int{1, 2, 3, 4, 5}
+ s2 := []int{4, 5, 6}
+ addOne := func(i int, v int) int {
+ return v + 1
+ }
+
+ res := slice.DifferenceBy(s1, s2, addOne)
+ fmt.Println(res) //[]int{1, 2}
+}
+```
+
+
+
+
+### DeleteByIndex
+删除切片中从开始索引到结束索引-1的元素
+
+函数签名:
+
+```go
+func DeleteByIndex(slice interface{}, start int, end ...int) (interface{}, error)
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ res1 := slice.DeleteByIndex([]string{"a", "b", "c", "d", "e"}, 3)
+ fmt.Println(res1) //[]string{"a", "b", "c", "e"}
+
+ res2 := slice.DeleteByIndex([]string{"a", "b", "c", "d", "e"}, 0, 2)
+ fmt.Println(res2) //[]string{"c", "d", "e"}
+
+}
+```
+
+
+
+
+### Drop
+创建一个切片,当 n > 0 时从开头删除 n 个元素,或者当 n < 0 时从结尾删除 n 个元素
+
+函数签名:
+
+```go
+func Drop(slice interface{}, n int) interface{}
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ res1 := slice.Drop([]int{}, 0)
+ fmt.Println(res1) //[]int{}
+
+ res2 := slice.Drop([]int{1, 2, 3, 4, 5}, 1)
+ fmt.Println(res2) //[]int{2, 3, 4, 5}
+
+ res3 := slice.Drop([]int{1, 2, 3, 4, 5}, -1)
+ fmt.Println(res3) //[]int{1, 2, 3, 4}
+}
+```
+
+
+
+
+### Every
+如果切片中的所有值都通过谓词函数,则返回true。 函数签名应该是func(index int, value interface{}) bool
+
+函数签名:
+
+```go
+func Every(slice, function interface{}) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 5}
+ isEven := func(i, num int) bool {
+ return num%2 == 0
+ }
+
+ res := slice.Every(nums, isEven)
+ fmt.Println(res) //false
+}
+```
+
+
+
+
+### Filter
+返回与函数匹配的所有元素。 函数签名应该是 func(index int, value interface{}) bool
+
+函数签名:
+
+```go
+func Filter(slice, function interface{}) interface{}
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 5}
+ isEven := func(i, num int) bool {
+ return num%2 == 0
+ }
+
+ res := slice.Filter(nums, isEven)
+ fmt.Println(res) //[]int{2, 4}
+}
+```
+
+
+
+### Find
+遍历slice的元素,返回第一个通过function真值测试的元素。函数签名应该是 func(index int, value interface{}) bool
+
+函数签名:
+
+```go
+func Find(slice, function interface{}) (interface{}, bool)
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 5}
+ isEven := func(i, num int) bool {
+ return num%2 == 0
+ }
+
+ res, ok := slice.Find(nums, even)
+ fmt.Println(res) //2
+ fmt.Println(ok) //true
+}
+```
+
+
+
+
+### FindLast
+从头到尾遍历 slice 的元素,返回最后一个通过函数真值测试的元素。 函数签名应该是 func(index int, value interface{}) bool。
+
+函数签名:
+
+```go
+func FindLast(slice, function interface{}) (interface{}, bool)
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 5}
+ isEven := func(i, num int) bool {
+ return num%2 == 0
+ }
+
+ res, ok := slice.FindLast(nums, even)
+ fmt.Println(res) //4
+ fmt.Println(ok) //true
+}
+```
+
+
+
+### FlattenDeep
+flattens slice recursive.
+
+函数签名:
+
+```go
+func FlattenDeep(slice interface{}) interface{}
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ arr := [][][]string{{{"a", "b"}}, {{"c", "d"}}}
+ res := slice.FlattenDeep(arr)
+ fmt.Println(res) //[]string{"a", "b", "c", "d"}
+}
+```
+
+
+
+
+
+### ForEach
+遍历slice的元素并为每个元素调用函数,函数签名应该是func(index int, value interface{})
+
+函数签名:
+
+```go
+func ForEach(slice, function interface{})
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ numbers := []int{1, 2, 3, 4, 5}
+ var numbersAddTwo []int
+ slice.ForEach(numbers, func(index int, value int) {
+ numbersAddTwo = append(numbersAddTwo, value+2)
+ })
+ fmt.Println(numbersAddTwo) //[]int{3, 4, 5, 6, 7}
+}
+```
+
+
+
+
+### GroupBy
+迭代切片的元素,每个元素将按条件分组,返回两个切片。 函数签名应该是func(index int, value interface{}) bool
+
+函数签名:
+
+```go
+func GroupBy(slice, function interface{}) (interface{}, interface{})
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 4, 5, 6}
+ evenFunc := func(i, num int) bool {
+ return (num % 2) == 0
+ }
+ even, odd := slice.GroupBy(nums, evenFunc)
+
+ fmt.Println(even) //[]int{2, 4, 6}
+ fmt.Println(odd) //]int{1, 3, 5}
+}
+```
+
+
+
+
+### IntSlice
+将接口切片转换为int切片
+
+函数签名:
+
+```go
+func IntSlice(slice interface{}) []int
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ var nums = []interface{}{1, 2, 3}
+ res := slice.IntSlice(nums)
+ fmt.Println(res) //[]int{1, 2, 3}
+}
+```
+
+
+
+
+### InterfaceSlice
+将值转换为接口切片
+
+函数签名:
+
+```go
+func InterfaceSlice(slice interface{}) []interface{}
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ var nums = []int{}{1, 2, 3}
+ res := slice.InterfaceSlice(nums)
+ fmt.Println(res) //[]interface{}{1, 2, 3}
+}
+```
+
+
+
+
+### Intersection
+多个切片的交集
+
+函数签名:
+
+```go
+func Intersection(slices ...interface{}) interface{}
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ s1 := []int{1, 2, 2, 3}
+ s2 := []int{1, 2, 3, 4}
+ res := slice.Intersection(s1, s2),
+
+ fmt.Println(res) //[]int{1, 2, 3}
+}
+```
+
+
+
+
+### InsertByIndex
+将元素插入到索引处的切片中
+
+函数签名:
+
+```go
+func InsertByIndex(slice interface{}, index int, value interface{}) (interface{}, error)
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ s := []string{"a", "b", "c"}
+
+ res1, _ := slice.InsertByIndex(s, 0, "1")
+ fmt.Println(res1) //[]string{"1", "a", "b", "c"}
+
+ res2, _ := slice.InsertByIndex(s, 3, []string{"1", "2", "3"})
+ fmt.Println(res2) //[]string{"a", "b", "c", "1", "2", "3"}
+}
+```
+
+
+
+
+### Map
+通过运行函数slice中的每个元素来创建一个值切片,函数签名应该是func(index int, value interface{}) interface{}。
+
+函数签名:
+
+```go
+func Map(slice, function interface{}) interface{}
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 4}
+ multiplyTwo := func(i, num int) int {
+ return num * 2
+ }
+ res := slice.Map(nums, multiplyTwo)
+ fmt.Println(res) //[]int{2, 4, 6, 8}
+}
+```
+
+
+
+
+### ReverseSlice
+反转切片中的元素顺序
+
+函数签名:
+
+```go
+func ReverseSlice(slice interface{})
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 4}
+ slice.ReverseSlice(nums)
+ fmt.Println(res) //[]int{4, 3, 2, 1}
+}
+```
+
+
+
+### Reduce
+将slice中的元素运行函数,返回运行结果。函数签名应该是func(index int, value1, value2 interface{}) interface{}。
+
+函数签名:
+
+```go
+func Reduce(slice, function, zero interface{}) interface{}
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 4}
+ reduceFunc := func(i, v1, v2 int) int {
+ return v1 + v2
+ }
+ res := slice.Reduce(nums, reduceFunc, 0)
+ fmt.Println(res) //10
+}
+```
+
+
+
+
+### Shuffle
+随机打乱切片中的元素顺序
+
+函数签名:
+
+```go
+func Shuffle(slice interface{}) interface{}
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 4, 5}
+ res := slice.Shuffle(nums)
+ fmt.Println(res) //3,1,5,4,2
+}
+```
+
+
+
+### SortByField
+按字段对结构切片进行排序。slice元素应为struct,字段类型应为int、uint、string或bool。 默认排序类型是升序(asc),如果是降序,设置 sortType 为 desc
+
+函数签名:
+
+```go
+func SortByField(slice interface{}, field string, sortType ...string) error
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ type student struct {
+ name string
+ age int
+ }
+ students := []student{
+ {"a", 10},
+ {"b", 15},
+ {"c", 5},
+ {"d", 6},
+ }
+ err := slice.SortByField(students, "age", "desc")
+ if err != nil {
+ fmt.Println(err)
+ }
+ fmt.Println(students)
+ // []students{
+ // {"b", 15},
+ // {"a", 10},
+ // {"d", 6},
+ // {"c", 5},
+ // }
+}
+```
+
+
+
+### Some
+如果列表中的任何值通过谓词函数,则返回true,函数签名应该是func(index int, value interface{}) bool .
+
+函数签名:
+
+```go
+func Some(slice, function interface{}) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ nums := []int{1, 2, 3, 5}
+ isEven := func(i, num int) bool {
+ return num%2 == 0
+ }
+
+ res := slice.Some(nums, isEven)
+ fmt.Println(res) //true
+}
+```
+
+
+
+### StringSlice
+将接口切片转换为字符串切片
+
+函数签名:
+
+```go
+func StringSlice(slice interface{}) []string
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ var s = []interface{}{"a", "b", "c"}
+ res := slice.StringSlice(s)
+ fmt.Println(res) //[]string{"a", "b", "c"}
+}
+```
+
+
+
+
+### Unique
+删除切片中的重复元素
+
+函数签名:
+
+```go
+func Unique(slice interface{}) interface{}
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ res := slice.Unique([]int{1, 2, 2, 3})
+ fmt.Println(res) //[]int{1, 2, 3}
+}
+```
+
+
+
+### Unique
+从所有给定的切片按顺序创建一个唯一值切片。 使用 == 进行相等比较。
+
+函数签名:
+
+```go
+func Union(slices ...interface{}) interface{}
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ s1 := []int{1, 3, 4, 6}
+ s2 := []int{1, 2, 5, 6}
+ res := slice.Union(s1, s2)
+
+ fmt.Println(res) //[]int{1, 3, 4, 6, 2, 5}
+}
+```
+
+
+
+### UpdateByIndex
+更新索引处的切片元素。 如果 param index < 0 或 index >= len(slice),将返回错误
+
+函数签名:
+
+```go
+func UpdateByIndex(slice interface{}, index int, value interface{}) (interface{}, error)
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ s := []string{"a", "b", "c"}
+
+ res1, _ := slice.UpdateByIndex(s, 0, "1")
+ fmt.Println(res1) //[]string{"1", "b", "c"}
+}
+```
+
+
+
+
+### Without
+创建一个不包括所有给定值的切片
+
+函数签名:
+
+```go
+func Without(slice interface{}, values ...interface{}) interface{}
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/slice"
+)
+
+func main() {
+ res := slice.Without([]int{1, 2, 3, 4, 5}, 1, 2)
+ fmt.Println(res) //[]int{3, 4, 5}
+}
+```
+
+
+
+
+
+
+
+
+
+
+
From 384be2e2e94c5a97b28372c6f76bcc01d3078983 Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Mon, 7 Feb 2022 10:54:44 +0800
Subject: [PATCH 21/34] docs: add doc for strutil package
---
docs/strutil.md | 574 +++++++++++++++++++++++++++++++++++++++++
docs/strutil_zh-CN.md | 575 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 1149 insertions(+)
create mode 100644 docs/strutil.md
create mode 100644 docs/strutil_zh-CN.md
diff --git a/docs/strutil.md b/docs/strutil.md
new file mode 100644
index 0000000..7b83263
--- /dev/null
+++ b/docs/strutil.md
@@ -0,0 +1,574 @@
+# Strutil
+Package strutil contains some functions to manipulate string.
+
+
+
+## Source:
+
+[https://github.com/duke-git/lancet/blob/main/strutil/string.go](https://github.com/duke-git/lancet/blob/main/strutil/string.go)
+
+
+
+
+## Usage:
+```go
+import (
+ "github.com/duke-git/lancet/strutil"
+)
+```
+
+
+
+## Index
+- [After](#After)
+- [AfterLast](#AfterLast)
+- [Before](#Before)
+- [BeforeLast](#BeforeLast)
+- [CamelCase](#CamelCase)
+- [Capitalize](#Capitalize)
+- [IsString](#IsString)
+- [KebabCase](#KebabCase)
+- [LowerFirst](#LowerFirst)
+- [UpperFirst](#UpperFirst)
+- [PadEnd](#PadEnd)
+- [PadStart](#PadStart)
+- [ReverseStr](#ReverseStr)
+- [SnakeCase](#SnakeCase)
+- [Wrap](#Wrap)
+
+- [Unwrap](#Unwrap)
+
+
+
+
+## Documentation
+
+
+### After
+Creates substring in source string after position when char first appear.
+
+Signature:
+
+```go
+func After(s, char string) string
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.After("lancet", "")
+ fmt.Println(s1) //lancet
+
+ s2 := strutil.After("github.com/test/lancet", "/")
+ fmt.Println(s2) //test/lancet
+
+ s3 := strutil.After("github.com/test/lancet", "test")
+ fmt.Println(s3) // /lancet
+}
+```
+
+
+
+### AfterLast
+Creates substring in source string after position when char last appear.
+
+Signature:
+
+```go
+func AfterLast(s, char string) string
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.AfterLast("lancet", "")
+ fmt.Println(s1) //lancet
+
+ s2 := strutil.AfterLast("github.com/test/lancet", "/")
+ fmt.Println(s2) //lancet
+
+ s3 := strutil.AfterLast("github.com/test/test/lancet", "test")
+ fmt.Println(s3) // /test/lancet
+}
+```
+
+
+
+
+### Before
+Creates substring in source string before position when char first appear.
+
+Signature:
+
+```go
+func Before(s, char string) string
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.Before("lancet", "")
+ fmt.Println(s1) //lancet
+
+ s2 := strutil.Before("github.com/test/lancet", "/")
+ fmt.Println(s2) //github.com
+
+ s3 := strutil.Before("github.com/test/lancet", "test")
+ fmt.Println(s3) // github.com/
+}
+```
+
+
+
+
+### BeforeLast
+Creates substring in source string before position when char first appear.
+
+Signature:
+
+```go
+func BeforeLast(s, char string) string
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.BeforeLast("lancet", "")
+ fmt.Println(s1) //lancet
+
+ s2 := strutil.BeforeLast("github.com/test/lancet", "/")
+ fmt.Println(s2) //github.com/test
+
+ s3 := strutil.BeforeLast("github.com/test/test/lancet", "test")
+ fmt.Println(s3) //github.com/test/
+}
+```
+
+
+
+
+### CamelCase
+Covert string to camelCase string.
+
+Signature:
+
+```go
+func CamelCase(s string) string
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.CamelCase("foo_bar")
+ fmt.Println(s1) //fooBar
+
+ s2 := strutil.CamelCase("Foo-Bar")
+ fmt.Println(s2) //fooBar
+
+ s3 := strutil.CamelCase("Foo&bar")
+ fmt.Println(s3) //fooBar
+
+ s4 := strutil.CamelCase("foo bar")
+ fmt.Println(s4) //fooBar
+}
+```
+
+
+
+
+### Capitalize
+Convert the first character of a string to upper case.
+
+Signature:
+
+```go
+func Capitalize(s string) string
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.Capitalize("foo")
+ fmt.Println(s1) //foo
+
+ s2 := strutil.Capitalize("Foo")
+ fmt.Println(s2) //foo
+
+ s3 := strutil.Capitalize("FOo"
+ fmt.Println(s3) //fOo
+}
+```
+
+
+
+### IsString
+Check if the value's data type is string.
+
+Signature:
+
+```go
+func IsString(v interface{}) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ fmt.Println(strutil.IsString("lancet")) //true
+ fmt.Println(strutil.IsString("")) //true
+
+ fmt.Println(strutil.IsString(1)) //false
+ fmt.Println(strutil.IsString("")) //false
+ fmt.Println(strutil.IsString([]string{})) //false
+}
+```
+
+
+
+### KebabCase
+Covert string to kebab-case.
+
+Signature:
+
+```go
+func KebabCase(s string) string
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.KebabCase("Foo Bar-")
+ fmt.Println(s1) //foo-bar
+
+ s2 := strutil.KebabCase("foo_Bar")
+ fmt.Println(s2) //foo-bar
+
+ s3 := strutil.KebabCase("fooBar")
+ fmt.Println(s3) //foo-bar
+
+ s4 := strutil.KebabCase("__FOO_BAR__")
+ fmt.Println(s4) //f-o-o-b-a-r
+}
+```
+
+
+
+
+### LowerFirst
+Convert the first character of string to lower case.
+
+Signature:
+
+```go
+func LowerFirst(s string) string
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.LowerFirst("foo")
+ fmt.Println(s1) //foo
+
+ s2 := strutil.LowerFirst("BAR")
+ fmt.Println(s2) //bAR
+
+ s3 := strutil.LowerFirst("FOo")
+ fmt.Println(s3) //fOo
+
+ s4 := strutil.LowerFirst("fOo大")
+ fmt.Println(s4) //fOo大
+}
+```
+
+
+
+
+### UpperFirst
+Convert the first character of string to upper case.
+
+Signature:
+
+```go
+func UpperFirst(s string) string
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.UpperFirst("foo")
+ fmt.Println(s1) //Foo
+
+ s2 := strutil.UpperFirst("bAR")
+ fmt.Println(s2) //BAR
+
+ s3 := strutil.UpperFirst("FOo")
+ fmt.Println(s3) //FOo
+
+ s4 := strutil.UpperFirst("fOo大")
+ fmt.Println(s4) //FOo大
+}
+```
+
+
+
+
+### PadEnd
+Pads string on the right side if it's shorter than size.
+
+Signature:
+
+```go
+func PadEnd(source string, size int, padStr string) string
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.PadEnd("a", 1, "b")
+ fmt.Println(s1) //a
+
+ s2 := strutil.PadEnd("a", 2, "b")
+ fmt.Println(s2) //ab
+
+ s3 := strutil.PadEnd("abcd", 6, "mno")
+ fmt.Println(s3) //abcdmn
+
+ s4 := strutil.PadEnd("abc", 6, "ab")
+ fmt.Println(s4) //abcaba
+}
+```
+
+
+
+
+### PadStart
+Pads string on the left side if it's shorter than size.
+
+Signature:
+
+```go
+func PadStart(source string, size int, padStr string) string
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.PadStart("a", 1, "b")
+ fmt.Println(s1) //a
+
+ s2 := strutil.PadStart("a", 2, "b")
+ fmt.Println(s2) //ba
+
+ s3 := strutil.PadStart("abcd", 6, "mno")
+ fmt.Println(s3) //mnabcd
+
+ s4 := strutil.PadStart("abc", 6, "ab")
+ fmt.Println(s4) //abaabc
+}
+```
+
+
+
+
+### ReverseStr
+Return string whose char order is reversed to the given string.
+
+Signature:
+
+```go
+func ReverseStr(s string) string
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.ReverseStr("abc")
+ fmt.Println(s1) //cba
+
+ s2 := strutil.ReverseStr("12345")
+ fmt.Println(s2) //54321
+}
+```
+
+
+
+### SnakeCase
+Covert string to snake_case.
+
+Signature:
+
+```go
+func SnakeCase(s string) string
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.SnakeCase("Foo Bar-")
+ fmt.Println(s1) //foo_bar
+
+ s2 := strutil.SnakeCase("foo_Bar")
+ fmt.Println(s2) //foo_bar
+
+ s3 := strutil.SnakeCase("fooBar")
+ fmt.Println(s3) //foo_bar
+
+ s4 := strutil.SnakeCase("__FOO_BAR__")
+ fmt.Println(s4) //f_o_o_b_a_r
+
+ s5 := strutil.SnakeCase("aBbc-s$@a&%_B.B^C")
+ fmt.Println(s5) //a_bbc_s_a_b_b_c
+}
+```
+
+
+
+
+### Wrap
+Wrap a string with another string.
+
+Signature:
+
+```go
+func Wrap(str string, wrapWith string) string
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.Wrap("ab", "")
+ fmt.Println(s1) //ab
+
+ s2 := strutil.Wrap("", "*")
+ fmt.Println(s2) //""
+
+ s3 := strutil.Wrap("ab", "*")
+ fmt.Println(s3) //*ab*
+
+ s4 := strutil.Wrap("ab", "\"")
+ fmt.Println(s4) //\"ab\"
+
+ s5 := strutil.Wrap("ab", "'")
+ fmt.Println(s5) //'ab'
+}
+```
+
+
+
+
+### Wrap
+Unwrap a given string from anther string. will change str value.
+
+Signature:
+
+```go
+func Unwrap(str string, wrapToken string) string
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.Unwrap("ab", "")
+ fmt.Println(s1) //ab
+
+ s2 := strutil.Unwrap("ab", "*")
+ fmt.Println(s2) //ab
+
+ s3 := strutil.Unwrap("**ab**", "*")
+ fmt.Println(s3) //*ab*
+
+ s4 := strutil.Unwrap("*ab", "*")
+ fmt.Println(s4) //*ab
+
+ s5 := strutil.Unwrap("***", "**")
+ fmt.Println(s5) //***
+}
+```
+
+
+
+
+
+
+
+
+
diff --git a/docs/strutil_zh-CN.md b/docs/strutil_zh-CN.md
new file mode 100644
index 0000000..35d3ef3
--- /dev/null
+++ b/docs/strutil_zh-CN.md
@@ -0,0 +1,575 @@
+# Strutil
+strutil包含处理字符串的相关函数。
+
+
+
+## 源码:
+
+[https://github.com/duke-git/lancet/blob/main/strutil/string.go](https://github.com/duke-git/lancet/blob/main/strutil/string.go)
+
+
+
+
+## 用法:
+```go
+import (
+ "github.com/duke-git/lancet/strutil"
+)
+```
+
+
+
+## 目录
+- [After](#After)
+- [AfterLast](#AfterLast)
+- [Before](#Before)
+- [BeforeLast](#BeforeLast)
+- [CamelCase](#CamelCase)
+- [Capitalize](#Capitalize)
+- [IsString](#IsString)
+- [KebabCase](#KebabCase)
+- [LowerFirst](#LowerFirst)
+- [UpperFirst](#UpperFirst)
+- [PadEnd](#PadEnd)
+- [PadStart](#PadStart)
+- [ReverseStr](#ReverseStr)
+- [SnakeCase](#SnakeCase)
+- [Wrap](#Wrap)
+
+- [Unwrap](#Unwrap)
+
+
+
+
+
+## Documentation文档
+
+
+### After
+截取源字符串中char首次出现时的位置之后的子字符串
+
+函数签名:
+
+```go
+func After(s, char string) string
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.After("lancet", "")
+ fmt.Println(s1) //lancet
+
+ s2 := strutil.After("github.com/test/lancet", "/")
+ fmt.Println(s2) //test/lancet
+
+ s3 := strutil.After("github.com/test/lancet", "test")
+ fmt.Println(s3) // /lancet
+}
+```
+
+
+
+### AfterLast
+截取源字符串中char最后一次出现时的位置之后的子字符串
+
+函数签名:
+
+```go
+func AfterLast(s, char string) string
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.AfterLast("lancet", "")
+ fmt.Println(s1) //lancet
+
+ s2 := strutil.AfterLast("github.com/test/lancet", "/")
+ fmt.Println(s2) //lancet
+
+ s3 := strutil.AfterLast("github.com/test/test/lancet", "test")
+ fmt.Println(s3) // /lancet
+}
+```
+
+
+
+
+### Before
+截取源字符串中char首次出现时的位置之前的子字符串
+
+函数签名:
+
+```go
+func Before(s, char string) string
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.Before("lancet", "")
+ fmt.Println(s1) //lancet
+
+ s2 := strutil.Before("github.com/test/lancet", "/")
+ fmt.Println(s2) //github.com
+
+ s3 := strutil.Before("github.com/test/lancet", "test")
+ fmt.Println(s3) // github.com/
+}
+```
+
+
+
+
+### BeforeLast
+截取源字符串中char最后一次出现时的位置之前的子字符串
+
+函数签名:
+
+```go
+func BeforeLast(s, char string) string
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.BeforeLast("lancet", "")
+ fmt.Println(s1) //lancet
+
+ s2 := strutil.BeforeLast("github.com/test/lancet", "/")
+ fmt.Println(s2) //github.com/test
+
+ s3 := strutil.BeforeLast("github.com/test/test/lancet", "test")
+ fmt.Println(s3) //github.com/test/
+}
+```
+
+
+
+
+### CamelCase
+将字符串转换为驼峰式字符串
+
+函数签名:
+
+```go
+func CamelCase(s string) string
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.CamelCase("foo_bar")
+ fmt.Println(s1) //fooBar
+
+ s2 := strutil.CamelCase("Foo-Bar")
+ fmt.Println(s2) //fooBar
+
+ s3 := strutil.CamelCase("Foo&bar")
+ fmt.Println(s3) //fooBar
+
+ s4 := strutil.CamelCase("foo bar")
+ fmt.Println(s4) //fooBar
+}
+```
+
+
+
+
+### Capitalize
+将字符串的第一个字符转换为大写
+
+函数签名:
+
+```go
+func Capitalize(s string) string
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.Capitalize("foo")
+ fmt.Println(s1) //foo
+
+ s2 := strutil.Capitalize("Foo")
+ fmt.Println(s2) //foo
+
+ s3 := strutil.Capitalize("FOo"
+ fmt.Println(s3) //fOo
+}
+```
+
+
+
+### IsString
+检查值的数据类型是否为字符串
+
+函数签名:
+
+```go
+func IsString(v interface{}) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ fmt.Println(strutil.IsString("lancet")) //true
+ fmt.Println(strutil.IsString("")) //true
+
+ fmt.Println(strutil.IsString(1)) //false
+ fmt.Println(strutil.IsString("")) //false
+ fmt.Println(strutil.IsString([]string{})) //false
+}
+```
+
+
+
+### KebabCase
+将字符串转换为kebab-case
+
+函数签名:
+
+```go
+func KebabCase(s string) string
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.KebabCase("Foo Bar-")
+ fmt.Println(s1) //foo-bar
+
+ s2 := strutil.KebabCase("foo_Bar")
+ fmt.Println(s2) //foo-bar
+
+ s3 := strutil.KebabCase("fooBar")
+ fmt.Println(s3) //foo-bar
+
+ s4 := strutil.KebabCase("__FOO_BAR__")
+ fmt.Println(s4) //f-o-o-b-a-r
+}
+```
+
+
+
+
+### LowerFirst
+将字符串的第一个字符转换为小写
+
+函数签名:
+
+```go
+func LowerFirst(s string) string
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.LowerFirst("foo")
+ fmt.Println(s1) //foo
+
+ s2 := strutil.LowerFirst("BAR")
+ fmt.Println(s2) //bAR
+
+ s3 := strutil.LowerFirst("FOo")
+ fmt.Println(s3) //fOo
+
+ s4 := strutil.LowerFirst("fOo大")
+ fmt.Println(s4) //fOo大
+}
+```
+
+
+
+
+### UpperFirst
+将字符串的第一个字符转换为大写
+
+函数签名:
+
+```go
+func UpperFirst(s string) string
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.UpperFirst("foo")
+ fmt.Println(s1) //Foo
+
+ s2 := strutil.UpperFirst("bAR")
+ fmt.Println(s2) //BAR
+
+ s3 := strutil.UpperFirst("FOo")
+ fmt.Println(s3) //FOo
+
+ s4 := strutil.UpperFirst("fOo大")
+ fmt.Println(s4) //FOo大
+}
+```
+
+
+
+
+### PadEnd
+如果字符串长度短于size,则在右侧填充字符串
+
+函数签名:
+
+```go
+func PadEnd(source string, size int, padStr string) string
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.PadEnd("a", 1, "b")
+ fmt.Println(s1) //a
+
+ s2 := strutil.PadEnd("a", 2, "b")
+ fmt.Println(s2) //ab
+
+ s3 := strutil.PadEnd("abcd", 6, "mno")
+ fmt.Println(s3) //abcdmn
+
+ s4 := strutil.PadEnd("abc", 6, "ab")
+ fmt.Println(s4) //abcaba
+}
+```
+
+
+
+
+### PadStart
+如果字符串长度短于size,则在左侧填充字符串
+
+函数签名:
+
+```go
+func PadStart(source string, size int, padStr string) string
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.PadStart("a", 1, "b")
+ fmt.Println(s1) //a
+
+ s2 := strutil.PadStart("a", 2, "b")
+ fmt.Println(s2) //ba
+
+ s3 := strutil.PadStart("abcd", 6, "mno")
+ fmt.Println(s3) //mnabcd
+
+ s4 := strutil.PadStart("abc", 6, "ab")
+ fmt.Println(s4) //abaabc
+}
+```
+
+
+
+
+### ReverseStr
+返回字符顺序与给定字符串相反的字符串
+
+函数签名:
+
+```go
+func ReverseStr(s string) string
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.ReverseStr("abc")
+ fmt.Println(s1) //cba
+
+ s2 := strutil.ReverseStr("12345")
+ fmt.Println(s2) //54321
+}
+```
+
+
+
+### SnakeCase
+将字符串转换为snake_case形式
+
+函数签名:
+
+```go
+func SnakeCase(s string) string
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.SnakeCase("Foo Bar-")
+ fmt.Println(s1) //foo_bar
+
+ s2 := strutil.SnakeCase("foo_Bar")
+ fmt.Println(s2) //foo_bar
+
+ s3 := strutil.SnakeCase("fooBar")
+ fmt.Println(s3) //foo_bar
+
+ s4 := strutil.SnakeCase("__FOO_BAR__")
+ fmt.Println(s4) //f_o_o_b_a_r
+
+ s5 := strutil.SnakeCase("aBbc-s$@a&%_B.B^C")
+ fmt.Println(s5) //a_bbc_s_a_b_b_c
+}
+```
+
+
+
+
+### Wrap
+用另一个字符串包裹一个字符串
+
+函数签名:
+
+```go
+func Wrap(str string, wrapWith string) string
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.Wrap("ab", "")
+ fmt.Println(s1) //ab
+
+ s2 := strutil.Wrap("", "*")
+ fmt.Println(s2) //""
+
+ s3 := strutil.Wrap("ab", "*")
+ fmt.Println(s3) //*ab*
+
+ s4 := strutil.Wrap("ab", "\"")
+ fmt.Println(s4) //\"ab\"
+
+ s5 := strutil.Wrap("ab", "'")
+ fmt.Println(s5) //'ab'
+}
+```
+
+
+
+
+### Unwrap
+用另一个字符串解开包裹一个字符串
+
+函数签名:
+
+```go
+func Unwrap(str string, wrapToken string) string
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/strutil"
+)
+
+func main() {
+ s1 := strutil.Unwrap("ab", "")
+ fmt.Println(s1) //ab
+
+ s2 := strutil.Unwrap("ab", "*")
+ fmt.Println(s2) //ab
+
+ s3 := strutil.Unwrap("**ab**", "*")
+ fmt.Println(s3) //*ab*
+
+ s4 := strutil.Unwrap("*ab", "*")
+ fmt.Println(s4) //*ab
+
+ s5 := strutil.Unwrap("***", "**")
+ fmt.Println(s5) //***
+}
+```
+
+
+
+
+
+
+
+
+
From 300be9e3dc54c5a656acfb22e00c7af9e5151d14 Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Mon, 7 Feb 2022 11:21:47 +0800
Subject: [PATCH 22/34] docs: add doc for system package
---
docs/system.md | 242 +++++++++++++++++++++++++++++++++++++++++++
docs/system_zh-CN.md | 242 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 484 insertions(+)
create mode 100644 docs/system.md
create mode 100644 docs/system_zh-CN.md
diff --git a/docs/system.md b/docs/system.md
new file mode 100644
index 0000000..6e2adae
--- /dev/null
+++ b/docs/system.md
@@ -0,0 +1,242 @@
+# System
+Package system contains some functions about os, runtime, shell command.
+
+
+
+## Source:
+
+[https://github.com/duke-git/lancet/blob/main/system/os.go](https://github.com/duke-git/lancet/blob/main/system/os.go)
+
+
+
+
+## Usage:
+```go
+import (
+ "github.com/duke-git/lancet/system"
+)
+```
+
+
+
+## Index
+- [IsWindows](#IsWindows)
+- [IsLinux](#IsLinux)
+- [IsMac](#IsMac)
+- [GetOsEnv](#GetOsEnv)
+- [SetOsEnv](#SetOsEnv)
+- [RemoveOsEnv](#RemoveOsEnv)
+- [CompareOsEnv](#CompareOsEnv)
+- [ExecCommand](#ExecCommand)
+
+
+
+
+## Documentation
+
+
+### IsWindows
+Check if current os is windows.
+
+Signature:
+
+```go
+func IsWindows() bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/system"
+)
+
+func main() {
+ isOsWindows := system.IsWindows()
+ fmt.Println(isOsWindows)
+}
+```
+
+
+
+
+### IsLinux
+Check if current os is linux.
+
+Signature:
+
+```go
+func IsLinux() bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/system"
+)
+
+func main() {
+ isOsLinux := system.IsLinux()
+ fmt.Println(isOsLinux)
+}
+```
+
+
+
+### IsMac
+Check if current os is macos.
+
+Signature:
+
+```go
+func IsMac() bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/system"
+)
+
+func main() {
+ isOsMac := system.IsMac
+ fmt.Println(isOsMac)
+}
+```
+
+
+
+### GetOsEnv
+Gets the value of the environment variable named by the key.
+
+Signature:
+
+```go
+func GetOsEnv(key string) string
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/system"
+)
+
+func main() {
+ fooEnv := system.GetOsEnv("foo")
+ fmt.Println(fooEnv)
+}
+```
+
+
+
+### SetOsEnv
+Sets the value of the environment variable named by the key.
+
+Signature:
+
+```go
+func SetOsEnv(key, value string) error
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/system"
+)
+
+func main() {
+ err := system.SetOsEnv("foo", "foo_value")
+ fmt.Println(err)
+}
+```
+
+
+
+
+### RemoveOsEnv
+Remove a single environment variable.
+
+Signature:
+
+```go
+func RemoveOsEnv(key string) error
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/system"
+)
+
+func main() {
+ err := system.RemoveOsEnv("foo")
+ if err != nil {
+ fmt.Println(err)
+ }
+}
+```
+
+
+
+### CompareOsEnv
+Get env named by the key and compare it with comparedEnv.
+
+Signature:
+
+```go
+func CompareOsEnv(key, comparedEnv string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/system"
+)
+
+func main() {
+ system.SetOsEnv("foo", "foo_value")
+ res := system.CompareOsEnv("foo", "foo_value")
+ fmt.Println(res) //true
+}
+```
+
+
+
+
+### CompareOsEnv
+use shell /bin/bash -c(linux) or cmd (windows) to execute command.
+
+Signature:
+
+```go
+func ExecCommand(command string) (stdout, stderr string, err error)
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/system"
+)
+
+func main() {
+ out, errout, err := system.ExecCommand("ls")
+ fmt.Println(out)
+ fmt.Println(errout)
+ fmt.Println(err)
+}
+```
+
+
+
+
+
+
+
+
diff --git a/docs/system_zh-CN.md b/docs/system_zh-CN.md
new file mode 100644
index 0000000..166d892
--- /dev/null
+++ b/docs/system_zh-CN.md
@@ -0,0 +1,242 @@
+# System
+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)
+
+
+
+
+## 用法:
+```go
+import (
+ "github.com/duke-git/lancet/system"
+)
+```
+
+
+
+## 目录
+- [IsWindows](#IsWindows)
+- [IsLinux](#IsLinux)
+- [IsMac](#IsMac)
+- [GetOsEnv](#GetOsEnv)
+- [SetOsEnv](#SetOsEnv)
+- [RemoveOsEnv](#RemoveOsEnv)
+- [CompareOsEnv](#CompareOsEnv)
+- [ExecCommand](#ExecCommand)
+
+
+
+
+## Documentation文档
+
+
+### IsWindows
+检查当前操作系统是否是windows
+
+Signature:
+
+```go
+func IsWindows() bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/system"
+)
+
+func main() {
+ isOsWindows := system.IsWindows()
+ fmt.Println(isOsWindows)
+}
+```
+
+
+
+
+### IsLinux
+检查当前操作系统是否是linux
+
+Signature:
+
+```go
+func IsLinux() bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/system"
+)
+
+func main() {
+ isOsLinux := system.IsLinux()
+ fmt.Println(isOsLinux)
+}
+```
+
+
+
+### IsMac
+检查当前操作系统是否是macos
+
+Signature:
+
+```go
+func IsMac() bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/system"
+)
+
+func main() {
+ isOsMac := system.IsMac
+ fmt.Println(isOsMac)
+}
+```
+
+
+
+### GetOsEnv
+获取key命名的环境变量的值
+
+Signature:
+
+```go
+func GetOsEnv(key string) string
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/system"
+)
+
+func main() {
+ fooEnv := system.GetOsEnv("foo")
+ fmt.Println(fooEnv)
+}
+```
+
+
+
+### SetOsEnv
+设置由key命名的环境变量的值
+
+Signature:
+
+```go
+func SetOsEnv(key, value string) error
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/system"
+)
+
+func main() {
+ err := system.SetOsEnv("foo", "foo_value")
+ fmt.Println(err)
+}
+```
+
+
+
+
+### RemoveOsEnv
+删除单个环境变量
+
+Signature:
+
+```go
+func RemoveOsEnv(key string) error
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/system"
+)
+
+func main() {
+ err := system.RemoveOsEnv("foo")
+ if err != nil {
+ fmt.Println(err)
+ }
+}
+```
+
+
+
+### CompareOsEnv
+获取key命名的环境变量值并与compareEnv进行比较
+
+Signature:
+
+```go
+func CompareOsEnv(key, comparedEnv string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/system"
+)
+
+func main() {
+ system.SetOsEnv("foo", "foo_value")
+ res := system.CompareOsEnv("foo", "foo_value")
+ fmt.Println(res) //true
+}
+```
+
+
+
+
+### CompareOsEnv
+使用shell /bin/bash -c(linux) 或 cmd (windows) 执行shell命令
+
+Signature:
+
+```go
+func ExecCommand(command string) (stdout, stderr string, err error)
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/system"
+)
+
+func main() {
+ out, errout, err := system.ExecCommand("ls")
+ fmt.Println(out)
+ fmt.Println(errout)
+ fmt.Println(err)
+}
+```
+
+
+
+
+
+
+
+
From 6855fe0bce2a2cdbc3b566a6a2458688c340f52a Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Mon, 7 Feb 2022 12:41:58 +0800
Subject: [PATCH 23/34] docs: add doc for validator package
---
docs/validator.md | 799 ++++++++++++++++++++++++++++++++++++++++
docs/validator_zh-CN.md | 799 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 1598 insertions(+)
create mode 100644 docs/validator.md
create mode 100644 docs/validator_zh-CN.md
diff --git a/docs/validator.md b/docs/validator.md
new file mode 100644
index 0000000..f4275f1
--- /dev/null
+++ b/docs/validator.md
@@ -0,0 +1,799 @@
+# Validator
+Package validator contains some functions for data validation.
+
+
+
+## Source:
+
+[https://github.com/duke-git/lancet/blob/main/validator/validator.go](https://github.com/duke-git/lancet/blob/main/validator/validator.go)
+
+
+
+
+## Usage:
+```go
+import (
+ "github.com/duke-git/lancet/validator"
+)
+```
+
+
+
+## Index
+- [ContainChinese](#ContainChinese)
+- [ContainLetter](#ContainLetter)
+- [ContainLower](#ContainLower)
+- [ContainUpper](#ContainUpper)
+- [IsAlpha](#IsAlpha)
+- [IsAllUpper](#IsAllUpper)
+- [IsAllLower](#IsAllLower)
+- [IsBase64](#IsBase64)
+- [IsChineseMobile](#IsChineseMobile)
+- [IsChineseIdNum](#IsChineseIdNum)
+- [IsChinesePhone](#IsChinesePhone)
+- [IsCreditCard](#IsCreditCard)
+- [IsDns](#IsDns)
+- [IsEmail](#IsEmail)
+
+- [IsEmptyString](#IsEmptyString)
+- [IsFloatStr](#IsFloatStr)
+- [IsNumberStr](#IsNumberStr)
+- [IsJSON](#IsJSON)
+- [IsRegexMatch](#IsRegexMatch)
+- [IsIntStr](#IsIntStr)
+- [IsIp](#IsIp)
+- [IsIpV4](#IsIpV4)
+- [IsIpV6](#IsIpV6)
+- [IsStrongPassword](#IsStrongPassword)
+- [IsUrl](#IsUrl)
+- [IsWeakPassword](#IsWeakPassword)
+
+
+
+
+## Documentation
+
+
+### ContainChinese
+Check if the string contain mandarin chinese.
+
+Signature:
+
+```go
+func ContainChinese(s string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.ContainChinese("你好")
+ fmt.Println(res1) //true
+
+ res2 := validator.ContainChinese("你好hello")
+ fmt.Println(res2) //true
+
+ res3 := validator.ContainChinese("hello")
+ fmt.Println(res3) //false
+}
+```
+
+
+
+### ContainLetter
+Check if the string contain at least one letter.
+
+Signature:
+
+```go
+func ContainLetter(str string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.ContainLetter("1bc")
+ fmt.Println(res1) //true
+
+ res2 := validator.ContainLetter("123")
+ fmt.Println(res2) //false
+
+ res3 := validator.ContainLetter("&@#$%^&*")
+ fmt.Println(res3) //false
+}
+```
+
+
+
+
+### ContainLower
+Check if the string contain at least one lower case letter a-z.
+
+Signature:
+
+```go
+func ContainLower(str string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.ContainLower("1bc")
+ fmt.Println(res1) //true
+
+ res2 := validator.ContainLower("123")
+ fmt.Println(res2) //false
+
+ res3 := validator.ContainLower("1BC")
+ fmt.Println(res3) //false
+}
+```
+
+
+
+
+### ContainUpper
+Check if the string contain at least one upper case letter A-Z.
+
+Signature:
+
+```go
+func ContainUpper(str string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.ContainUpper("1bc")
+ fmt.Println(res1) //false
+
+ res2 := validator.ContainUpper("123")
+ fmt.Println(res2) //false
+
+ res3 := validator.ContainUpper("1BC")
+ fmt.Println(res3) //true
+}
+```
+
+
+
+
+### IsAlpha
+Check if the string contains only letters (a-zA-Z).
+
+Signature:
+
+```go
+func IsAlpha(s string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsAlpha("abc")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsAlpha("1bc")
+ fmt.Println(res2) //false
+
+ res3 := validator.IsAlpha("")
+ fmt.Println(res3) //false
+}
+```
+
+### IsAllUpper
+Check if string is all upper case letters A-Z.
+
+Signature:
+
+```go
+func IsAllUpper(str string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsAllUpper("ABC")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsAllUpper("aBC")
+ fmt.Println(res2) //false
+}
+```
+
+
+
+
+### IsAllLower
+Check if string is all lower case letters a-z.
+
+Signature:
+
+```go
+func IsAllLower(str string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsAllLower("abc")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsAllLower("abC")
+ fmt.Println(res2) //false
+}
+```
+
+
+
+
+### IsBase64
+Check if the string is base64 string.
+
+Signature:
+
+```go
+func IsBase64(base64 string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsBase64("aGVsbG8=")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsBase64("123456")
+ fmt.Println(res2) //false
+}
+```
+
+
+
+
+### IsChineseMobile
+Check if the string is valid chinese mobile number.
+
+Signature:
+
+```go
+func IsChineseMobile(mobileNum string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsChineseMobile("13263527980")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsChineseMobile("434324324")
+ fmt.Println(res2) //false
+}
+```
+
+
+
+### IsChineseIdNum
+Check if the string is chinese id number.
+
+Signature:
+
+```go
+func IsChineseIdNum(id string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsChineseIdNum("210911192105130715")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsChineseIdNum("123456")
+ fmt.Println(res2) //false
+}
+```
+
+
+
+
+### IsChinesePhone
+Check if the string is chinese phone number.
+
+Signature:
+
+```go
+func IsChinesePhone(phone string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsChinesePhone("010-32116675")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsChinesePhone("123-87562")
+ fmt.Println(res2) //false
+}
+```
+
+
+
+
+### IsCreditCard
+Check if the string is credit card.
+
+Signature:
+
+```go
+func IsCreditCard(creditCart string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsCreditCard("4111111111111111")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsCreditCard("123456")
+ fmt.Println(res2) //false
+}
+```
+
+
+
+
+### IsDns
+Check if the string is valid dns.
+
+Signature:
+
+```go
+func IsDns(dns string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsDns("abc.com")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsDns("a.b.com")
+ fmt.Println(res2) //false
+
+ res3 := validator.IsDns("http://abc.com")
+ fmt.Println(res3) //false
+}
+```
+
+
+
+
+### IsEmail
+Check if the string is email address.
+
+Signature:
+
+```go
+func IsEmail(email string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsEmail("abc@xyz.com")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsEmail("a.b@@com")
+ fmt.Println(res2) //false
+}
+```
+
+
+
+
+
+### IsEmptyString
+Check if the string is empty or not.
+
+Signature:
+
+```go
+func IsEmptyString(s string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsEmptyString("")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsEmptyString("abc")
+ fmt.Println(res2) //false
+}
+```
+
+
+
+
+### IsFloatStr
+Check if the string can convert to a float.
+
+Signature:
+
+```go
+func IsFloatStr(s string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsFloatStr("")) //false
+ fmt.Println(validator.IsFloatStr("12a")) //false
+ fmt.Println(validator.IsFloatStr("3.")) //true
+ fmt.Println(validator.IsFloatStr("+3.")) //true
+ fmt.Println(validator.IsFloatStr("-3.")) //true
+ fmt.Println(validator.IsFloatStr("12")) //true
+}
+```
+
+
+
+
+### IsNumberStr
+Check if the string can convert to a number.
+
+Signature:
+
+```go
+func IsNumberStr(s string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsNumberStr("")) //false
+ fmt.Println(validator.IsNumberStr("12a")) //false
+ fmt.Println(validator.IsNumberStr("3.")) //true
+ fmt.Println(validator.IsNumberStr("+3.")) //true
+ fmt.Println(validator.IsNumberStr("-3.")) //true
+ fmt.Println(validator.IsNumberStr("+3e2")) //true
+}
+```
+
+
+
+
+### IsJSON
+Check if the string is valid JSON.
+
+Signature:
+
+```go
+func IsJSON(str string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsJSON("")) //false
+ fmt.Println(validator.IsJSON("abc")) //false
+ fmt.Println(validator.IsJSON("{}")) //true
+ fmt.Println(validator.IsJSON("[]")) //true
+ fmt.Println(validator.IsJSON("123")) //true
+ fmt.Println(validator.IsJSON("{\"name\": \"test\"}")) //true
+}
+```
+
+
+
+
+### IsRegexMatch
+Check if the string match the regexp.
+
+Signature:
+
+```go
+func IsRegexMatch(s, regex string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsRegexMatch("abc", `^[a-zA-Z]+$`)) //true
+ fmt.Println(validator.IsRegexMatch("1ab", `^[a-zA-Z]+$`)) //false
+ fmt.Println(validator.IsRegexMatch("", `^[a-zA-Z]+$`)) //false
+}
+```
+
+
+
+
+### IsIntStr
+Check if the string can convert to a integer.
+
+Signature:
+
+```go
+func IsIntStr(s string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsIntStr("+3")) //true
+ fmt.Println(validator.IsIntStr("-3")) //true
+ fmt.Println(validator.IsIntStr("3.")) //false
+ fmt.Println(validator.IsIntStr("abc")) //false
+}
+```
+
+
+
+
+### IsIp
+Check if the string is a ip address.
+
+Signature:
+
+```go
+func IsIp(ipstr string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsIp("127.0.0.1")) //true
+ fmt.Println(validator.IsIp("::0:0:0:0:0:0:1")) //true
+ fmt.Println(validator.IsIp("127.0.0")) //false
+ fmt.Println(validator.IsIp("127")) //false
+}
+```
+
+
+
+
+### IsIpV4
+Check if the string is a ipv4 address.
+
+Signature:
+
+```go
+func IsIpV4(ipstr string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsIpV4("127.0.0.1")) //true
+ fmt.Println(validator.IsIpV4("::0:0:0:0:0:0:1")) //false
+ fmt.Println(validator.IsIpV4("127.0.0")) //false
+ fmt.Println(validator.IsIpV4("127")) //false
+}
+```
+
+
+
+
+### IsIpV6
+Check if the string is a ipv6 address.
+
+Signature:
+
+```go
+func IsIpV6(ipstr string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsIpV6("127.0.0.1")) //false
+ fmt.Println(validator.IsIpV6("::0:0:0:0:0:0:1")) //true
+ fmt.Println(validator.IsIpV6("127.0.0")) //false
+ fmt.Println(validator.IsIpV6("127")) //false
+}
+```
+
+
+
+
+### IsStrongPassword
+Check if the string is strong password (alpha(lower+upper) + number + special chars(!@#$%^&*()?><)).
+
+Signature:
+
+```go
+func IsStrongPassword(password string, length int) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsStrongPassword("abc", 3)) //false
+ fmt.Println(validator.IsStrongPassword("abc123", 6)) //false
+ fmt.Println(validator.IsStrongPassword("abcABC", 6)) //false
+ fmt.Println(validator.IsStrongPassword("abcABC123@#$", 16)) //false
+ fmt.Println(validator.IsStrongPassword("abcABC123@#$", 12)) //true
+}
+```
+
+
+
+
+### IsUrl
+Check if the string is url.
+
+Signature:
+
+```go
+func IsUrl(str string) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsUrl("http://abc.com")) //true
+ fmt.Println(validator.IsUrl("abc.com")) //true
+ fmt.Println(validator.IsUrl("a.b.com")) //true
+ fmt.Println(validator.IsUrl("abc")) //false
+}
+```
+
+
+
+
+### IsWeakPassword
+Check if the string is weak password(only letter or only number or letter + number)
+.
+
+Signature:
+
+```go
+func IsWeakPassword(password string, length int) bool
+```
+Example:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsWeakPassword("abc")) //true
+ fmt.Println(validator.IsWeakPassword("123")) //true
+ fmt.Println(validator.IsWeakPassword("abc123")) //true
+ fmt.Println(validator.IsWeakPassword("abc123@#$")) //false
+}
+```
+
+
+
+
+
+
+
+
+
diff --git a/docs/validator_zh-CN.md b/docs/validator_zh-CN.md
new file mode 100644
index 0000000..00c5e10
--- /dev/null
+++ b/docs/validator_zh-CN.md
@@ -0,0 +1,799 @@
+# Validator
+validator验证器包,包含常用字符串格式验证函数。
+
+
+
+## 源码:
+
+[https://github.com/duke-git/lancet/blob/main/validator/validator.go](https://github.com/duke-git/lancet/blob/main/validator/validator.go)
+
+
+
+
+## 用法:
+```go
+import (
+ "github.com/duke-git/lancet/validator"
+)
+```
+
+
+
+## 目录:
+- [ContainChinese](#ContainChinese)
+- [ContainLetter](#ContainLetter)
+- [ContainLower](#ContainLower)
+- [ContainUpper](#ContainUpper)
+- [IsAlpha](#IsAlpha)
+- [IsAllUpper](#IsAllUpper)
+- [IsAllLower](#IsAllLower)
+- [IsBase64](#IsBase64)
+- [IsChineseMobile](#IsChineseMobile)
+- [IsChineseIdNum](#IsChineseIdNum)
+- [IsChinesePhone](#IsChinesePhone)
+- [IsCreditCard](#IsCreditCard)
+- [IsDns](#IsDns)
+- [IsEmail](#IsEmail)
+
+- [IsEmptyString](#IsEmptyString)
+- [IsFloatStr](#IsFloatStr)
+- [IsNumberStr](#IsNumberStr)
+- [IsJSON](#IsJSON)
+- [IsRegexMatch](#IsRegexMatch)
+- [IsIntStr](#IsIntStr)
+- [IsIp](#IsIp)
+- [IsIpV4](#IsIpV4)
+- [IsIpV6](#IsIpV6)
+- [IsStrongPassword](#IsStrongPassword)
+- [IsUrl](#IsUrl)
+- [IsWeakPassword](#IsWeakPassword)
+
+
+
+
+## 文档
+
+
+### ContainChinese
+验证字符串是否包含中文字符
+
+函数签名:
+
+```go
+func ContainChinese(s string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.ContainChinese("你好")
+ fmt.Println(res1) //true
+
+ res2 := validator.ContainChinese("你好hello")
+ fmt.Println(res2) //true
+
+ res3 := validator.ContainChinese("hello")
+ fmt.Println(res3) //false
+}
+```
+
+
+
+### ContainLetter
+验证字符串是否包含至少一个英文字母
+
+函数签名:
+
+```go
+func ContainLetter(str string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.ContainLetter("1bc")
+ fmt.Println(res1) //true
+
+ res2 := validator.ContainLetter("123")
+ fmt.Println(res2) //false
+
+ res3 := validator.ContainLetter("&@#$%^&*")
+ fmt.Println(res3) //false
+}
+```
+
+
+
+
+### ContainLower
+验证字符串是否包含至少一个英文小写字母
+
+函数签名:
+
+```go
+func ContainLower(str string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.ContainLower("1bc")
+ fmt.Println(res1) //true
+
+ res2 := validator.ContainLower("123")
+ fmt.Println(res2) //false
+
+ res3 := validator.ContainLower("1BC")
+ fmt.Println(res3) //false
+}
+```
+
+
+
+
+### ContainUpper
+验证字符串是否包含至少一个英文大写字母.
+
+函数签名:
+
+```go
+func ContainUpper(str string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.ContainUpper("1bc")
+ fmt.Println(res1) //false
+
+ res2 := validator.ContainUpper("123")
+ fmt.Println(res2) //false
+
+ res3 := validator.ContainUpper("1BC")
+ fmt.Println(res3) //true
+}
+```
+
+
+
+
+### IsAlpha
+验证字符串是否只包含英文字母
+
+函数签名:
+
+```go
+func IsAlpha(s string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsAlpha("abc")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsAlpha("1bc")
+ fmt.Println(res2) //false
+
+ res3 := validator.IsAlpha("")
+ fmt.Println(res3) //false
+}
+```
+
+### IsAllUpper
+验证字符串是否全是大写英文字母
+
+函数签名:
+
+```go
+func IsAllUpper(str string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsAllUpper("ABC")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsAllUpper("aBC")
+ fmt.Println(res2) //false
+}
+```
+
+
+
+
+### IsAllLower
+验证字符串是否全是小写英文字母
+
+函数签名:
+
+```go
+func IsAllLower(str string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsAllLower("abc")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsAllLower("abC")
+ fmt.Println(res2) //false
+}
+```
+
+
+
+
+### IsBase64
+验证字符串是否是base64编码
+
+函数签名:
+
+```go
+func IsBase64(base64 string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsBase64("aGVsbG8=")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsBase64("123456")
+ fmt.Println(res2) //false
+}
+```
+
+
+
+
+### IsChineseMobile
+验证字符串是否是中国手机号码
+
+函数签名:
+
+```go
+func IsChineseMobile(mobileNum string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsChineseMobile("13263527980")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsChineseMobile("434324324")
+ fmt.Println(res2) //false
+}
+```
+
+
+
+### IsChineseIdNum
+验证字符串是否是中国身份证号码
+
+函数签名:
+
+```go
+func IsChineseIdNum(id string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsChineseIdNum("210911192105130715")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsChineseIdNum("123456")
+ fmt.Println(res2) //false
+}
+```
+
+
+
+
+### IsChinesePhone
+验证字符串是否是中国电话座机号码
+
+函数签名:
+
+```go
+func IsChinesePhone(phone string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsChinesePhone("010-32116675")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsChinesePhone("123-87562")
+ fmt.Println(res2) //false
+}
+```
+
+
+
+
+### IsCreditCard
+验证字符串是否是信用卡号码
+
+函数签名:
+
+```go
+func IsCreditCard(creditCart string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsCreditCard("4111111111111111")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsCreditCard("123456")
+ fmt.Println(res2) //false
+}
+```
+
+
+
+
+### IsDns
+验证字符串是否是有效dns
+
+函数签名:
+
+```go
+func IsDns(dns string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsDns("abc.com")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsDns("a.b.com")
+ fmt.Println(res2) //false
+
+ res3 := validator.IsDns("http://abc.com")
+ fmt.Println(res3) //false
+}
+```
+
+
+
+
+### IsEmail
+验证字符串是否是有效电子邮件地址
+
+函数签名:
+
+```go
+func IsEmail(email string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsEmail("abc@xyz.com")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsEmail("a.b@@com")
+ fmt.Println(res2) //false
+}
+```
+
+
+
+
+
+### IsEmptyString
+验证字符串是否是空字符串
+
+函数签名:
+
+```go
+func IsEmptyString(s string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ res1 := validator.IsEmptyString("")
+ fmt.Println(res1) //true
+
+ res2 := validator.IsEmptyString("abc")
+ fmt.Println(res2) //false
+}
+```
+
+
+
+
+### IsFloatStr
+验证字符串是否是可以转换为浮点数
+
+函数签名:
+
+```go
+func IsFloatStr(s string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsFloatStr("")) //false
+ fmt.Println(validator.IsFloatStr("12a")) //false
+ fmt.Println(validator.IsFloatStr("3.")) //true
+ fmt.Println(validator.IsFloatStr("+3.")) //true
+ fmt.Println(validator.IsFloatStr("-3.")) //true
+ fmt.Println(validator.IsFloatStr("12")) //true
+}
+```
+
+
+
+
+### IsNumberStr
+验证字符串是否是可以转换为数字
+
+函数签名:
+
+```go
+func IsNumberStr(s string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsNumberStr("")) //false
+ fmt.Println(validator.IsNumberStr("12a")) //false
+ fmt.Println(validator.IsNumberStr("3.")) //true
+ fmt.Println(validator.IsNumberStr("+3.")) //true
+ fmt.Println(validator.IsNumberStr("-3.")) //true
+ fmt.Println(validator.IsNumberStr("+3e2")) //true
+}
+```
+
+
+
+
+### IsJSON
+验证字符串是否是有效json
+
+函数签名:
+
+```go
+func IsJSON(str string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsJSON("")) //false
+ fmt.Println(validator.IsJSON("abc")) //false
+ fmt.Println(validator.IsJSON("{}")) //true
+ fmt.Println(validator.IsJSON("[]")) //true
+ fmt.Println(validator.IsJSON("123")) //true
+ fmt.Println(validator.IsJSON("{\"name\": \"test\"}")) //true
+}
+```
+
+
+
+
+### IsRegexMatch
+验证字符串是否可以匹配正则表达式
+
+函数签名:
+
+```go
+func IsRegexMatch(s, regex string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsRegexMatch("abc", `^[a-zA-Z]+$`)) //true
+ fmt.Println(validator.IsRegexMatch("1ab", `^[a-zA-Z]+$`)) //false
+ fmt.Println(validator.IsRegexMatch("", `^[a-zA-Z]+$`)) //false
+}
+```
+
+
+
+
+### IsIntStr
+验证字符串是否是可以转换为整数
+
+函数签名:
+
+```go
+func IsIntStr(s string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsIntStr("+3")) //true
+ fmt.Println(validator.IsIntStr("-3")) //true
+ fmt.Println(validator.IsIntStr("3.")) //false
+ fmt.Println(validator.IsIntStr("abc")) //false
+}
+```
+
+
+
+
+### IsIp
+验证字符串是否是ip地址
+
+函数签名:
+
+```go
+func IsIp(ipstr string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsIp("127.0.0.1")) //true
+ fmt.Println(validator.IsIp("::0:0:0:0:0:0:1")) //true
+ fmt.Println(validator.IsIp("127.0.0")) //false
+ fmt.Println(validator.IsIp("127")) //false
+}
+```
+
+
+
+
+### IsIpV4
+验证字符串是否是ipv4地址
+
+函数签名:
+
+```go
+func IsIpV4(ipstr string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsIpV4("127.0.0.1")) //true
+ fmt.Println(validator.IsIpV4("::0:0:0:0:0:0:1")) //false
+ fmt.Println(validator.IsIpV4("127.0.0")) //false
+ fmt.Println(validator.IsIpV4("127")) //false
+}
+```
+
+
+
+
+### IsIpV6
+验证字符串是否是ipv6地址
+
+函数签名:
+
+```go
+func IsIpV6(ipstr string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsIpV6("127.0.0.1")) //false
+ fmt.Println(validator.IsIpV6("::0:0:0:0:0:0:1")) //true
+ fmt.Println(validator.IsIpV6("127.0.0")) //false
+ fmt.Println(validator.IsIpV6("127")) //false
+}
+```
+
+
+
+
+### IsStrongPassword
+验证字符串是否是强密码:(alpha(lower+upper) + number + special chars(!@#$%^&*()?><))
+
+函数签名:
+
+```go
+func IsStrongPassword(password string, length int) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsStrongPassword("abc", 3)) //false
+ fmt.Println(validator.IsStrongPassword("abc123", 6)) //false
+ fmt.Println(validator.IsStrongPassword("abcABC", 6)) //false
+ fmt.Println(validator.IsStrongPassword("abcABC123@#$", 16)) //false
+ fmt.Println(validator.IsStrongPassword("abcABC123@#$", 12)) //true
+}
+```
+
+
+
+
+### IsUrl
+验证字符串是否是url
+
+函数签名:
+
+```go
+func IsUrl(str string) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsUrl("http://abc.com")) //true
+ fmt.Println(validator.IsUrl("abc.com")) //true
+ fmt.Println(validator.IsUrl("a.b.com")) //true
+ fmt.Println(validator.IsUrl("abc")) //false
+}
+```
+
+
+
+
+### IsWeakPassword
+验证字符串是否是弱密码:(only letter or only number or letter + number)
+.
+
+函数签名:
+
+```go
+func IsWeakPassword(password string, length int) bool
+```
+例子:
+
+```go
+import (
+ "fmt"
+ "github.com/duke-git/lancet/validator"
+)
+
+func main() {
+ fmt.Println(validator.IsWeakPassword("abc")) //true
+ fmt.Println(validator.IsWeakPassword("123")) //true
+ fmt.Println(validator.IsWeakPassword("abc123")) //true
+ fmt.Println(validator.IsWeakPassword("abc123@#$")) //false
+}
+```
+
+
+
+
+
+
+
+
+
From 8b04aa5f31d8e4262f23f1f99f062e4a9d8d1bc7 Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Mon, 7 Feb 2022 16:35:01 +0800
Subject: [PATCH 24/34] release v1.2.3 update readme file
---
README.md | 733 ++++++++++++++---------------------------
README_zh-CN.md | 741 ++++++++++++++----------------------------
docs/cryptor_zh-CN.md | 61 ++--
3 files changed, 502 insertions(+), 1033 deletions(-)
diff --git a/README.md b/README.md
index 2a1ee30..fca3a7b 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@

-[](https://github.com/duke-git/lancet/releases)
+[](https://github.com/duke-git/lancet/releases)
[](https://pkg.go.dev/github.com/duke-git/lancet)
[](https://goreportcard.com/report/github.com/duke-git/lancet)
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
@@ -56,543 +56,282 @@ func main() {
```
## API Documentation
-### 1. convertor contains some functions for data convertion
-
-- Support conversion between commonly used data types.
-- Usage: import "github.com/duke-git/lancet/convertor"
+### Convertor package contains some functions for data convertion.
```go
-package main
+import "github.com/duke-git/lancet/convertor"
+```
+#### Function list:
+- [ColorHexToRGB](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ColorHexToRGB)
+- [ColorRGBToHex](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ColorRGBToHex)
+- [ToBool](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToBool)
+- [ToBytes](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToBytes)
+- [ToChar](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToChar)
+- [ToInt](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToInt)
+- [ToJson](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToJson)
+- [ToString](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#ToString)
+- [StructToMap](https://github.com/duke-git/lancet/blob/main/docs/convertor.md#StructToMap)
+
+### Cryptor package is for data encryption and decryption.
+```go
+import "github.com/duke-git/lancet/cryptor"
+```
+
+#### Function list:
+- [AesEcbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesEcbEncrypt)
+- [AesEcbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesEcbDecrypt)
+- [AesCbcEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCbcEncrypt)
+- [AesCbcDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCbcDecrypt)
+- [AesCtrCrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCtrCrypt)
+- [AesCfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCfbEncrypt)
+- [AesCfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesCfbDecrypt)
+- [AesOfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesOfbEncrypt)
+- [AesOfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#AesOfbDecrypt)
+- [Base64StdEncode](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Base64StdEncode)
+- [Base64StdDecode](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Base64StdDecode)
+- [DesEcbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesEcbEncrypt)
+- [DesEcbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesEcbDecrypt)
+- [DesCbcEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCbcEncrypt)
+- [DesCbcDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCbcDecrypt)
+- [DesCtrCrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCtrCrypt)
+- [DesCfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCfbEncrypt)
+- [DesCfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesCfbDecrypt)
+- [DesOfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesOfbEncrypt)
+- [DesOfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#DesOfbDecrypt)
+- [HmacMd5](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacMd5)
+- [HmacSha1](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacSha1)
+- [HmacSha256](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacSha256)
+- [HmacSha512](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#HmacSha512)
+- [Md5String](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Md5String)
+- [Md5File](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Md5File)
+- [Sha1](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Sha1)
+- [Sha256](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Sha256)
+- [Sha512](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#Sha512)
+- [GenerateRsaKey](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#GenerateRsaKey)
+- [RsaEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#RsaEncrypt)
+- [RsaDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor.md#RsaDecrypt)
+
+### Datetime package supports date and time format and compare.
+
+
+```go
+import "github.com/duke-git/lancet/datetime"
+```
+#### Function list:
+- [AddDay](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddDay)
+- [AddHour](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddHour)
+- [AddMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#AddMinute)
+- [GetNowDate](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNowDate)
+- [GetNowTime](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNowTime)
+- [GetNowDateTime](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNowDateTime)
+- [GetZeroHourTimestamp](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetZeroHourTimestamp)
+- [GetNightTimestamp](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#GetNightTimestamp)
+- [FormatTimeToStr](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#FormatTimeToStr)
+- [FormatStrToTime](https://github.com/duke-git/lancet/blob/main/docs/datetime.md#FormatStrToTime)
+
+### Fileutil package implements some basic functions for file operations.
+
+```go
+import "github.com/duke-git/lancet/fileutil"
+```
+
+#### Function list:
+
+- [ClearFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#ClearFile)
+- [CreateFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#CreateFile)
+- [CopyFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#CopyFile)
+- [FileMode](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#FileMode)
+- [MiMeType](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#MiMeType)
+- [IsExist](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#IsExist)
+- [IsLink](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#IsLink)
+- [IsDir](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#IsDir)
+- [ListFileNames](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#ListFileNames)
+- [RemoveFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#RemoveFile)
+- [ReadFileToString](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#ReadFileToString)
+- [ReadFileByLine](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#ReadFileByLine)
+- [Zip](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#Zip)
+- [UnZip](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#UnZip)
+
+### Formatter contains some functions for data formatting.
+
+```go
import (
- "fmt"
- "github.com/duke-git/lancet/convertor"
-)
-
-func main() {
- s := "12.3"
- f, err := convertor.ToFloat(s)
- if err != nil {
- fmt.Errorf("error is %s", err.Error())
- }
- fmt.Println(f) // 12.3
-}
-```
-
-- Function list:
-
-```go
-func ColorHexToRGB(colorHex string) (red, green, blue int) //convert color hex to color rgb
-func ColorRGBToHex(red, green, blue int) string //convert color rgb to color hex
-func ToBool(s string) (bool, error) //convert string to a boolean
-func ToBytes(data interface{}) ([]byte, error) //convert interface to bytes
-func ToChar(s string) []string //convert string to char slice
-func ToFloat(value interface{}) (float64, error) //convert value to float64, if input is not a float return 0.0 and error
-func ToInt(value interface{}) (int64, error) //convert value to int64, if input is not a numeric format return 0 and error
-func ToJson(value interface{}) (string, error) //convert value to a valid json string
-func ToString(value interface{}) string //convert value to string
-func StructToMap(value interface{}) (map[string]interface{}, error) //convert struct to map, only convert exported field, tag `json` should be set
-```
-
-### 2. cryptor is for data encryption and decryption
-
-- Support md5, hmac, aes, des, rsa.
-- Usage: import "github.com/duke-git/lancet/cryptor"
-
-```go
-package main
-
-import (
- "fmt"
- "github.com/duke-git/lancet/cryptor"
-)
-
-func main() {
- data := "hello"
- key := "abcdefghijklmnop"
-
- encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
- decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key))
- fmt.Println(string(decrypted)) // hello
-}
-```
-
-- Function list:
-
-```go
-func AesEcbEncrypt(data, key []byte) []byte //AES ECB encrypt
-func AesEcbDecrypt(encrypted, key []byte) []byte //AES ECB decrypt
-func AesCbcEncrypt(data, key []byte) []byte //AES CBC encrypt
-func AesCbcDecrypt(encrypted, key []byte) []byte //AES CBC decrypt
-func AesCtrCrypt(data, key []byte) []byte //AES CTR encrypt / decrypt
-func AesCfbEncrypt(data, key []byte) []byte //AES CFB encrypt
-func AesCfbDecrypt(encrypted, key []byte) []byte //AES CFB decrypt
-func AesOfbEncrypt(data, key []byte) []byte //AES OFB encrypt
-func AesOfbDecrypt(data, key []byte) []byte //AES OFB decrypt
-func Base64StdEncode(s string) string //base64 encode
-func Base64StdDecode(s string) string //base64 decode
-func DesEcbEncrypt(data, key []byte) []byte //DES ECB encrypt
-func DesEcbDecrypt(encrypted, key []byte) []byte //DES ECB decrypt
-func DesCbcEncrypt(data, key []byte) []byte //DES CBC encrypt
-func DesCbcDecrypt(encrypted, key []byte) []byte //DES CBC decrypt
-func DesCtrCrypt(data, key []byte) []byte //DES CTR encrypt/decrypt
-func DesCfbEncrypt(data, key []byte) []byte //DES CFB encrypt
-func DesCfbDecrypt(encrypted, key []byte) []byte //DES CFB decrypt
-func DesOfbEncrypt(data, key []byte) []byte //DES OFB encrypt
-func DesOfbDecrypt(data, key []byte) []byte //DES OFB decrypt
-func HmacMd5(data, key string) string //get hmac md5 value
-func HmacSha1(data, key string) string //get hmac sha1 value
-func HmacSha256(data, key string) string //get hmac sha256 value
-func HmacSha512(data, key string) string //get hmac sha512 value
-func Md5String(s string) string //return the md5 value of string
-func Md5File(filename string) (string, error) //return the md5 value of file
-func Sha1(data string) string //get sha1 value
-func Sha256(data string) string //getsha256 value
-func Sha512(data string) string //get sha512 value
-func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) error //generate RSA pem file
-func RsaEncrypt(data []byte, pubKeyFileName string) []byte //RSA encrypt
-func RsaDecrypt(data []byte, privateKeyFileName string) []byte //RSA decrypt
-
-```
-
-### 3. datetime parse and format datetime
-
-- Parse and format datetime
-- Usage: import "github.com/duke-git/lancet/datetime"
-
-```go
-package main
-
-import (
- "fmt"
- "github.com/duke-git/lancet/datetime"
-)
-
-func main() {
- now := time.Now()
- s := datetime.FormatTimeToStr(now, "yyyy-mm-dd hh:mm:ss")
- fmt.Println(s) // 2021-11-24 11:16:55
-}
-```
-
-- Function list:
-
-```go
-func AddDay(t time.Time, day int64) time.Time //add or sub days to time
-func AddHour(t time.Time, hour int64) time.Time //add or sub hours to time
-func AddMinute(t time.Time, minute int64) time.Time //add or sub minutes to time
-func GetNowDate() string //get current date, format is yyyy-mm-dd
-func GetNowTime() string //get current time, format is hh:mm:ss
-func GetNowDateTime() string //get current date and time, format is yyyy-mm-dd hh:mm:ss
-func GetZeroHourTimestamp() int64 //return timestamp of zero hour (timestamp of 00:00)
-func GetNightTimestamp() int64 //return timestamp of zero hour (timestamp of 23:59)
-func FormatTimeToStr(t time.Time, format string) string //convert time to string
-func FormatStrToTime(str, format string) time.Time //convert string to time
-```
-
-### 4. fileutil basic functions for file operations
-
-- Basic functions for file operations.
-- Usage: import "github.com/duke-git/lancet/fileutil"
-
-```go
-package main
-
-import (
- "fmt"
- "github.com/duke-git/lancet/fileutil"
-)
-
-func main() {
- fmt.Println(fileutil.IsDir("./")) // true
-}
-```
-
-- Function list:
-
-```go
-func ClearFile(path string) error //write empty string to path file
-func CreateFile(path string) bool // create a file in path
-func CopyFile(srcFilePath string, dstFilePath string) error //copy src file to dst file
-func FileMode(path string) (fs.FileMode, error) //return file's mode and permission
-func MiMeType(file interface{}) string //return file mime type, file should be string or *os.File
-func IsExist(path string) bool //checks if a file or directory exists
-func IsLink(path string) bool //checks if a file is symbol link or not
-func IsDir(path string) bool //checks if the path is directy or not
-func ListFileNames(path string) ([]string, error) //return all file names in the path
-func RemoveFile(path string) error //remove the path file
-func ReadFileToString(path string) (string, error) //return string of file content
-func ReadFileByLine(path string)([]string, error) //read file content by line
-func Zip(fpath string, destPath string) error //create zip file, fpath could be a single file or a directory
-func UnZip(zipFile string, destPath string) error //unzip the file and save it to destPath
-```
-
-### 5. formatter is for data format
-
-- Contain some formatting function
-- Usage: import "github.com/duke-git/lancet/formatter"
-
-```go
-package main
-
-import (
- "fmt"
"github.com/duke-git/lancet/formatter"
)
-
-func main() {
- fmt.Println(formatter.Comma("12345", "")) // "12,345"
- fmt.Println(formatter.Comma(12345.67, "¥")) // "¥12,345.67"
-}
```
+#### Function list:
+- [Comma](https://github.com/duke-git/lancet/blob/main/docs/formatter.md#Comma)
-- Function list:
+### Function package can control the flow of function execution and support part of functional programming
```go
-func Comma(v interface{}, symbol string) string //add comma to number by every 3 numbers from right. ahead by symbol char
+import "github.com/duke-git/lancet/function"
```
-### 6. function can control the function execution and support functional programming
+#### Function list:
+- [After](https://github.com/duke-git/lancet/blob/main/docs/function.md#After)
+- [Before](https://github.com/duke-git/lancet/blob/main/docs/function.md#Before)
+- [Curry](https://github.com/duke-git/lancet/blob/main/docs/function.md#Curry)
+- [Compose](https://github.com/duke-git/lancet/blob/main/docs/function.md#Compose)
+- [Debounced](https://github.com/duke-git/lancet/blob/main/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/main/docs/function.md#Delay)
+- [Watcher](https://github.com/duke-git/lancet/blob/main/docs/function.md#Watcher)
-- Control function execution and support functional programming.
-- Usage: import "github.com/duke-git/lancet/function"
+### Netutil package contains functions to get net information and send http request.
```go
-package main
-
-import (
- "fmt"
- "github.com/duke-git/lancet/function"
-)
-
-func main() {
- var print = func(s string) {
- fmt.Println(s)
- }
- function.Delay(2*time.Second, print, "hello world")
-}
+import "github.com/duke-git/lancet/netutil"
```
-- Function list:
+#### Function list:
+- [ConvertMapToQueryString](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#ConvertMapToQueryString)
+- [GetInternalIp](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetInternalIp)
+- [GetPublicIpInfo](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#GetPublicIpInfo)
+- [IsPublicIP](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#IsPublicIP)
+- [HttpGet](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpGet)
+- [HttpDelete](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpDelete)
+- [HttpPost](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPost)
+- [HttpPut](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPut)
+- [HttpPatch](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPatch)
+- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#ParseHttpResponse)
+
+### Random package implements some basic functions to generate random int and string.
```go
-func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value //creates a function that invokes func once it's called n or more times
-func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value //creates a function that invokes func once it's called less than n times
-func (f Fn) Curry(i interface{}) func(...interface{}) interface{} //make a curryed function
-func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) interface{} //compose the functions from right to left
-func Debounced(fn func(), duration time.Duration) func() //creates a debounced function that delays invoking fn until after wait duration have elapsed since the last time the debounced function was invoked.
-func Delay(delay time.Duration, fn interface{}, args ...interface{}) //invoke function after delayed time
-func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool //invoke function every duration time, until close the returned bool chan
-func (w *Watcher) Start() //start the watch timer.
-func (w *Watcher) Stop() //stop the watch timer
-func (w *Watcher) Reset() {} //reset the watch timer.
-func (w *Watcher) GetElapsedTime() time.Duration //return time duration from watcher start to end.
+import "github.com/duke-git/lancet/random"
```
-### 7. netutil is for net process
+#### Function list:
+- [RandBytes](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandBytes)
+- [RandInt](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandInt)
+- [RandString](https://github.com/duke-git/lancet/blob/main/docs/random.md#RandString)
-- Ip and http request method.
-- Usage: import "github.com/duke-git/lancet/netutil".
-- The Http function params order:url, header, query string, body, httpclient.
+### Retry package is for executing a function repeatedly until it was successful or canceled by the context.
```go
-package main
-
-import (
- "fmt"
- "io/ioutil"
- "log"
- "github.com/duke-git/lancet/netutil"
-)
-
-func main() {
- url := "https://gutendex.com/books?"
- header := make(map[string]string)
- header["Content-Type"] = "application/json"
- queryParams := make(map[string]interface{})
- queryParams["ids"] = "1"
-
- resp, err := netutil.HttpGet(url, header, queryParams)
- if err != nil {
- log.Fatal(err)
- }
-
- body, _ := ioutil.ReadAll(resp.Body)
- fmt.Println("response: ", resp.StatusCode, string(body))
-}
+import "github.com/duke-git/lancet/retry"
```
-- Function list:
+#### Function list:
+- [Context](https://github.com/duke-git/lancet/blob/main/docs/retry.md#Context)
+- [Retry](https://github.com/duke-git/lancet/blob/main/docs/retry.md#Retry)
+- [RetryFunc](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryFunc)
+- [RetryDuration](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryDuration)
+- [RetryTimes](https://github.com/duke-git/lancet/blob/main/docs/retry.md#RetryTimes)
+
+### Slice contains some functions to manipulate slice.
```go
-func GetInternalIp() string //get internal ip
-func GetPublicIpInfo() (*PublicIpInfo, error) //get public ip info: country, region, isp, city, lat, lon, ip
-func IsPublicIP(IP net.IP) bool //判断ip是否为公共ip
-func HttpGet(url string, params ...interface{}) (*http.Response, error) //http get request
-func HttpPost(url string, params ...interface{}) (*http.Response, error) //http post request
-func HttpPut(url string, params ...interface{}) (*http.Response, error) //http put request
-func HttpDelete(url string, params ...interface{}) (*http.Response, error) //http delete request
-func HttpPatch(url string, params ...interface{}) (*http.Response, error) //http patch request
-func ConvertMapToQueryString(param map[string]interface{}) string //convert map to url query string
-func ParseHttpResponse(resp *http.Response, obj interface{}) error //decode http response to specified interface
+import "github.com/duke-git/lancet/slice"
```
-### 8. random is for rand string and int generation
+#### Function list:
+- [Contain](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Contain)
+- [ContainSubSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ContainSubSlice)
+- [Chunk](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Chunk)
+- [Compact](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Compact)
+- [Concat](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Concat)
+- [Count](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Count)
+- [Difference](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Difference)
+- [DifferenceBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DifferenceBy)
+- [DeleteByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DeleteByIndex)
+- [Drop](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Drop)
+- [Every](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Every)
+- [Filter](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Filter)
+- [Find](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Find)
+- [FindLast](https://github.com/duke-git/lancet/blob/main/docs/slice.md#FindLast)
+- [FlattenDeep](#FlattenDeep)
+- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ForEach)
+- [GroupBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#GroupBy)
+- [IntSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#IntSlice)
+- [InterfaceSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#InterfaceSlice)
+- [Intersection](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Intersection)
+- [InsertByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice.md#InsertByIndex)
+- [Map](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Map)
+- [ReverseSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ReverseSlice)
+- [Reduce](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Reduce)
+- [Shuffle](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Shuffle)
+- [SortByField](https://github.com/duke-git/lancet/blob/main/docs/slice.md#SortByField)
+- [Some](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Some)
+- [StringSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#StringSlice)
+- [Unique](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Unique)
+- [Union](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Union)
+- [UpdateByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice.md#UpdateByIndex)
+- [Without](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Without)
-- Generate random string and int.
-- Usage: import "github.com/duke-git/lancet/random".
+### Strutil package contains some functions to manipulate string.
```go
-package main
-
-import (
- "fmt"
- "io/ioutil"
- "log"
- "github.com/duke-git/lancet/random"
-)
-
-func main() {
- randStr := random.RandString(6)
- fmt.Println(randStr)
-}
+import "github.com/duke-git/lancet/strutil"
```
-- Function list:
+#### Function list:
+
+- [After](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#After)
+- [AfterLast](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#AfterLast)
+- [Before](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Before)
+- [BeforeLast](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#BeforeLast)
+- [CamelCase](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#CamelCase)
+- [Capitalize](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Capitalize)
+- [IsString](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#IsString)
+- [KebabCase](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#KebabCase)
+- [LowerFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#LowerFirst)
+- [UpperFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#UpperFirst)
+- [PadEnd](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#PadEnd)
+- [PadStart](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#PadStart)
+- [ReverseStr](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#ReverseStr)
+- [SnakeCase](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#SnakeCase)
+- [Wrap](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Wrap)
+- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#Unwrap)
+
+### System package contain some functions about os, runtime, shell command.
```go
-func RandBytes(length int) []byte //generate random []byte
-func RandInt(min, max int) int //generate random int
-func RandString(length int) string //generate random string
+import "github.com/duke-git/lancet/system"
```
-### 9. retry is for executing a function repeatedly until it was successful or canceled by the context.
+#### Function list:
+- [IsWindows](https://github.com/duke-git/lancet/blob/main/docs/system.md#IsWindows)
+- [IsLinux](https://github.com/duke-git/lancet/blob/main/docs/system.md#IsLinux)
+- [IsMac](https://github.com/duke-git/lancet/blob/main/docs/system.md#IsMac)
+- [GetOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system.md#GetOsEnv)
+- [SetOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system.md#SetOsEnv)
+- [RemoveOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system.md#RemoveOsEnv)
+- [CompareOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system.md#CompareOsEnv)
+- [ExecCommand](https://github.com/duke-git/lancet/blob/main/docs/system.md#ExecCommand)
-- Executes a function repeatedly until it was successful or canceled by the context.
-- Default retry times is 5, default retry duration is 3 second.
-- Usage: import "github.com/duke-git/lancet/retry".
+### Validator package contains some functions for data validation.
```go
-package main
-
-import (
- "fmt"
- "io/ioutil"
- "log"
- "github.com/duke-git/lancet/retry"
-)
-
-func main() {
- var number int
- increaseNumber := func() error {
- number++
- if number == 3 {
- return nil
- }
- return errors.New("error occurs")
- }
-
- err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
-
- fmt.Println(number) //3
-}
+import "github.com/duke-git/lancet/validator"
```
+#### Function list:
-- Function list:
-
-```go
-type RetryFunc func() error //function that retry executes
-func RetryTimes(n uint) //set times of retry
-func RetryDuration(d time.Duration) //generate random string
-func Context(ctx context.Context) //set retry context config
-func Retry(retryFunc RetryFunc, opts ...Option) error //executes the retryFunc repeatedly until it was successful or canceled by the context
-```
-
-### 10. slice is for process slice
-
-- Contain function for process slice.
-- Usage: import "github.com/duke-git/lancet/slice"
-- Due to the unstable support of generic, most of the slice processing function parameter and return value is interface {}. After go generic is stable, the related functions will be refactored.
-
-```go
-package main
-
-import (
- "fmt"
- "io/ioutil"
- "log"
- "github.com/duke-git/lancet/slice"
-)
-
-func main() {
- nums := []int{1, 4, 3, 4, 6, 7, 3}
- uniqueNums, _ := slice.IntSlice(slice.Unique(nums))
- fmt.Println(uniqueNums) //[1 4 3 6 7]
-}
-```
-
-- Function list:
-
-```go
-func Contain(slice interface{}, value interface{}) bool //check if the value is in the slice or not
-func ContainSubSlice(slice interface{}, subslice interface{}) bool //check if the slice contain subslice or not
-func Chunk(slice []interface{}, size int) [][]interface{} //creates an slice of elements split into groups the length of `size`
-func Compact(slice interface{}) interface{} //creates an slice with all falsey values removed. The values false, nil, 0, and "" are falsey
-func Concat(slice interface{}, values ...interface{}) interface{} //creates a new slice concatenating slice with any additional slices and/or values
-func Difference(slice1, slice2 interface{}) interface{} //creates an slice of whose element not included in the other given slice
-func DifferenceBy(slice interface{}, comparedSlice interface{}, iterateeFn interface{}) interface{} //it accepts iteratee which is invoked for each element of slice and values to generate the criterion by which they're compared.
-func DeleteByIndex(slice interface{}, start int, end ...int) (interface{}, error) //delete the element of slice from start index to end index - 1
-func Drop(slice interface{}, n int) interface{} //creates a slice with `n` elements dropped from the beginning when n > 0, or `n` elements dropped from the ending when n < 0
-func Every(slice, function interface{}) bool //return true if all of the values in the slice pass the predicate function, function signature should be func(index int, value interface{}) bool
-func None(slice, function interface{}) bool // return true if all the values in the slice mismatch the criteria
-func Filter(slice, function interface{}) interface{} //filter slice, function signature should be func(index int, value interface{}) bool
-func Find(slice, function interface{}) (interface{}, bool) //iterates over elements of slice, returning the first one that passes a truth test on function.function signature should be func(index int, value interface{}) bool
-func FlattenDeep(slice interface{}) interface{} //flattens slice recursive
-func ForEach(slice, function interface{}) //iterates over elements of slice and invokes function for each element, function signature should be func(index int, value interface{})
-func IntSlice(slice interface{}) ([]int, error) //convert value to int slice
-func InterfaceSlice(slice interface{}) []interface{} //convert value to interface{} slice
-func Intersection(slices ...interface{}) interface{} //creates a slice of unique values that included by all slices.
-func InsertByIndex(slice interface{}, index int, value interface{}) (interface{}, error) //insert the element into slice at index.
-func Map(slice, function interface{}) interface{} //map lisce, function signature should be func(index int, value interface{}) interface{}
-func ReverseSlice(slice interface{}) //revere slice
-func Reduce(slice, function, zero interface{}) interface{} //reduce slice, function signature should be func(index int, value1, value2 interface{}) interface{}
-func Shuffle(slice interface{}) interface{} //creates an slice of shuffled values
-func SortByField(slice interface{}, field string, sortType ...string) error //sort struct slice by field
-func Some(slice, function interface{}) bool //return true if any of the values in the list pass the predicate function, function signature should be func(index int, value interface{}) bool
-func StringSlice(slice interface{}) []string //convert value to string slice
-func Unique(slice interface{}) interface{} //remove duplicate elements in slice
-func Union(slices ...interface{}) interface{} //Union creates a slice of unique values, in order, from all given slices. using == for equality comparisons
-func UpdateByIndex(slice interface{}, index int, value interface{}) (interface{}, error) //update the slice element at index.
-func Without(slice interface{}, values ...interface{}) interface{} //creates a slice excluding all given values
-func GroupBy(slice, function interface{}) (interface{}, interface{}) // groups slice into two categories
-func Count(slice, function interface{}) int // Count iterates over elements of slice, returns a count of all matched elements
-```
-
-### 11. strutil is for processing string
-
-- Contain functions to precess string
-- Usage: import "github.com/duke-git/lancet/strutil"
-
-```go
-package main
-
-import (
- "fmt"
- "io/ioutil"
- "log"
- "github.com/duke-git/lancet/strutil"
-)
-
-func main() {
- str := "Foo-Bar"
- camelCaseStr := strutil.CamelCase(str)
- fmt.Println(camelCaseStr) //fooBar
-}
-```
-
-- Function list:
-
-```go
-func After(s, char string) string //create substring in source string after position when char first appear
-func AfterLast(s, char string) string //create substring in source string after position when char last appear
-func Before(s, char string) string //create substring in source string before position when char first appear
-func BeforeLast(s, char string) string //create substring in source string before position when char last appear
-func CamelCase(s string) string //covert string to camelCase string. "foo bar" -> "fooBar"
-func Capitalize(s string) string //convert the first character of a string to upper case, "fOO" -> "Foo"
-func IsString(v interface{}) bool //check if the value data type is string or not
-func KebabCase(s string) string //covert string to kebab-case, "foo_Bar" -> "foo-bar"
-func LowerFirst(s string) string //convert the first character of string to lower case
-func UpperFirst(s string) string //converts the first character of string to upper case
-func PadEnd(source string, size int, padStr string) string //pads string on the right side if it's shorter than size
-func PadStart(source string, size int, padStr string) string//pads string on the left side if it's shorter than size
-func ReverseStr(s string) string //return string whose char order is reversed to the given string
-func SnakeCase(s string) string //covert string to snake_case "fooBar" -> "foo_bar"
-func Wrap(str string, wrapWith string) string //wrap a string with another string.
-func Unwrap(str string, wrapToken string) string //unwrap a given string from anther string. will change str value
-```
-### 12. system contain some functions about os, runtime, shell command.
-
-- Generate random string and int.
-- Usage: import "github.com/duke-git/lancet/system".
-
-```go
-package main
-
-import (
- "fmt"
- "io/ioutil"
- "log"
- "github.com/duke-git/lancet/system"
-)
-
-func main() {
- envFoo := system.GetOsEnv("foo")
- fmt.Println(envFoo)
-}
-```
-
-- Function list:
-
-```go
-func IsWindows() bool //check if current os is windows
-func IsLinux() bool //check if current os is linux
-func IsMac() bool //check if current os is macos
-func GetOsEnv(key string) string //gets the value of the environment variable named by the key.
-func SetOsEnv(key, value string) error //sets the value of the environment variable named by the key.
-func RemoveOsEnv(key string) error //remove a single environment variable.
-func CompareOsEnv(key, comparedEnv string) bool //gets env named by the key and compare it with comparedEnv
-func ExecCommand(command string) (stdout, stderr string, err error) //use shell /bin/bash -c to execute command
-```
-
-### 13. validator is for data validation
-
-- Contain function for data validation.
-- Usage: import "github.com/duke-git/lancet/validator".
-
-```go
-package main
-
-import (
- "fmt"
- "io/ioutil"
- "log"
- "github.com/duke-git/lancet/validator"
-)
-
-func main() {
- str := "Foo-Bar"
- isAlpha := validator.IsAlpha(str)
- fmt.Println(isAlpha) //false
-}
-```
-
-- Function list:
-
-```go
-func ContainChinese(s string) bool //check if the string contain mandarin chinese
-func IsAlpha(s string) bool //checks if the string contains only letters (a-zA-Z)
-func IsBase64(base64 string) bool //check if the string is base64 string
-func IsAllUpper(str string) bool //check if the string is all upper case letters A-Z
-func IsAllLower(str string) bool //check if the string is all lower case letters a-z
-func ContainUpper(str string) bool //check if the string contain at least one upper case letter A-Z
-func ContainLower(str string) bool //check if the string contain at least one lower case letter a-z
-func ContainLetter(str string) bool //check if the string contain at least one letter
-func IsJSON(str string) bool //checks if the string is valid JSON
-func IsChineseMobile(mobileNum string) bool //check if the string is chinese mobile number
-func IsChineseIdNum(id string) bool //check if the string is chinese id number
-func IsChinesePhone(phone string) bool //check if the string is chinese phone number
-func IsCreditCard(creditCart string) bool //check if the string is credit card
-func IsDns(dns string) bool //check if the string is dns
-func IsEmail(email string) bool //check if the string is a email address
-func IsEmptyString(s string) bool //check if the string is empty
-func IsFloatStr(s string) bool //check if the string can convert to a float
-func IsNumberStr(s string) bool //check if the string can convert to a number
-func IsRegexMatch(s, regex string) bool //check if the string match the regexp
-func IsIntStr(s string) bool //check if the string can convert to a integer
-func IsIp(ipstr string) bool //check if the string is a ip address
-func IsIpV4(ipstr string) bool //check if the string is a ipv4 address
-func IsIpV6(ipstr string) bool //check if the string is a ipv6 address
-func IsStrongPassword(password string, length int) bool //check if the string is strong password (alpha(lower+upper) + number + special chars(!@#$%^&*()?><))
-func IsUrl(str string) bool //check if the string is url
-func IsWeakPassword(password string) bool //check if the string is weak password(only letter or only number or letter + number)
-```
+- [ContainChinese](https://github.com/duke-git/lancet/blob/main/docs/validator.md#ContainChinese)
+- [ContainLetter](https://github.com/duke-git/lancet/blob/main/docs/validator.md#ContainLetter)
+- [ContainLower](https://github.com/duke-git/lancet/blob/main/docs/validator.md#ContainLower)
+- [ContainUpper](https://github.com/duke-git/lancet/blob/main/docs/validator.md#ContainUpper)
+- [IsAlpha](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsAlpha)
+- [IsAllUpper](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsAllUpper)
+- [IsAllLower](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsAllLower)
+- [IsBase64](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsBase64)
+- [IsChineseMobile](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsChineseMobile)
+- [IsChineseIdNum](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsChineseIdNum)
+- [IsChinesePhone](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsChinesePhone)
+- [IsCreditCard](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsCreditCard)
+- [IsDns](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsDns)
+- [IsEmail](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsEmail)
+- [IsEmptyString](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsEmptyString)
+- [IsFloatStr](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsFloatStr)
+- [IsNumberStr](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsNumberStr)
+- [IsJSON](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsJSON)
+- [IsRegexMatch](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsRegexMatch)
+- [IsIntStr](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsIntStr)
+- [IsIp](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsIp)
+- [IsIpV4](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsIpV4)
+- [IsIpV6](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsIpV6)
+- [IsStrongPassword](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsStrongPassword)
+- [IsUrl](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsUrl)
+- [IsWeakPassword](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsWeakPassword)
\ No newline at end of file
diff --git a/README_zh-CN.md b/README_zh-CN.md
index 4a51389..2628885 100644
--- a/README_zh-CN.md
+++ b/README_zh-CN.md
@@ -4,7 +4,7 @@

-[](https://github.com/duke-git/lancet/releases)
+[](https://github.com/duke-git/lancet/releases)
[](https://pkg.go.dev/github.com/duke-git/lancet)
[](https://goreportcard.com/report/github.com/duke-git/lancet)
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
@@ -18,7 +18,7 @@
## 特性
- 👏 全面、高效、可复用
-- 💪 160+常用go工具函数,支持string、slice、datetime、net、crypt...
+- 💪 170+常用go工具函数,支持string、slice、datetime、net、crypt...
- 💅 只依赖go标准库
- 🌍 所有导出函数单元测试覆盖率100%
@@ -56,544 +56,287 @@ func main() {
```
## API文档
-### 1. convertor数据转换包
-
-- 转换函数支持常用数据类型之间的转换
-- 导入包:import "github.com/duke-git/lancet/convertor"
+### convertor转换器包支持一些常见的数据类型转换。
```go
-package main
+import "github.com/duke-git/lancet/convertor"
+```
+#### 函数列表:
+- [ColorHexToRGB](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ColorHexToRGB)
+- [ColorRGBToHex](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ColorRGBToHex)
+- [ToBool](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToBool)
+- [ToBytes](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToBytes)
+- [ToChar](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToChar)
+- [ToInt](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToInt)
+- [ToJson](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToJson)
+- [ToString](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#ToString)
+- [StructToMap](https://github.com/duke-git/lancet/blob/main/docs/convertor_zh-CN.md#StructToMap)
+
+### cryptor加密包支持数据加密和解密,获取md5,hash值。支持base64, md5, hmac, aes, des, rsa。
+```go
+import "github.com/duke-git/lancet/cryptor"
+```
+
+#### 函数列表:
+- [AesEcbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesEcbEncrypt)
+- [AesEcbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesEcbDecrypt)
+- [AesCbcEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCbcEncrypt)
+- [AesCbcDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCbcDecrypt)
+- [AesCtrCrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCtrCrypt)
+- [AesCfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCfbEncrypt)
+- [AesCfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesCfbDecrypt)
+- [AesOfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesOfbEncrypt)
+- [AesOfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#AesOfbDecrypt)
+- [Base64StdEncode](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Base64StdEncode)
+- [Base64StdDecode](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Base64StdDecode)
+- [DesEcbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesEcbEncrypt)
+- [DesEcbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesEcbDecrypt)
+- [DesCbcEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCbcEncrypt)
+- [DesCbcDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCbcDecrypt)
+- [DesCtrCrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCtrCrypt)
+- [DesCfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCfbEncrypt)
+- [DesCfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesCfbDecrypt)
+- [DesOfbEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesOfbEncrypt)
+- [DesOfbDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#DesOfbDecrypt)
+- [HmacMd5](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacMd5)
+- [HmacSha1](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacSha1)
+- [HmacSha256](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacSha256)
+- [HmacSha512](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#HmacSha512)
+- [Md5String](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Md5String)
+- [Md5File](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Md5File)
+- [Sha1](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Sha1)
+- [Sha256](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Sha256)
+- [Sha512](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#Sha512)
+- [GenerateRsaKey](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#GenerateRsaKey)
+- [RsaEncrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#RsaEncrypt)
+- [RsaDecrypt](https://github.com/duke-git/lancet/blob/main/docs/cryptor_zh-CN.md#RsaDecrypt)
+
+### datetime日期时间处理包,格式化日期,比较日期。
+
+
+```go
+import "github.com/duke-git/lancet/datetime"
+```
+#### 函数列表:
+- [AddDay](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddDay)
+- [AddHour](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddHour)
+- [AddMinute](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#AddMinute)
+- [GetNowDate](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNowDate)
+- [GetNowTime](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNowTime)
+- [GetNowDateTime](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNowDateTime)
+- [GetZeroHourTimestamp](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetZeroHourTimestamp)
+- [GetNightTimestamp](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#GetNightTimestamp)
+- [FormatTimeToStr](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#FormatTimeToStr)
+- [FormatStrToTime](https://github.com/duke-git/lancet/blob/main/docs/datetime_zh-CN.md#FormatStrToTime)
+
+### fileutil包支持文件基本操作。
+
+```go
+import "github.com/duke-git/lancet/fileutil"
+```
+
+#### 函数列表:
+
+- [ClearFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#ClearFile)
+- [CreateFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#CreateFile)
+- [CopyFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#CopyFile)
+- [FileMode](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#FileMode)
+- [MiMeType](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#MiMeType)
+- [IsExist](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#IsExist)
+- [IsLink](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#IsLink)
+- [IsDir](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#IsDir)
+- [ListFileNames](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#ListFileNames)
+- [RemoveFile](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#RemoveFile)
+- [ReadFileToString](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#ReadFileToString)
+- [ReadFileByLine](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#ReadFileByLine)
+- [Zip](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#Zip)
+- [UnZip](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#UnZip)
+
+### formatter格式化器包含一些数据格式化处理方法。
+
+```go
import (
- "fmt"
- "github.com/duke-git/lancet/convertor"
-)
-
-func main() {
- s := "12.3"
- f, err := convertor.ToFloat(s)
- if err != nil {
- fmt.Errorf("error is %s", err.Error())
- }
- fmt.Println(f) // 12.3
-}
-```
-
-- 函数列表:
-
-```go
-func ColorHexToRGB(colorHex string) (red, green, blue int) //颜色值16进制转rgb
-func ColorRGBToHex(red, green, blue int) string //颜色值rgb转16进制
-func ToBool(s string) (bool, error) //字符串转成Bool
-func ToBytes(data interface{}) ([]byte, error) //interface转成byte slice
-func ToChar(s string) []string //字符串转成字符slice
-func ToFloat(value interface{}) (float64, error) //interface转成float64
-func ToInt(value interface{}) (int64, error) //interface转成int64
-func ToJson(value interface{}) (string, error) //interface转成json string
-func ToString(value interface{}) string //interface转成string
-func StructToMap(value interface{}) (map[string]interface{}, error) //struct串转成map, 需要设置struct tag `json`
-```
-
-### 2. cryptor加解密包
-
-- 加密函数支持md5, hmac, aes, des, rsa
-- 导入包:import "github.com/duke-git/lancet/cryptor"
-
-```go
-package main
-
-import (
- "fmt"
- "github.com/duke-git/lancet/cryptor"
-)
-
-func main() {
- data := "hello"
- key := "abcdefghijklmnop"
-
- encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
- decrypted := cryptor.AesCbcDecrypt(encrypted, []byte(key))
- fmt.Println(string(decrypted)) // hello
-}
-```
-
-- 函数列表:
-
-```go
-func AesEcbEncrypt(data, key []byte) []byte //AES ECB模式加密
-func AesEcbDecrypt(encrypted, key []byte) []byte //AES ECB模式解密
-func AesCbcEncrypt(data, key []byte) []byte //AES CBC模式加密
-func AesCbcDecrypt(encrypted, key []byte) []byte //AES CBC模式解密
-func AesCtrCrypt(data, key []byte) []byte //AES CTR模式加密/解密
-func AesCfbEncrypt(data, key []byte) []byte //AES CFB模式加密
-func AesCfbDecrypt(encrypted, key []byte) []byte //AES CFB模式解密
-func AesOfbEncrypt(data, key []byte) []byte //AES OFB模式加密
-func AesOfbDecrypt(data, key []byte) []byte //AES OFB模式解密
-func Base64StdEncode(s string) string //base64编码
-func Base64StdDecode(s string) string //base64解码
-func DesEcbEncrypt(data, key []byte) []byte //DES ECB模式加密
-func DesEcbDecrypt(encrypted, key []byte) []byte //DES ECB模式解密
-func DesCbcEncrypt(data, key []byte) []byte //DES CBC模式加密
-func DesCbcDecrypt(encrypted, key []byte) []byte //DES CBC模式解密
-func DesCtrCrypt(data, key []byte) []byte //DES CTR模式加密/解密
-func DesCfbEncrypt(data, key []byte) []byte //DES CFB模式加密
-func DesCfbDecrypt(encrypted, key []byte) []byte //DES CFB模式解密
-func DesOfbEncrypt(data, key []byte) []byte //DES OFB模式加密
-func DesOfbDecrypt(data, key []byte) []byte //DES OFB模式解密
-func HmacMd5(data, key string) string //获取hmac md5值
-func HmacSha1(data, key string) string //获取hmac sha1值
-func HmacSha256(data, key string) string //获取hmac sha256值
-func HmacSha512(data, key string) string //获取hmac sha512值
-func Md5String(s string) string //获取字符串md5值
-func Md5File(filename string) (string, error) //获取文件md5值
-func Sha1(data string) string //获取sha1值
-func Sha256(data string) string //获取sha256值
-func Sha512(data string) string //获取sha512值
-func GenerateRsaKey(keySize int, priKeyFile, pubKeyFile string) error //生成RSA私钥文件
-func RsaEncrypt(data []byte, pubKeyFileName string) []byte //RSA加密
-func RsaDecrypt(data []byte, privateKeyFileName string) []byte //RSA解密
-
-```
-
-### 3. datetime日期时间处理包
-
-- 处理日期时间
-- 导入包:import "github.com/duke-git/lancet/datetime"
-
-```go
-package main
-
-import (
- "fmt"
- "github.com/duke-git/lancet/datetime"
-)
-
-func main() {
- now := time.Now()
- s := datetime.FormatTimeToStr(now, "yyyy-mm-dd hh:mm:ss")
- fmt.Println(s) // 2021-11-24 11:16:55
-}
-```
-
-- 函数列表:
-
-```go
-func AddDay(t time.Time, day int64) time.Time //加减天数
-func AddHour(t time.Time, hour int64) time.Time //加减小时数
-func AddMinute(t time.Time, minute int64) time.Time //加减分钟数
-func GetNowDate() string //获取当天日期 格式yyyy-mm-dd
-func GetNowTime() string //获取当前时间 格式hh:mm:ss
-func GetNowDateTime() string //获取当前日期时间 格式yyyy-mm-dd hh:mm:ss
-func GetZeroHourTimestamp() int64 //获取当天零时时间戳(00:00)
-func GetNightTimestamp() int64 //获取当天23时时间戳(23:59)
-func FormatTimeToStr(t time.Time, format string) string //时间格式化字符串
-func FormatStrToTime(str, format string) time.Time //字符串转换成时间
-```
-
-### 4. fileutil文件处理包
-
-- 文件处理常用函数
-- 导入包:import "github.com/duke-git/lancet/fileutil"
-
-```go
-package main
-
-import (
- "fmt"
- "github.com/duke-git/lancet/fileutil"
-)
-
-func main() {
- fmt.Println(fileutil.IsDir("./")) // true
-}
-```
-
-- 函数列表:
-
-```go
-func ClearFile(path string) error //清空文件内容
-func CreateFile(path string) bool //创建文件
-func FileMode(path string) (fs.FileMode, error) //返回文件mode信息
-func MiMeType(file interface{}) string //返回文件mime类型
-func IsExist(path string) bool //判断文件/目录是否存在
-func IsDir(path string) bool //判断是否为目录
-func IsLink(path string) bool //检查文件是否为符号链接文件
-func RemoveFile(path string) error //删除文件
-func CopyFile(srcFilePath string, dstFilePath string) error //复制文件
-func ListFileNames(path string) ([]string, error) //列出目录下所有文件名称
-func ReadFileToString(path string) (string, error) //读取文件内容为字符串
-func ReadFileByLine(path string)([]string, error) //按行读取文件内容
-func Zip(fpath string, destPath string) error //压缩文件fpath参数可以是文件或目录,destPath是压缩后目标文件
-func UnZip(zipFile string, destPath string) error //解压文件,并将文件存储在destPath目录中
-```
-
-### 5. formatter格式化处理包
-
-- 格式化相关处理函数
-- 导入包:import "github.com/duke-git/lancet/formatter"
-
-```go
-package main
-
-import (
- "fmt"
"github.com/duke-git/lancet/formatter"
)
-
-func main() {
- fmt.Println(formatter.Comma("12345", "")) // "12,345"
- fmt.Println(formatter.Comma(12345.67, "¥")) // "¥12,345.67"
-}
```
+#### 函数列表:
+- [Comma](https://github.com/duke-git/lancet/blob/main/docs/formatter_zh-CN.md#Comma)
-- 函数列表:
+
+### function函数包控制函数执行流程,包含部分函数式编程。
```go
-func Comma(v interface{}, symbol string) string //用逗号每隔3位分割数字/字符串
+import "github.com/duke-git/lancet/function"
```
-### 6. function包可以控制函数执行,支持部分函数式编程
+#### 函数列表:
+- [After](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#After)
+- [Before](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Before)
+- [Curry](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Curry)
+- [Compose](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Compose)
+- [Debounced](https://github.com/duke-git/lancet/blob/main/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/main/docs/function_zh-CN.md#Delay)
+- [Watcher](https://github.com/duke-git/lancet/blob/main/docs/function_zh-CN.md#Watcher)
-- 控制函数执行,支持部分函数式编程
-- 导入包:import "github.com/duke-git/lancet/function"
+
+### netutil网络包支持获取ip地址,发送http请求。
```go
-package main
-
-import (
- "fmt"
- "github.com/duke-git/lancet/function"
-)
-
-func main() {
- var print = func(s string) {
- fmt.Println(s)
- }
- function.Delay(2*time.Second, print, "hello world")
-}
+import "github.com/duke-git/lancet/netutil"
```
-- Function list:
+#### 函数列表:
+- [ConvertMapToQueryString](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#ConvertMapToQueryString)
+- [GetInternalIp](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#GetInternalIp)
+- [GetPublicIpInfo](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#GetPublicIpInfo)
+- [IsPublicIP](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#IsPublicIP)
+- [HttpGet](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpGet)
+- [HttpDelete](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpDelete)
+- [HttpPost](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPost)
+- [HttpPut](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPut)
+- [HttpPatch](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPatch)
+- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#ParseHttpResponse)
+
+### random随机数生成器包,可以生成随机[]bytes, int, string。
```go
-func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value //创建一个函数, 只有在运行了n次之后才有效果
-func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value //创建一个函数,调用不超过n次。 当n已经达到时,最后一个函数调用的结果将被记住并返回
-func (f Fn) Curry(i interface{}) func(...interface{}) interface{} //函数柯里化
-func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) interface{} //从右至左组合函数
-func Delay(delay time.Duration, fn interface{}, args ...interface{}) //延迟调用函数
-func Debounced(fn func(), duration time.Duration) func() //go防抖函数,在duration时间内连续调用只会执行一次.
-func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool //每隔duration时间调用函数, 关闭返回通道可以停止调用
-func (w *Watcher) Start() //开时watcher
-func (w *Watcher) Stop() //开时watcher
-func (w *Watcher) Reset() {} //重置代码watcher
-func (w *Watcher) GetElapsedTime() time.Duration //get code excution elapsed time.
+import "github.com/duke-git/lancet/random"
```
-### 7. netutil网络处理包
+#### 函数列表:
+- [RandBytes](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandBytes)
+- [RandInt](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandInt)
+- [RandString](https://github.com/duke-git/lancet/blob/main/docs/random_zh-CN.md#RandString)
-- 处理ip, http请求相关函数
-- 导入包:import "github.com/duke-git/lancet/netutil"
-- http方法params参数顺序:header, query string, body, httpclient
+### retry重试执行函数直到函数运行成功或被context cancel。
```go
-package main
-
-import (
- "fmt"
- "io/ioutil"
- "log"
- "github.com/duke-git/lancet/netutil"
-)
-
-func main() {
- url := "https://gutendex.com/books?"
- header := make(map[string]string)
- header["Content-Type"] = "application/json"
- queryParams := make(map[string]interface{})
- queryParams["ids"] = "1"
-
- resp, err := netutil.HttpGet(url, header, queryParams)
- if err != nil {
- log.Fatal(err)
- }
-
- body, _ := ioutil.ReadAll(resp.Body)
- fmt.Println("response: ", resp.StatusCode, string(body))
-}
+import "github.com/duke-git/lancet/retry"
```
-- 函数列表:
+#### 函数列表:
+- [Context](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#Context)
+- [Retry](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#Retry)
+- [RetryFunc](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryFunc)
+- [RetryDuration](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryDuration)
+- [RetryTimes](https://github.com/duke-git/lancet/blob/main/docs/retry_zh-CN.md#RetryTimes)
+
+
+### slice包包含操作切片的方法集合。
```go
-func GetInternalIp() string //获取内部ip
-func GetPublicIpInfo() (*PublicIpInfo, error) //获取公共ip信息: country, region, isp, city, lat, lon, ip
-func IsPublicIP(IP net.IP) bool //判断ip是否为公共ip
-func HttpGet(url string, params ...interface{}) (*http.Response, error) //http get请求
-func HttpPost(url string, params ...interface{}) (*http.Response, error) //http post请求
-func HttpPut(url string, params ...interface{}) (*http.Response, error) //http put请求
-func HttpDelete(url string, params ...interface{}) (*http.Response, error) //http delete请求
-func HttpPatch(url string, params ...interface{}) (*http.Response, error) //http patch请求
-func ConvertMapToQueryString(param map[string]interface{}) string //将map转换成url query string
-func ParseHttpResponse(resp *http.Response, obj interface{}) error //将http响应解码成特定interface
+import "github.com/duke-git/lancet/slice"
```
-### 8. random随机数处理包
+#### 函数列表:
+- [Contain](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Contain)
+- [ContainSubSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ContainSubSlice)
+- [Chunk](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Chunk)
+- [Compact](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Compact)
+- [Concat](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Concat)
+- [Count](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Count)
+- [Difference](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Difference)
+- [DifferenceBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#DifferenceBy)
+- [DeleteByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#DeleteByIndex)
+- [Drop](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Drop)
+- [Every](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Every)
+- [Filter](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Filter)
+- [Find](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Find)
+- [FindLast](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#FindLast)
+- [FlattenDeep](#FlattenDeep)
+- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ForEach)
+- [GroupBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#GroupBy)
+- [IntSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#IntSlice)
+- [InterfaceSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#InterfaceSlice)
+- [Intersection](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Intersection)
+- [InsertByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#InsertByIndex)
+- [Map](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Map)
+- [ReverseSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ReverseSlice)
+- [Reduce](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Reduce)
+- [Shuffle](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Shuffle)
+- [SortByField](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#SortByField)
+- [Some](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Some)
+- [StringSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#StringSlice)
+- [Unique](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Unique)
+- [Union](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Union)
+- [UpdateByIndex](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#UpdateByIndex)
+- [Without](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Without)
-- 生成和处理随机数
-- 导入包:import "github.com/duke-git/lancet/random"
+
+### strutil包含处理字符串的相关函数。
```go
-package main
-
-import (
- "fmt"
- "io/ioutil"
- "log"
- "github.com/duke-git/lancet/random"
-)
-
-func main() {
- randStr := random.RandString(6)
- fmt.Println(randStr)
-}
+import "github.com/duke-git/lancet/strutil"
```
-- 函数列表:
+#### 函数列表:
+
+- [After](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#After)
+- [AfterLast](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#AfterLast)
+- [Before](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Before)
+- [BeforeLast](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#BeforeLast)
+- [CamelCase](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#CamelCase)
+- [Capitalize](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Capitalize)
+- [IsString](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#IsString)
+- [KebabCase](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#KebabCase)
+- [LowerFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#LowerFirst)
+- [UpperFirst](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#UpperFirst)
+- [PadEnd](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#PadEnd)
+- [PadStart](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#PadStart)
+- [ReverseStr](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#ReverseStr)
+- [SnakeCase](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#SnakeCase)
+- [Wrap](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Wrap)
+- [Unwrap](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#Unwrap)
+
+
+### system包含os, runtime, shell command相关函数。
```go
-func RandBytes(length int) []byte //生成随机[]byte
-func RandInt(min, max int) int //生成随机int
-func RandString(length int) string //生成随机string
+import "github.com/duke-git/lancet/system"
```
-### 9. retry重试执行函数
+#### 函数列表:
+- [IsWindows](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#IsWindows)
+- [IsLinux](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#IsLinux)
+- [IsMac](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#IsMac)
+- [GetOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#GetOsEnv)
+- [SetOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#SetOsEnv)
+- [RemoveOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#RemoveOsEnv)
+- [CompareOsEnv](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#CompareOsEnv)
+- [ExecCommand](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN.md#ExecCommand)
-- 重试执行函数直到函数成功或被context停止
-- 默认重试次数5, 默认执行间隔3秒.
-- Usage: import "github.com/duke-git/lancet/retry".
+### validator验证器包,包含常用字符串格式验证函数。
```go
-package main
-
-import (
- "fmt"
- "io/ioutil"
- "log"
- "github.com/duke-git/lancet/retry"
-)
-
-func main() {
- var number int
- increaseNumber := func() error {
- number++
- if number == 3 {
- return nil
- }
- return errors.New("error occurs")
- }
-
- err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
-
- fmt.Println(number) //3
-}
+import "github.com/duke-git/lancet/validator"
```
+#### 函数列表:
-- Function list:
-
-```go
-type RetryFunc func() error //要重试执行的函数
-func RetryTimes(n uint) //设置重试次数,默认5次
-func RetryDuration(d time.Duration) //设置重试间隔时间,默认3秒
-func Context(ctx context.Context) //context config
-func Retry(retryFunc RetryFunc, opts ...Option) error //重试函数
-```
-
-### 10. slice切片操作包
-
-- 切片操作相关函数
-- 导入包:import "github.com/duke-git/lancet/slice"
-- 由于go目前对范型支持不稳定,slice处理函数参数和返回值大部分为interface{}, 待范型特性稳定后,会重构相关函数
-
-```go
-package main
-
-import (
- "fmt"
- "io/ioutil"
- "log"
- "github.com/duke-git/lancet/slice"
-)
-
-func main() {
- nums := []int{1, 4, 3, 4, 6, 7, 3}
- uniqueNums, _ := slice.IntSlice(slice.Unique(nums))
- fmt.Println(uniqueNums) //[1 4 3 6 7]
-}
-```
-
-- 函数列表:
-
-```go
-func Contain(slice interface{}, value interface{}) bool //判断slice是否包含value
-func ContainSubSlice(slice interface{}, subslice interface{}) bool //判断slice是否包含subslice
-func Chunk(slice []interface{}, size int) [][]interface{} //均分slice
-func Compact(slice interface{}) interface{} //去除slice中的false vule. false values are false, nil, 0, and ""
-func Concat(slice interface{}, values ...interface{}) interface{} //连接values到slice中
-func Difference(slice1, slice2 interface{}) interface{} //返回切片,其元素在slice1中,不在slice2中
-func DifferenceBy(slice interface{}, comparedSlice interface{}, iterateeFn interface{}) interface{} //将slice 和comparedSlice中每个元素调用iterateeFn后作比较,如果不相等返回slice中的元素。
-func DeleteByIndex(slice interface{}, start int, end ...int) (interface{}, error) //删除切片中start到end位置的值
-func Drop(slice interface{}, n int) interface{} //创建一个新切片,当n大于0时删除原切片前n个元素,当n小于0时删除原切片后n个元素
-func Every(slice, function interface{}) bool //slice中所有元素都符合函数条件时返回true, 否则返回false. 函数签名:func(index int, value interface{}) bool
-func None(slice, function interface{}) bool //slice中所有元素都不符合函数条件时返回true, 否则返回false. 函数签名:func(index int, value interface{}) bool
-func Find(slice, function interface{}) (interface{}, bool)//查找slice中第一个符合条件的元素,函数签名:func(index int, value interface{}) bool
-func Filter(slice, function interface{}) interface{} //过滤slice, 函数签名:func(index int, value interface{}) bool
-func FlattenDeep(slice interface{}) interface{} //将slice递归为一维切片。
-func ForEach(slice, function interface{}) //遍历切片,在每个元素上执行函数,函数签名:func(index int, value interface{})
-func IntSlice(slice interface{}) ([]int, error) //转成int切片
-func InterfaceSlice(slice interface{}) []interface{} //转成interface{}切片
-func Intersection(slices ...interface{}) interface{} //slice交集,去重
-func InsertByIndex(slice interface{}, index int, value interface{}) (interface{}, error) //在切片中index位置插入value
-func Map(slice, function interface{}) interface{} //遍历切片, 函数签名:func(index int, value interface{}) interface{}
-func ReverseSlice(slice interface{}) //反转切片
-func Reduce(slice, function, zero interface{}) interface{} //切片reduce操作, 函数签名:func(index int, value1, value2 interface{}) interface{}
-func Shuffle(slice interface{}) interface{} //创建一个被打乱值的切片
-func Some(slice, function interface{}) bool //slice中任意一个元素都符合函数条件时返回true, 否则返回false. 函数签名:func(index int, value interface{}) bool
-func SortByField(slice interface{}, field string, sortType ...string) error //对struct切片进行排序
-func StringSlice(slice interface{}) []string //转为string切片
-func Unique(slice interface{}) interface{} //去重切片
-func Union(slices ...interface{}) interface{} //slice并集, 去重
-func UpdateByIndex(slice interface{}, index int, value interface{}) (interface{}, error) //在切片中index位置更新value
-func Without(slice interface{}, values ...interface{}) interface{} //slice去除values
-func GroupBy(slice, function interface{}) (interface{}, interface{}) //根据函数function的逻辑分slice为两组slice
-func Count(slice, function interface{}) int
-```
-
-### 11. strutil字符串处理包
-
-- 字符串操作相关函数
-- 导入包:import "github.com/duke-git/lancet/strutil"
-
-```go
-package main
-
-import (
- "fmt"
- "io/ioutil"
- "log"
- "github.com/duke-git/lancet/strutil"
-)
-
-func main() {
- str := "Foo-Bar"
- camelCaseStr := strutil.CamelCase(str)
- fmt.Println(camelCaseStr) //fooBar
-}
-```
-
-- 函数列表:
-
-```go
-func After(s, char string) string //截取字符串中char第一次出现之后的字符串
-func AfterLast(s, char string) string //截取字符串中char最后一次出现之后的字符串
-func Before(s, char string) string //截取字符串中char第一次出现之前的字符串
-func BeforeLast(s, char string) string //截取字符串中char最后一次出现之前的字符串
-func CamelCase(s string) string //字符串转为cameCase, "foo bar" -> "fooBar"
-func Capitalize(s string) string //字符串转为Capitalize, "fOO" -> "Foo"
-func IsString(v interface{}) bool //判断是否是字符串
-func KebabCase(s string) string //字符串转为KebabCase, "foo_Bar" -> "foo-bar"
-func UpperFirst(s string) string //字符串的第一个字母转为大写字母
-func LowerFirst(s string) string //字符串的第一个字母转为小写字母
-func PadEnd(source string, size int, padStr string) string //字符串末尾填充size个字符
-func PadStart(source string, size int, padStr string) string//字符串开头填充size个字符
-func ReverseStr(s string) string //字符串逆序
-func Wrap(str string, wrapWith string) string //包裹字符串 Wrap("abc", "*") -> *abc*.
-func Unwrap(str string, wrapToken string) string //解包裹字符串 Wrap("*abc*", "*") -> abc.
-func SnakeCase(s string) string //字符串转为SnakeCase, "fooBar" -> "foo_bar"
-```
-
-### 12. system系统包
-
-- 包含一些操作系统,运行时,shell命令执行的函数.
-- Usage: import "github.com/duke-git/lancet/system".
-
-```go
-package main
-
-import (
- "fmt"
- "io/ioutil"
- "log"
- "github.com/duke-git/lancet/system"
-)
-
-func main() {
- envFoo := system.GetOsEnv("foo")
- fmt.Println(envFoo)
-}
-```
-
-- Function list:
-
-```go
-func IsWindows() bool //判断操作系统是windows
-func IsLinux() bool //判断操作系统是linux
-func IsMac() bool //判断操作系统是macos
-func GetOsEnv(key string) string //获取名称为key的环境变量
-func SetOsEnv(key, value string) error //设置环境变量
-func RemoveOsEnv(key string) error //删除指定key的环境变量
-func CompareOsEnv(key, comparedEnv string) bool //获取名称为key的环境变量并和comparedEnv比较
-func ExecCommand(command string) (stdout, stderr string, err error) //执行shell命令(/bin/bash)
-```
-
-### 13. validator验证器包
-
-- 数据校验相关函数
-- 导入包:import "github.com/duke-git/lancet/validator"
-
-```go
-package main
-
-import (
- "fmt"
- "io/ioutil"
- "log"
- "github.com/duke-git/lancet/validator"
-)
-
-func main() {
- str := "Foo-Bar"
- isAlpha := validator.IsAlpha(str)
- fmt.Println(isAlpha) //false
-}
-```
-
-- 函数列表:
-
-```go
-func ContainChinese(s string) bool //判断字符串中是否含有中文字符
-func IsAlpha(s string) bool //判断字符串是否只含有字母
-func IsBase64(base64 string) bool //判断字符串是base64
-func IsAllUpper(str string) bool //断字符串是否全是大写字母
-func IsAllLower(str string) bool //断字符串是否全是小写字母
-func ContainUpper(str string) bool //判断字符串是否包含大写字母
-func ContainLower(str string) bool //判断字符串是否包含小写字母
-func ContainLetter(str string) bool //判断字符串是否包含字母
-func IsJSON(str string) bool //判断字符串是否是JSON
-func IsChineseMobile(mobileNum string) bool //判断字符串是否是手机号
-func IsChineseIdNum(id string) bool //判断字符串是否是身份证号
-func IsChinesePhone(phone string) bool //判断字符串是否是座机电话号码
-func IsCreditCard(creditCart string) bool //判断字符串是否是信用卡
-func IsDns(dns string) bool //判断字符串是否是DNS
-func IsEmail(email string) bool //判断字符串是否是邮箱
-func IsEmptyString(s string) bool //判断字符串是否为空
-func IsFloatStr(s string) bool //判断字符串是否可以转成float
-func IsNumberStr(s string) bool //判断字符串是否可以转成数字
-func IsRegexMatch(s, regex string) bool //判断字符串是否match正则表达式
-func IsIntStr(s string) bool //判断字符串是否可以转成整数
-func IsIp(ipstr string) bool //判断字符串是否是ip
-func IsIpV4(ipstr string) bool //判断字符串是否是ipv4
-func IsIpV6(ipstr string) bool //判断字符串是否是ipv6
-func IsStrongPassword(password string, length int) bool //判断字符串是否是强密码(大小写字母+数字+特殊字符)
-func IsUrl(str string) bool //判断字符串是否是url
-func IsWeakPassword(password string) bool //判断字符串是否是弱密码(只有字母或数字)
-```
+- [ContainChinese](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#ContainChinese)
+- [ContainLetter](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#ContainLetter)
+- [ContainLower](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#ContainLower)
+- [ContainUpper](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#ContainUpper)
+- [IsAlpha](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsAlpha)
+- [IsAllUpper](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsAllUpper)
+- [IsAllLower](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsAllLower)
+- [IsBase64](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsBase64)
+- [IsChineseMobile](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsChineseMobile)
+- [IsChineseIdNum](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsChineseIdNum)
+- [IsChinesePhone](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsChinesePhone)
+- [IsCreditCard](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsCreditCard)
+- [IsDns](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsDns)
+- [IsEmail](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsEmail)
+- [IsEmptyString](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsEmptyString)
+- [IsFloatStr](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsFloatStr)
+- [IsNumberStr](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsNumberStr)
+- [IsJSON](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsJSON)
+- [IsRegexMatch](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsRegexMatch)
+- [IsIntStr](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsIntStr)
+- [IsIp](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsIp)
+- [IsIpV4](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsIpV4)
+- [IsIpV6](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsIpV6)
+- [IsStrongPassword](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsStrongPassword)
+- [IsUrl](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsUrl)
+- [IsWeakPassword](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsWeakPassword)
\ No newline at end of file
diff --git a/docs/cryptor_zh-CN.md b/docs/cryptor_zh-CN.md
index bd52a26..6847bcb 100644
--- a/docs/cryptor_zh-CN.md
+++ b/docs/cryptor_zh-CN.md
@@ -22,45 +22,32 @@ import (
## 目录
+- [AesEcbEncrypt](#AesEcbEncrypt)
+- [AesEcbDecrypt](#AesEcbDecrypt)
+- [AesCbcEncrypt](#AesCbcEncrypt)
+- [AesCbcDecrypt](#AesCbcDecrypt)
+- [AesCtrCrypt](#AesCtrCrypt)
+- [AesCfbEncrypt](#AesCfbEncrypt)
+- [AesCfbDecrypt](#AesCfbDecrypt)
+- [AesOfbEncrypt](#AesOfbEncrypt)
+- [AesOfbDecrypt](#AesOfbDecrypt)
+- [Base64StdEncode](#Base64StdEncode)
+- [Base64StdDecode](#Base64StdDecode)
-- [Cryptor](#cryptor)
- - [源码:](#源码)
- - [用法:](#用法)
- - [目录](#目录)
- - [文档](#文档)
- - [AesEcbEncrypt](#aesecbencrypt)
- - [AesEcbDecrypt](#aesecbdecrypt)
- - [AesCbcEncrypt](#aescbcencrypt)
- - [AesCbcDecrypt](#aescbcdecrypt)
- - [AesCtrCrypt](#aesctrcrypt)
- - [AesCfbEncrypt](#aescfbencrypt)
- - [AesCfbDecrypt](#aescfbdecrypt)
- - [AesOfbEncrypt](#aesofbencrypt)
- - [AesOfbDecrypt](#aesofbdecrypt)
- - [Base64StdEncode](#base64stdencode)
- - [Base64StdDecode](#base64stddecode)
- - [DesEcbEncrypt](#desecbencrypt)
- - [DesEcbDecrypt](#desecbdecrypt)
- - [DesCbcEncrypt](#descbcencrypt)
- - [DesCbcDecrypt](#descbcdecrypt)
- - [DesCtrCrypt](#desctrcrypt)
- - [DesCfbEncrypt](#descfbencrypt)
- - [DesCfbDecrypt](#descfbdecrypt)
- - [DesOfbEncrypt](#desofbencrypt)
- - [DesOfbDecrypt](#desofbdecrypt)
- - [HmacMd5](#hmacmd5)
- - [HmacSha1](#hmacsha1)
- - [HmacSha256](#hmacsha256)
- - [HmacSha512](#hmacsha512)
- - [Md5String](#md5string)
- - [Md5File](#md5file)
- - [Sha1](#sha1)
- - [Sha256](#sha256)
- - [Sha512](#sha512)
- - [GenerateRsaKey](#generatersakey)
- - [RsaEncrypt](#rsaencrypt)
- - [RsaDecrypt](#rsadecrypt)
+- [DesEcbEncrypt](#DesEcbEncrypt)
+- [DesEcbDecrypt](#DesEcbDecrypt)
+- [DesCbcEncrypt](#DesCbcEncrypt)
+- [DesCbcDecrypt](#DesCbcDecrypt)
+- [DesCtrCrypt](#DesCtrCrypt)
+- [DesCfbEncrypt](#DesCfbEncrypt)
+- [DesCfbDecrypt](#DesCfbDecrypt)
+- [DesOfbEncrypt](#DesOfbEncrypt)
+- [DesOfbDecrypt](#DesOfbDecrypt)
+- [HmacMd5](#HmacMd5)
+- [HmacSha1](#HmacSha1)
+- [HmacSha256](#HmacSha256)
+- [HmacSha512](#HmacSha512)
- [Md5String](#Md5String)
- [Md5File](#Md5File)
- [Sha1](#Sha1)
From 1dd826f05006c52b3aa588074edab1e7d94d6f0d Mon Sep 17 00:00:00 2001
From: dudaodong
Date: Tue, 8 Feb 2022 14:43:57 +0800
Subject: [PATCH 25/34] add logo png and update readme file
---
README.md | 18 ++++++++++++------
README_zh-CN.md | 14 ++++++++++----
logo.png | Bin 0 -> 64830 bytes
3 files changed, 22 insertions(+), 10 deletions(-)
create mode 100644 logo.png
diff --git a/README.md b/README.md
index fca3a7b..058458b 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
-# Lancet
-
- Lancet is a comprehensive, efficient, and reusable util function library of go. Inspired by the java apache common package and lodash.js.
-
+
+

+
+

[](https://github.com/duke-git/lancet/releases)
@@ -11,14 +11,20 @@
[](https://codecov.io/gh/duke-git/lancet)
[](https://github.com/duke-git/lancet/blob/main/LICENSE)
+
+
+
+
+
+ Lancet is a comprehensive, efficient, and reusable util function library of go. Inspired by the java apache common package and lodash.js.
+
English | [简体中文](./README_zh-CN.md)
-
## Feature
- 👏 Comprehensive, efficient and reusable.
-- 💪 160+ common go util functions, support string, slice, datetime, net, crypt...
+- 💪 170+ common go util functions, support string, slice, datetime, net, crypt...
- 💅 Only depend on the go standard library.
- 🌍 Unit test for every exported function.
diff --git a/README_zh-CN.md b/README_zh-CN.md
index 2628885..cc567e7 100644
--- a/README_zh-CN.md
+++ b/README_zh-CN.md
@@ -1,7 +1,7 @@
-# Lancet
-
- lancet(柳叶刀)是一个全面、高效、可复用的go语言工具函数库。 lancet受到了java apache common包和lodash.js的启发。
-
+
+

+
+

[](https://github.com/duke-git/lancet/releases)
@@ -11,6 +11,12 @@
[](https://codecov.io/gh/duke-git/lancet)
[](https://github.com/duke-git/lancet/blob/main/LICENSE)
+
+
+
+
+ lancet(柳叶刀)是一个全面、高效、可复用的go语言工具函数库。 lancet受到了java apache common包和lodash.js的启发。
+
简体中文 | [English](./README.md)
diff --git a/logo.png b/logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..19fad302a065f484eca667059d3e0e5205373f5f
GIT binary patch
literal 64830
zcmX_m19W9guyt(Pn%K6jiEU1jiLD#knAo0Z;!JFNqKR$YSQGs>-}~RYz0Nwl&ON-_H6g)oOuA_pL%0mur_>g*;3vfM}$>jK;^E})X0JDB@qDm&x
zKnyf+&f{bj%;00DN|p0LL3>hyo$KZKbqa3U!
z??wnDNS#Ri22pSgcAELzsW@7E4Q+dHF^E=Zn^T2Jw?)7GYr)kEA1*
zhZI@pGVygfrG$9Z1%h1?bYoplFqLQ(lBDt`nK*BD?rKsK(ewVJa7l4HBpV;CcOvTv;u_AxnNXgBj*@~VsPQ)i@ti;lzH59|zmE7=3y=tM2zz^>9$@?>k
zND$!sY+#vAMc$9G$ByQmr3bJoXP^~Uqk3eGTqKYl1{-2W>PA5dLaelw2N^sCC#qNi
zmlc9|*^GwfzlxwSS=`O*4(8=_J;mV3pqk+++elwAF`G~|b+7knR
z!lVFCM4mPf(l!S1_Yx3&j&d`m(ww?F9ymkm<8Uv#V+40dgdc
zc>4CciZkrM?@$-UIe9jetMF5fvlSrUL{xlFdN*fsA{;#lg57&hBxc`3T8HD^0scWn
zL=DXoDoFbkt*?rGhz9Jjyc*b0SxGV+rPa+RlKf4`uRb6)V4f(YdPaIy9Lwcbw|U-|
zRQSFkqLGjKGFq6njB$?Ufg%uP*h^5)-#e&ea=&bOo&kYcQ)Bg3W!tN75FogcD07Dz
zV34XTMPOAsUtpz
zdFd5XfhFjZbHXuz(C+){L|T*QafRR(gj#?rhK3<7aU4l*7OwLpK9XTK4vMT$77HVy
zgv>^knnHSil+glQEjWdOFwtHX`v%bki!aJRR4=Jx)Vu`JI|d-lmJ)qhL|u-|4{C8Vpn7fS--;3!?B8;6M!ZN_K-Epn=%IQxW5bL?K
z1;-i8)|a%cu#Gm1&JI5hCl$)xuhfs;kKdZU3Qrm-NfBbLa2M>$7M3BEBWEDJF1fC3
zNAVjYAEQH#GMRiVX-+*!`MgksKT&S(yPj!R9TLguUCl;V^olOmJm*J`bDt+L-T
z7p<#Y&A8vYESMU&R?>+i4u4oBYA1Ro5{_z*UhEr1a}TBMD$5mEs2-}1({ZJ6q`;E=(+#JloC@zS{#mk
zOcj?*mH1itU;AGU_U#X{7kC#27nZBOO)St+J&BqwQ)ggc6db6DCW?6WP3P!
zjoneg3dRLJ8a>hBczH+SE
zxeb@QW&l}xOgl}722fBstYQfS@J8@wI5!;tE3IpT3zX}UW(}MBDRMvQ1~^AKC*0yr
zoaa$E+I0gnNA2QP;2T9Ud=zmwB6Oz(r_R}VxD!~@vmH4c*)E&wnq`}4o0c7~|0J88
z*k_uy4L7VbOpH%{k6mP}`d;Px*TUA(w(y?+%=Is+y`6osJveue#
zUGWO^>euF~rVdl(rpMnizqc#`7Qx-GoY43+cnzE-iG_%z;XXmze}D*YJQoHdpg|RN#1K1ICz)MO)8ebiMPXh{=3+h
zdZf4GGZ1%(bI85)Yx5$mqqw8juknQ#wS5FHVTfdk#8{|Hur!Y=kJw1d$i|4U%fa`|
zXT*o)R`^ol3jQJUZ2tImY-yfn=CR*k8$i#ozbUD87N13a{CGK|KI5pyq@7<2Tqh
zQN7;3fxks>MIB5mw||gLkoo_aF2H5<)xxo5IdiX5sN;N+y^{IO;>+DZ2ZacaN{3T&n!}=G%H!pQ4atd}c%|ZKk_=u5;UAMRg0wLeK6WQ+;fc@}M
z8dVh4x$eniz1loQy>_RC9atpTqC`X}sJXc0Vy@x
zm5zoNmt@z6qsoJ_0}|}B$i|_cKQojvg-bPeY3Y)izTW4ydwfslRBKlcAEh2Yy>;7>
zd9!TG1th&X`-}QZ`Oh?!*hG}sD&s2m2o9JI&*8Hm^dtD^Ma}F_+2vUZ+rC$iH0n0C
zOo<(q%-H1F@_Fv8KX~uldd&QsoXPvpFH|tK*?EB;LnOe-V$5l|Iw`u6T9hJ?nk!n1
zdBbtk4Q4@Sve7;L?e;e3IP|(3L&Z#GNoAaNoo4uIv#)$0a?doQv)Rz^I&_#in7W(V
zq6J;EYFKHgr}EG3K4Y=jHp4c0snb}%`y!0}v4QD~_H6%bb-Z}|Y)Su@aohU@%uaYV
zb|3Z&4}qgW`}H36dzo!^2=|g5+lpGl!L8QpUxBs$mPM^qjWl~2hncN+fXrOHtBCK1
zLG!$|)!1}x$6&{*$H;}S;en=R^N80>^!Fw`qm6pc{>`cv@rT7F-bK5$nPp=aFrq}#
zr@izhV+Z0`!DYbci^`Pg*#Kd}p9HKWie`@Q9jBr0_V;x6zhq=c?H#Ucd2gz2YdZ+0
z2pQr}i1nRwTmU=Q-I&lc?b(!Hb7?q~h3)g!0Uryk>O4vbLK`mBH@%P;2D1D(d8MiwNAYDb}Rvm*i0A_3K!}S@ebgB;&U0Uj>sJ%Qx!8d1Zj`W1{G)Q1Cu0w(~22KB%}moPZt|MjK8X~7`>dkz5x
z7GVPh_5a^d0^L7UdW3LyUX4eP<>wD
za%z-UU|^zPa*|>iUf}0l+OCFj$<%mcaKT{U5DSWZ8Wz+s74D_w8mXz7hKAqUfBp0w
zxAV07`*--z-g9c$E?_|TVL*6lIrieNdgXUkO-;?X{4YB7WVv6>Foj%VW<4`Pf)vw3
z&kKw#}$-jIs%%*X$
z+|m27SnvEen?&OIm>gEq?A)!tx}Nx)%BONmG%6II^#R2WSz{J^Dm#+s`(cvMvFy4s
zr5s+u+dRAIyVB)XFhLB&b2DENSAI8PhrLnJe1~C&ReFeRjg#rv(6;(#*hL%8@4VLr*B1ztj9
zuUNaj&oPfSVr*HgwBNLP=r|nU|E;$R@nDw2&71uWX@)3co@g}MT&ZVMaovJw+5h*J
zeP52$NUvoJYjsg2UKN62B3vzOwWIZ0k%-Cr1&ea@!gc%f%hU5a5@|Bm?nU
zs=>gd88H~!y1Z~(tDCDNeYQ&HV_o7)#2zsS
z7~oRcBAYBGZDrlw49TtN>zgqBVXR7{Gs=Lpvtsccg_IhmtD^ML^pY-_
zJ(@Tfq&p3g+_z`M$)Wrl$ds+0zTq1q8NFpm{XPY1Qsr5!LnfYw<_Mwwt!S1WRgr}O
z1Si*Q@r!e;Gxh_+y$Pu9eE>P(4hj5>TGv#_XTkWkf8RI^YkZ#?)`GB=FNw}v;|zQl
z2;VyETB7XeBlz2TF*%`w5FQJPLQJTE%>t34Z*ezuWd#>c`8_{ZjjN~LZ2wrTkMrPEe6tE}*a649L+rD*jweS!^ytAh;k?X+yDWXFnwsR8Lsggs$VPPU5Zgqpy!*e+YDbf%1ud|3(u7>2L3ZrB
zQrEO15+7?I{54Yq|As!=rh@6LmYb*wLY|D6Z8-*+#x6bf*2;R!_Hvk5gsj0CG(O~guz&3r1PSLJ{c*KSi-Mr(!s
zabs+Xe|69~K8}}l=^6^c@E?GbrfeR&-NEg*nXvIar=!R<1br>odUGKV3AGJ^uyQ!JR_&~(RGiv_
z{_C|1*Q6fjQ1l#6XA#FFKK(Z6D-tYpp@bd;8Xj|S?SO^`%{~4^`G$7=KX}P_YW>5nXS=`H5kb7HRmj2QtrL5FWeBuoeSwse{jfu
zZ^M`0m3yOq?OQ=6#cwE(31Fv$sYQw7Tj81G;|+%__E}Fe-{?h%LP(eZQRT{~HTt$j
zIB}5M8-(6;?rDC%V1@SQ$kdH>)Xz*UI-3%=&Axxl9NHq}m76>M
zV{j2ZX2Dxxl!OkOF+D2D>)neVYiQ)&H@=iK!^2*?LlE~jK3^<)t?)^@U+osW%&dV(
zW0uWkBZ4_-)ZVBFEWMr*U%99iwMclUXeawHQdNa@R+df$p@swUp@ziK#MssrnE5~EArGghBlpp+I4M!KmLB1;-6Q9Co
z^fhg39S=g8#I_rx?x|IJ=zun|QIVctF;y!)x8hxG|B8laWX9GA*953=DaTt_$t{Ox
zm)Kh^Rx#LqKISK)Xof#{-<3@Gg1lmhGAaG3?1Wo-ap~S@1A+q1r<-dL9fp{c4e&>_
zf9OiDLz<2fHPB8lxDUN)xq?kp;4>)5ko@6ygA0%}pGzh+eVCKeW`$WuYk5@J*rZdC
zCzA@+*g}6mYzZvvp_pdaQ|3;xl+1uYmO1eWGGNCTRaHND^l^xe&x`PMS8E`0z&+L|
z^=lUy>KIyjIWl+*^HsOJnL_fn;3spg=7;p2qwu^r=QPTQF2
zsGc2rtiu_fa@_lr<3-$}m$$O1@}L&dt=&Nu24p%Iml4?O*pUos~b
z1%Tkkt7=4DOAzJL*lSdY)_$aUR1g$PKGn>;MWv*P%bP^b#x=6_$#_-utH5Z>O8@7)
zC$h&6+`4p9@22P&yM$(sq<0dirACP~(aI<_ZhYZui}bMJEPW)C-4qR-iogS{Z%C6A
zF$R0~#mLmXDc2EJ*b$rwVi;~LY$mx(Mk^6ri7riw06f;?%&sQf&LACGx%>USwYrJ5
zT8EXMrHHST7mmht;kU^9;;Iya~0)t}G+;dxwCKy5NgV8d}F;tf>
zQFxJFxC4ha!5**SAJq7sHA#c~O4=Jo&L<47a8qJ_67l}!VuV5R6#X;Z6K!rn4!~Rl
zqii|`S0Pr#H#f*Za)>U(bF4t{6#IIu)?-TDg&0*csG2%r`rA_W23{-tEvRGMSf;T;X?6D+yhM-|&3|{nyBM;md3TxrVz7CmaZ=$6Er2lK|`0?9|3q
zoFE4yW44wC7f2rpM9HZaLu|x_9bOM!IR7PQ{A0^V3AYWWgtw$wne6FM86%s5wbWE~
zROJVCWiT&!oLsvw&lebXT&~7A1J#4t#~(oFt7}
z@?QymZDB?kQ3e+_M1HOJZ4E=s;Fp9nyh8@wN?|P6XD0A5@*
zOcf76Fy*+P+INW(`Wdjfb`t-Gh)-_^Yvxe0WCFU5ERn8`E*qabiKN#}P6sPw2{q01
zAeZ-KEC^!;!0Ea9^@>AYBO<_#*EwFPNG@nk}h!{
zeO0}nMJg+^uNB6pxa1taq)YL#Mw@2))seld8RBk~zRP3oQ%_=ki&`kX0wsT)ilT7j
zuF!u+xuD=su?cg?rC8XRl+C{~eKp(=oFbtGlpMzB_;w%kTe0VvD&+Y134VD-%A;{X
zJJj%x(bN(Iqd!AoXYR=SkFQn$xbLIeYu3FuXY(*bbMgvnu7UsO
z=eU?)l-YH3INWYI*4aAPH2nuL4m43X`JkYMW#`yqW`EE#M=4nwQ6^-_a&bLr@QuVd
z$|bNTc4LRSY*sJAI8|I#6mbcOY1BGFy%Ss$Jlf%TnHVvfY+swn!HMOUz2})Wr>Tqo
zx?f1w7h}`@c1#@mBXS{M+pO>2I~O3DFLUpl0SgijUhmx>IS{`
z^1hAcrZJ2o-$T(8(8`PNv=b3chFNq|ae`3l*4K
zEcK;Hq>XlpwgJ-!7dU2Y0n7p(_uMalKT)fl81!*Q{iC_ime=`j@KaWL|71K-C0Vmg
zG0}4|ffs5CcVuTJ)?t*4RwAp`>99wMdf9AfKDNNN7jhD8?3O({*rg_
zUgFXBk|jtuuzc&2TOF4)E+i{C;od||17UTt$&p)vaF&iO;$xQ%RzP}0b?Cq|JLD%h
zBYD9$8$nHzpYyL>ZVrS#frW=!hZoNcjeR5CgKi3i5<=e$8w^yi6^>ha<K`n$FKjYdbRmmyh#{2%;
z=tI>A`(W%g7tWekm>l9mn|6H_V7{KD1)GrK*11uN`QXppXJCJFJGS7QFHKH`(`@sx90Yg8C|$#FP<
zTm<6BbrtO9SPlA$To2(tD5bBcU0?^y_Y+cStqn#bQAFItSruDyQ2
za*m2!4hIyEB3nHR_ewFV$3+L
z!G25~bya{bhXT_fRzWmbti~L$WpN-%R3xmr4N*hM=>uMU#q;2EvspF_5)vWYNq|UM
zrdOo<(Y%D_nuzzK83v~41O~F=j!D*GtQj}5r`~@x{j`I-M@1N+BK$;
z_FH;}nQlO~|0jvP3D!Q-JoMe1ai1e?Ik#`!o1P1&CUM*SkXNFI#2g&%%z(kr-mlCT
zK_gcR94Xk3pVNO0v2N?}lBx1VXDHP&?HPV_&T-TUN!6~EIH}hC8=8mcOMIi^S0cC?
zk;#@0Nh8LTM%rK|xCiJ=TTajJO;i#p!kSg*k1KW+>F@j_Y?r1eXYK)VmK9+?X%2
z$O;N2R^0k>pbayBXRsrNeZ9Y&j9el{kP@wrRJ@Nv%w*LcIjLh3RfHmw=wYTnE-6d}
zC*XRU-4hoopjlI6hx~^Zj;XjGJK5JfF)fQ8f}Kf;}o2#Cs|3
z?!=gWatIl_;z3_qp&!V(duzch^lD^c*fZ-^CjFd?u+h@%58hfQEhIdTj)C-Wi##!l
zN&^btO87}U{h=dF4GYZF@C35e{$Za-$3jk$;kmW2hUhAJ|1I!A@~ZSDW@nbojY9&{
z8F|uhn$UiIn>%Lh3w}9Zr9|Z9PKD0Gl{FYV56#N1INFhbbV1RjWZFQ!>n1`R`ij)@eNj)n_<+n_Ky11=%a#(;%na0iVOi?OrmfO
z`+{X8j#Qki>)v_P)MxECS0n{7&
z9geu##4bM&urJYKqRn@%|I3<9K#h@<;v5{wXQ*I6_gzfZ?f{p>%V~$&2H6aJ{d(s7
z>}bk$!*Bq2$!g(F1S{f<_nCkGKMhBcfeh~%$ctlEJjY>-&Im*n4E92XNQ78M^Wq5z
z3rr!KSB1~aQ2LYPfStA}j0pa*eJZ8-H7j%^Kp8cn!$`MfP$)WYvS|3Z&T^<*vP3K<
z!9_pGPxl!Q(uReh^cO}CMf|KVDM839R#mmI3=2?gQ}bPD%SgJ%2(%f_T{#mc-5jvY
zyRmWhG(Hx^#vHNmYASP?y$h_SSZ#-$b$5XUB6!F;f0&RIEGD(l1To4q4KNS6NP@d6
zj_PB7-@`meeMpoAoCJCC6Lp01+VR{1iP2IEx#^m~cjsD8>;3EYlior(u^J6+|ORxA0
z_D^_NR!`z<&FWoZL!>3o+oCJ5=#qi`
zP~*+83GzLx;eN#PAzEs@`B8<}wo4HCACVBr_-7&2e-XZ<}M3euNOt{7F`w_I}|S
z&fa;v$5J#^dwZ9-JoQjwA8qY+^Z`VdD95ShyjN_-dKJz#f^X!7I+ztn8WD@=X13B@
zN1O^ty2%nfNLRD_KoPzJjJ7SW@_6gs#y~^#DcS?xWC%tSeW36=hMcUC6cjR~9kzo3+^*JGlDZQKAfbloZw4vdVM5eEeZ>1YZlufaIYR{hf!$Z7O
z2&}GS&?d4IdAe_f86L3gF7!4}WUptWsKS;u32HfnPu50L(LxnQIlG1b_;(Cz@WCaX
zv_Y|O`bFpqFjt6p*=>d8sN|&_0J5VPpNc|dH<_6TX|A)V
z^VCcTo}>eA)dV+Qjx{&jLivNTv&4qVwADb0oV18D(040LMP?wVodlEo)JC4LLxHBa>a816awvq>t=9}!CDvI^VCVWSDVXD
zIzWNzSd%l<(n}e-qrgPz3h5P0$_3okZ$83LG6?$lo^j2f^hkeGCy_#Mu+cw$zuCdA
z$vyH1Gl5i#lD?YZswv-IdP;$XQI4s&o>Qpb&m$!oHan-Hz4mdc!yhs&%l(YTQe!IroLsdw<-uUJZD>`<~hQU|S$wFB_k15#2`yUkI-6
zY#uxFHJN@vjRRg2_OX#jWb4Sku~FhYY_`b{6khOro?$wqgmC5MRb|9)+r{yqy8Xjp
ziqN+kg%+2m?EW1~_h1pd9NaH}nE|o@*aMRst=nPNp<&C|tW-BJ;pKl#DcTE7#Mnw`
z7bPSjSxhl^=QA#?Lyd?0G{{RhX{AqS@GhijFaLe{U`&(zillr#VbVU}=UqKwKU~Ye
zGE24A&>{B8BOyrD_xndaG8-c@z8m$^Nvy(-Lg4bPyfwx!ZEAn7zI(&_SwGW8ms#Hu}f2_>{%>c*pm20yK5C?rQ?*#?{x-$j#iAmL=U
z@chwlGtVc@Sk;OrahBeaf(RYkOdl~P>T$jle9?Z1RSJA+FeaAx*4X(#a_asMsIEAw
zuj;PD($^L0xJ67=FKIj-+CcqN2U}Y=L7R<*5TUTw%vgU*lnR>U_d%A<>dCRXOyc_C
zq5TQ)41aIJ7~E;I3Wrard}b#dLVdY%JfQYSBTS<1)z4Rs2VIoof5vQc_X9`q0AF8*MR1TB|B+W#29%b_lkU6;oQ#c@@!qR2NAmgcsj_S-+$)%
z&khXYehP$XopBREcHmZ(w<;8>IVq!Ak)S=$y`sNkrzDP~GO}`VAR+osWS?!gqV*=2
zVq@#yHV)OdT(1i$tV331Z>0Y7-htaNd!{@2YNLZ>Q^NkYLo}5v>veNXHOuqb+Ky5M+ZAl<$Om!PK6)CUk_;W(oplJyoS)ED(U)xC*v$9_5$T$
z@nOvrQJw`LX*?T-fBWeyEi3a8DUd+?5W;)oF6^loeS3$XkMzxR2+XtBRZLb#dk|ew
z?AogkR{aPVy!#e0AOuW%kZvKGNcV>MJcHPZfNUGN_G?Xb-eALHUXRTk^<_rxz~Re`
zQVeoJxDi5NJ%xkDJPbhdf)CHfjY1nT&m)(B8Js<3M*ZgVoX5>}#Fi~$L?8}88NbZr
zVgj;rv$&+D9z*O+LqXdbY#Tmn@?HKg`!mDHIb)_M6ke@2QZot|p@9|Hh|IcTqBu}F
z?B(KR%|6@Y8XZ^V34!!0)?SZ5<1{u5oa?Zjkdue%7uqu
z8ZNA0)@dKWo%AHa@Sw5%E2Xxz`!r;8pd!DW`C(0((&b0cVq<%xLfj$TbmbrU4BRl$
zWE=%&qf!e;HVVAoyj#|wVjj2!#r4bFgiSvccXAMQOswpihLqgo3od%q>WKSi(d_Yx
zG!q_`*$JWC)RiW6I7zT35lm%)gCxfAem=H3*vvK3i&M^Bdhz#{bb2)@e
zfI>lVjPBxULd2AgXsnv1KLbs3GLic7C8DPFg65yaQ$4BBILLH$BZ9W#iP@milqfoj
zgEi%m?vRVOM{NECORZkUL~U&Nc&u7uHM1^yfI2NWV-`JYScimHfshTWI$?cv7l&uM
z>z=3zho{~6)g)6tWF8^4ryy4d?ioKKHUWt+UlCe=*(nHIMFS7LM)+`u(~HJS`)7TV
z&lknv^AP-pi6-S_kfk8~Rd0!6?fxYgp5sVFEk=FINVpy~FxYsVNH2-ZD
zN{X$y{8BEwfpPukPs#ldJQ1&qo6{q2(j=hK7>oJU*3AZ;u`?IV1_vz`l_X;y|59
zVl|AM9-H>B>s9|q!mmbHj6w8Qq!AWK-lUp2;FHUBn{BJ%fueLRyrj?n(Yy1cvS{fz>`LJJqd
zz3=fmb`uChV?e!6mqKs7VuzR6?*Mp(8h_VXoI79?tG?_-b3+3kqhe-&C5s`iO1}$G
z(scCd)L-D8d3z2oUAEj{|MF{7i|NT7;*71Pi9kY2BnU(wb#Q?lotkv45_=UJ^ATP!
z*}}5L!CMp;Bou=K;0(gWq;Vl1cL#hexIcO056P=2ez=tPg0=zSd=z}Imui`PHF|ze
zctmZAf6HB^zBpL^tu1Es#3G_z}-(DCMA>qzwjd505qQn{+9;mZPJsJIfy4@`{Dp
zV0l;G3q*CbUV?W#sf4#vkG%6J%gsisWv6?x?9)^W
z?mFG1)wPgCI-kmCx=CYCK5hVp#e9-5O=C;U(Huzv4{KdDQmVext`bQiU3B{jcOFk-
zB^t(m+112pQ&Zj$2uMijo7w_qZg!@Hq07d7ab7W~K%2A@(d?O1MSnTr;IS
z%-qMixYdWYtAr=MzZ(fsOnMN3$xz9B7p#UsdRZSSF=zm-7aLk5obs;
zlsX9FOrA_wrSY1a)f-x`odq2R7)agUWevrD8?{{&iuKMtT4Hiw76Pw5-i9)OOwMl(*Ub4v7!YP<7m^HOP#@X4@xe
ze;zaU>ClWKi&J;;cdrnt`bom(svh|!(#PSJE(N{Hd()8rZ9d-$CQe^8km0e`t#)hn
zblPl_jvnp-Y$d3UB%+JZPr-xfIO~o)>4GGy8}m>AMg4g?uJ`*TY~9y~`zQyV#Ps7b
zqH6Dt^|f&Q+uFN-cuv)XT8;^it$xG