1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-02-08 14:42:27 +08:00

Compare commits

..

20 Commits

Author SHA1 Message Date
dudaodong
a74038466f release v1.3.7 2023-03-01 10:04:15 +08:00
dudaodong
02daa7f6cb doc: add new function docs 2023-02-28 15:09:05 +08:00
dudaodong
fef6fd7b9d fix: fix issue #75 2023-02-23 11:51:26 +08:00
dudaodong
f6cd98086f doc: add doc for Pipeline function 2023-02-23 10:52:07 +08:00
dudaodong
24eb2bbacd doc: format all markdown doc 2023-02-23 10:36:54 +08:00
dudaodong
15c1537bf0 doc: add doc for SplitWords and WordCount 2023-02-23 10:23:38 +08:00
dudaodong
c02654559a doc: add pad function 2023-02-23 10:19:05 +08:00
dudaodong
634ca09e8c feat: add CopyProperties for merge properties between structs 2023-02-20 14:03:02 +08:00
dudaodong
f2e743dcf4 release v1.3.6 2023-02-16 11:56:11 +08:00
dudaodong
f8f58cae10 doc: add doc for DeepClone function 2023-02-16 11:53:28 +08:00
dudaodong
215b79140d feat: add DeepClone 2023-02-16 11:50:11 +08:00
dudaodong
0bd675340f fix: fix AesEcbEncrypt failed with key lenght is 24 or 32 2023-02-16 11:45:08 +08:00
dudaodong
f3d73899b1 release v1.3.5 2022-12-15 16:36:15 +08:00
dudaodong
d4a20b239a add new function 2022-12-15 16:35:33 +08:00
dudaodong
4c28431451 fix: fix lint issue 2022-12-15 16:31:04 +08:00
dudaodong
168ed096c7 fix: fix ExecCommand bug forwindows 2022-12-15 16:29:36 +08:00
dudaodong
a060769635 clean code 2022-12-15 16:27:21 +08:00
dudaodong
0a99492cf6 feat: add IsGBK 2022-12-15 16:21:09 +08:00
dudaodong
fb3de03f37 clean document 2022-12-15 16:13:32 +08:00
dudaodong
43c2fd2a22 feat: add UpperKebabCase/UpperSnakeCase 2022-12-15 16:05:02 +08:00
47 changed files with 5503 additions and 4140 deletions

View File

@@ -4,7 +4,7 @@
<br/> <br/>
![Go version](https://img.shields.io/badge/go-v1.16-9cf) ![Go version](https://img.shields.io/badge/go-v1.16-9cf)
[![Release](https://img.shields.io/badge/release-1.3.4-green.svg)](https://github.com/duke-git/lancet/releases) [![Release](https://img.shields.io/badge/release-1.3.7-green.svg)](https://github.com/duke-git/lancet/releases)
[![GoDoc](https://godoc.org/github.com//duke-git/lancet?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet) [![GoDoc](https://godoc.org/github.com//duke-git/lancet?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet)
[![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet)](https://goreportcard.com/report/github.com/duke-git/lancet) [![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet)](https://goreportcard.com/report/github.com/duke-git/lancet)
[![test](https://github.com/duke-git/lancet/actions/workflows/codecov.yml/badge.svg?branch=main&event=push)](https://github.com/duke-git/lancet/actions/workflows/codecov.yml) [![test](https://github.com/duke-git/lancet/actions/workflows/codecov.yml/badge.svg?branch=main&event=push)](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
@@ -83,6 +83,8 @@ import "github.com/duke-git/lancet/convertor"
- [StructToMap](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#StructToMap) - [StructToMap](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#StructToMap)
- [EncodeByte](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#EncodeByte) - [EncodeByte](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#EncodeByte)
- [DecodeByte](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#DecodeByte) - [DecodeByte](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#DecodeByte)
- [DeepClone](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#DeepClone)
- [CopyProperties](https://github.com/duke-git/lancet/blob/v1/docs/convertor.md#CopyProperties)
### 2. Cryptor package is for data encryption and decryption. ### 2. Cryptor package is for data encryption and decryption.
@@ -212,6 +214,8 @@ import "github.com/duke-git/lancet/function"
- [Compose](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Compose) - [Compose](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Compose)
- [Debounced](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Debounced) - [Debounced](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Debounced)
- [Delay](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Delay) - [Delay](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Delay)
- [Pipeline](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Pipeline)
- [Schedule](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Schedule)
- [Watcher](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Watcher) - [Watcher](https://github.com/duke-git/lancet/blob/v1/docs/function.md#Watcher)
### 6. Mathutil package implements some functions for math calculation. ### 6. Mathutil package implements some functions for math calculation.
@@ -350,15 +354,20 @@ import "github.com/duke-git/lancet/strutil"
- [Capitalize](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Capitalize) - [Capitalize](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Capitalize)
- [IsString](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#IsString) - [IsString](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#IsString)
- [KebabCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#KebabCase) - [KebabCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#KebabCase)
- [UpperKebabCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#UpperKebabCase)
- [LowerFirst](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#LowerFirst) - [LowerFirst](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#LowerFirst)
- [UpperFirst](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#UpperFirst) - [UpperFirst](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#UpperFirst)
- [Pad](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Pad)
- [PadEnd](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#PadEnd) - [PadEnd](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#PadEnd)
- [PadStart](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#PadStart) - [PadStart](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#PadStart)
- [Reverse](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Reverse) - [Reverse](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Reverse)
- [SnakeCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#SnakeCase) - [SnakeCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#SnakeCase)
- [UpperSnakeCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#UpperSnakeCase)
- [SplitEx](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#SplitEx) - [SplitEx](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#SplitEx)
- [Wrap](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Wrap) - [Wrap](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Wrap)
- [Unwrap](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Unwrap) - [Unwrap](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Unwrap)
- [SplitWords](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#SplitWords)
- [WordCount](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#WordCount)
### 12. System package contain some functions about os, runtime, shell command. ### 12. System package contain some functions about os, runtime, shell command.
@@ -413,6 +422,7 @@ import "github.com/duke-git/lancet/validator"
- [IsUrl](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsUrl) - [IsUrl](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsUrl)
- [IsWeakPassword](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsWeakPassword) - [IsWeakPassword](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsWeakPassword)
- [IsZeroValue](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsZeroValue) - [IsZeroValue](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsZeroValue)
- [IsGBK](https://github.com/duke-git/lancet/blob/v1/docs/validator.md#IsGBK)
## How to Contribute ## How to Contribute

View File

@@ -4,7 +4,7 @@
<br/> <br/>
![Go version](https://img.shields.io/badge/go-v1.16-9cf) ![Go version](https://img.shields.io/badge/go-v1.16-9cf)
[![Release](https://img.shields.io/badge/release-1.3.4-green.svg)](https://github.com/duke-git/lancet/releases) [![Release](https://img.shields.io/badge/release-1.3.7-green.svg)](https://github.com/duke-git/lancet/releases)
[![GoDoc](https://godoc.org/github.com//duke-git/lancet?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet) [![GoDoc](https://godoc.org/github.com//duke-git/lancet?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet)
[![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet)](https://goreportcard.com/report/github.com/duke-git/lancet) [![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet)](https://goreportcard.com/report/github.com/duke-git/lancet)
[![test](https://github.com/duke-git/lancet/actions/workflows/codecov.yml/badge.svg?branch=main&event=push)](https://github.com/duke-git/lancet/actions/workflows/codecov.yml) [![test](https://github.com/duke-git/lancet/actions/workflows/codecov.yml/badge.svg?branch=main&event=push)](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
@@ -82,6 +82,8 @@ import "github.com/duke-git/lancet/convertor"
- [StructToMap](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#StructToMap) - [StructToMap](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#StructToMap)
- [EncodeByte](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#EncodeByte) - [EncodeByte](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#EncodeByte)
- [DecodeByte](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#DecodeByte) - [DecodeByte](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#DecodeByte)
- [DeepClone](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#DeepClone)
- [CopyProperties](https://github.com/duke-git/lancet/blob/v1/docs/convertor_zh-CN.md#CopyProperties)
### 2. cryptor 加密包支持数据加密和解密,获取 md5hash 值。支持 base64, md5, hmac, aes, des, rsa。 ### 2. cryptor 加密包支持数据加密和解密,获取 md5hash 值。支持 base64, md5, hmac, aes, des, rsa。
@@ -211,6 +213,8 @@ import "github.com/duke-git/lancet/function"
- [Compose](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Compose) - [Compose](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Compose)
- [Debounced](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Debounced) - [Debounced](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Debounced)
- [Delay](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Delay) - [Delay](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Delay)
- [Pipeline](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Pipeline)
- [Schedule](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Schedule)
- [Watcher](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Watcher) - [Watcher](https://github.com/duke-git/lancet/blob/v1/docs/function_zh-CN.md#Watcher)
### 6. mathutil 包实现了一些数学计算的函数。 ### 6. mathutil 包实现了一些数学计算的函数。
@@ -349,15 +353,20 @@ import "github.com/duke-git/lancet/strutil"
- [Capitalize](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Capitalize) - [Capitalize](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Capitalize)
- [IsString](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#IsString) - [IsString](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#IsString)
- [KebabCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#KebabCase) - [KebabCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#KebabCase)
- [UpperKebabCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#UpperKebabCase)
- [LowerFirst](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#LowerFirst) - [LowerFirst](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#LowerFirst)
- [UpperFirst](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#UpperFirst) - [UpperFirst](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#UpperFirst)
- [Pad](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Pad)
- [PadEnd](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#PadEnd) - [PadEnd](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#PadEnd)
- [PadStart](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#PadStart) - [PadStart](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#PadStart)
- [Reverse](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Reverse) - [Reverse](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Reverse)
- [SnakeCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#SnakeCase) - [SnakeCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#SnakeCase)
- [UpperSnakeCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#UpperSnakeCase)
- [SplitEx](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#SplitEx) - [SplitEx](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#SplitEx)
- [Wrap](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Wrap) - [Wrap](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Wrap)
- [Unwrap](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Unwrap) - [Unwrap](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Unwrap)
- [SplitWords](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#SplitWords)
- [WordCount](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#WordCount)
### 13. system 包含 os, runtime, shell command 相关函数。 ### 13. system 包含 os, runtime, shell command 相关函数。
@@ -412,6 +421,7 @@ import "github.com/duke-git/lancet/validator"
- [IsUrl](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsUrl) - [IsUrl](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsUrl)
- [IsWeakPassword](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsWeakPassword) - [IsWeakPassword](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsWeakPassword)
- [IsZeroValue](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsZeroValue) - [IsZeroValue](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsZeroValue)
- [IsGBK](https://github.com/duke-git/lancet/blob/v1/docs/validator_zh-CN.md#IsGBK)
## 如何贡献代码 ## 如何贡献代码

View File

@@ -9,6 +9,7 @@ import (
"encoding/binary" "encoding/binary"
"encoding/gob" "encoding/gob"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"math" "math"
"reflect" "reflect"
@@ -262,3 +263,59 @@ func DecodeByte(data []byte, target interface{}) error {
decoder := gob.NewDecoder(buffer) decoder := gob.NewDecoder(buffer)
return decoder.Decode(target) return decoder.Decode(target)
} }
// DeepClone creates a deep copy of passed item.
// can't clone unexported field of struct
func DeepClone(src interface{}) interface{} {
c := cloner{
ptrs: map[reflect.Type]map[uintptr]reflect.Value{},
}
result := c.clone(reflect.ValueOf(src))
if result.Kind() == reflect.Invalid {
return nil
}
return result.Interface()
}
// CopyProperties copies each field from the source into the destination. It recursively copies struct pointers and interfaces that contain struct pointers.
func CopyProperties(dst, src interface{}) (err error) {
defer func() {
if e := recover(); e != nil {
err = errors.New(fmt.Sprintf("%v", e))
}
}()
dstType, dstValue := reflect.TypeOf(dst), reflect.ValueOf(dst)
srcType, srcValue := reflect.TypeOf(src), reflect.ValueOf(src)
if dstType.Kind() != reflect.Ptr || dstType.Elem().Kind() != reflect.Struct {
return errors.New("CopyProperties: param dst should be struct pointer")
}
if srcType.Kind() == reflect.Ptr {
srcType, srcValue = srcType.Elem(), srcValue.Elem()
}
if srcType.Kind() != reflect.Struct {
return errors.New("CopyProperties: param src should be a struct or struct pointer")
}
dstType, dstValue = dstType.Elem(), dstValue.Elem()
propertyNums := dstType.NumField()
for i := 0; i < propertyNums; i++ {
property := dstType.Field(i)
propertyValue := srcValue.FieldByName(property.Name)
if !propertyValue.IsValid() || property.Type != propertyValue.Type() {
continue
}
if dstValue.Field(i).CanSet() {
dstValue.Field(i).Set(propertyValue)
}
}
return nil
}

View File

@@ -0,0 +1,216 @@
// Copyright 2023 dudaodong@gmail.com. All rights reserved.
// Use of this source code is governed by MIT license
// Package convertor implements some functions to convert data.
package convertor
import "reflect"
type cloner struct {
ptrs map[reflect.Type]map[uintptr]reflect.Value
}
// clone return a duplicate of passed item.
func (c *cloner) clone(v reflect.Value) reflect.Value {
switch v.Kind() {
case reflect.Invalid:
return reflect.ValueOf(nil)
// bool
case reflect.Bool:
return reflect.ValueOf(v.Bool())
//int
case reflect.Int:
return reflect.ValueOf(int(v.Int()))
case reflect.Int8:
return reflect.ValueOf(int8(v.Int()))
case reflect.Int16:
return reflect.ValueOf(int16(v.Int()))
case reflect.Int32:
return reflect.ValueOf(int32(v.Int()))
case reflect.Int64:
return reflect.ValueOf(v.Int())
// uint
case reflect.Uint:
return reflect.ValueOf(uint(v.Uint()))
case reflect.Uint8:
return reflect.ValueOf(uint8(v.Uint()))
case reflect.Uint16:
return reflect.ValueOf(uint16(v.Uint()))
case reflect.Uint32:
return reflect.ValueOf(uint32(v.Uint()))
case reflect.Uint64:
return reflect.ValueOf(v.Uint())
// float
case reflect.Float32:
return reflect.ValueOf(float32(v.Float()))
case reflect.Float64:
return reflect.ValueOf(v.Float())
// complex
case reflect.Complex64:
return reflect.ValueOf(complex64(v.Complex()))
case reflect.Complex128:
return reflect.ValueOf(v.Complex())
// string
case reflect.String:
return reflect.ValueOf(v.String())
// array
case reflect.Array, reflect.Slice:
return c.cloneArray(v)
// map
case reflect.Map:
return c.cloneMap(v)
// Ptr
case reflect.Ptr:
return c.clonePtr(v)
// struct
case reflect.Struct:
return c.cloneStruct(v)
// func
case reflect.Func:
return v
// interface
case reflect.Interface:
return c.clone(v.Elem())
}
return reflect.Zero(v.Type())
}
func (c *cloner) cloneArray(v reflect.Value) reflect.Value {
if v.IsNil() {
return reflect.Zero(v.Type())
}
arr := reflect.MakeSlice(v.Type(), v.Len(), v.Len())
for i := 0; i < v.Len(); i++ {
val := c.clone(v.Index(i))
if val.IsValid() {
continue
}
item := arr.Index(i)
if !item.CanSet() {
continue
}
item.Set(val.Convert(item.Type()))
}
return arr
}
func (c *cloner) cloneMap(v reflect.Value) reflect.Value {
if v.IsNil() {
return reflect.Zero(v.Type())
}
clonedMap := reflect.MakeMap(v.Type())
for _, key := range v.MapKeys() {
value := v.MapIndex(key)
clonedKey := c.clone(key)
clonedValue := c.clone(value)
if !isNillable(clonedKey) || !clonedKey.IsNil() {
clonedKey = clonedKey.Convert(key.Type())
}
if (!isNillable(clonedValue) || !clonedValue.IsNil()) && clonedValue.IsValid() {
clonedValue = clonedValue.Convert(value.Type())
}
if !clonedValue.IsValid() {
clonedValue = reflect.Zero(clonedMap.Type().Elem())
}
clonedMap.SetMapIndex(clonedKey, clonedValue)
}
return clonedMap
}
func isNillable(v reflect.Value) bool {
switch v.Kind() {
case reflect.Chan, reflect.Interface, reflect.Ptr, reflect.Func:
return true
}
return false
}
func (c *cloner) clonePtr(v reflect.Value) reflect.Value {
if v.IsNil() {
return reflect.Zero(v.Type())
}
var newVal reflect.Value
if v.Elem().CanAddr() {
ptrs, exists := c.ptrs[v.Type()]
if exists {
if newVal, exists := ptrs[v.Elem().UnsafeAddr()]; exists {
return newVal
}
}
}
newVal = c.clone(v.Elem())
if v.Elem().CanAddr() {
ptrs, exists := c.ptrs[v.Type()]
if exists {
if newVal, exists := ptrs[v.Elem().UnsafeAddr()]; exists {
return newVal
}
}
}
clonedPtr := reflect.New(newVal.Type())
clonedPtr.Elem().Set(newVal)
return clonedPtr
}
func (c *cloner) cloneStruct(v reflect.Value) reflect.Value {
clonedStructPtr := reflect.New(v.Type())
clonedStruct := clonedStructPtr.Elem()
if v.CanAddr() {
ptrs := c.ptrs[clonedStructPtr.Type()]
if ptrs == nil {
ptrs = make(map[uintptr]reflect.Value)
c.ptrs[clonedStructPtr.Type()] = ptrs
}
ptrs[v.UnsafeAddr()] = clonedStructPtr
}
for i := 0; i < v.NumField(); i++ {
newStructValue := clonedStruct.Field(i)
if !newStructValue.CanSet() {
continue
}
clonedVal := c.clone(v.Field(i))
if !clonedVal.IsValid() {
continue
}
newStructValue.Set(clonedVal.Convert(newStructValue.Type()))
}
return clonedStruct
}

View File

@@ -2,6 +2,7 @@ package convertor
import ( import (
"fmt" "fmt"
"reflect"
"testing" "testing"
"github.com/duke-git/lancet/internal" "github.com/duke-git/lancet/internal"
@@ -213,3 +214,97 @@ func TestDecodeByte(t *testing.T) {
DecodeByte(byteData, &obj) DecodeByte(byteData, &obj)
assert.Equal("abc", obj) assert.Equal("abc", obj)
} }
func TestDeepClone(t *testing.T) {
// assert := internal.NewAssert(t, "TestDeepClone")
type Struct struct {
Str string
Int int
Float float64
Bool bool
Nil interface{}
unexported string
}
cases := []interface{}{
true,
1,
0.1,
map[string]int{
"a": 1,
"b": 2,
},
&Struct{
Str: "test",
Int: 1,
Float: 0.1,
Bool: true,
Nil: nil,
// unexported: "can't be cloned",
},
}
for i, item := range cases {
cloned := DeepClone(item)
t.Log(cloned)
if &cloned == &item {
t.Fatalf("[TestDeepClone case #%d failed]: equal pointer", i)
}
if !reflect.DeepEqual(item, cloned) {
t.Fatalf("[TestDeepClone case #%d failed] unequal objects", i)
}
}
}
func TestCopyProperties(t *testing.T) {
assert := internal.NewAssert(t, "TestCopyProperties")
type Address struct {
Country string
ZipCode string
}
type User struct {
Name string
Age int
Role string
Addr Address
Hobbys []string
salary int
}
type Employee struct {
Name string
Age int
Role string
Addr Address
Hobbys []string
salary int
}
user := User{Name: "user001", Age: 10, Role: "Admin", Addr: Address{Country: "CN", ZipCode: "001"}, Hobbys: []string{"a", "b"}, salary: 1000}
employee1 := Employee{}
err := CopyProperties(&employee1, &user)
assert.IsNil(err)
assert.Equal("user001", employee1.Name)
assert.Equal("Admin", employee1.Role)
assert.Equal("CN", employee1.Addr.Country)
assert.Equal(0, employee1.salary)
employee2 := Employee{Name: "employee001", Age: 20, Role: "User",
Addr: Address{Country: "UK", ZipCode: "002"}, salary: 500}
err = CopyProperties(&employee2, &user)
assert.IsNil(err)
assert.Equal("user001", employee2.Name)
assert.Equal("Admin", employee2.Role)
assert.Equal("CN", employee2.Addr.Country)
assert.Equal(500, employee2.salary)
}

View File

@@ -17,14 +17,23 @@ import (
// AesEcbEncrypt encrypt data with key use AES ECB algorithm // AesEcbEncrypt encrypt data with key use AES ECB algorithm
// len(key) should be 16, 24 or 32 // len(key) should be 16, 24 or 32
func AesEcbEncrypt(data, key []byte) []byte { func AesEcbEncrypt(data, key []byte) []byte {
cipher, _ := aes.NewCipher(generateAesKey(key)) size := len(key)
if size != 16 && size != 24 && size != 32 {
panic("key length shoud be 16 or 24 or 32")
}
cipher, _ := aes.NewCipher(generateAesKey(key, size))
length := (len(data) + aes.BlockSize) / aes.BlockSize length := (len(data) + aes.BlockSize) / aes.BlockSize
plain := make([]byte, length*aes.BlockSize) plain := make([]byte, length*aes.BlockSize)
copy(plain, data) copy(plain, data)
pad := byte(len(plain) - len(data)) pad := byte(len(plain) - len(data))
for i := len(data); i < len(plain); i++ { for i := len(data); i < len(plain); i++ {
plain[i] = pad plain[i] = pad
} }
encrypted := make([]byte, len(plain)) encrypted := make([]byte, len(plain))
for bs, be := 0, cipher.BlockSize(); bs <= len(data); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() { 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]) cipher.Encrypt(encrypted[bs:be], plain[bs:be])
@@ -36,9 +45,14 @@ func AesEcbEncrypt(data, key []byte) []byte {
// AesEcbDecrypt decrypt data with key use AES ECB algorithm // AesEcbDecrypt decrypt data with key use AES ECB algorithm
// len(key) should be 16, 24 or 32 // len(key) should be 16, 24 or 32
func AesEcbDecrypt(encrypted, key []byte) []byte { func AesEcbDecrypt(encrypted, key []byte) []byte {
cipher, _ := aes.NewCipher(generateAesKey(key)) size := len(key)
if size != 16 && size != 24 && size != 32 {
panic("key length shoud be 16 or 24 or 32")
}
cipher, _ := aes.NewCipher(generateAesKey(key, size))
decrypted := make([]byte, len(encrypted)) decrypted := make([]byte, len(encrypted))
//
for bs, be := 0, cipher.BlockSize(); bs < len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() { 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]) cipher.Decrypt(decrypted[bs:be], encrypted[bs:be])
} }

View File

@@ -2,15 +2,15 @@ package cryptor
import "bytes" import "bytes"
func generateAesKey(key []byte) []byte { func generateAesKey(key []byte, size int) []byte {
genKey := make([]byte, 16) aesKey := make([]byte, size)
copy(genKey, key) copy(aesKey, key)
for i := 16; i < len(key); { for i := size; i < len(key); {
for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 { for j := 0; j < size && i < len(key); j, i = j+1, i+1 {
genKey[j] ^= key[i] aesKey[j] ^= key[i]
} }
} }
return genKey return aesKey
} }
func generateDesKey(key []byte) []byte { func generateDesKey(key []byte) []byte {

View File

@@ -1,4 +1,5 @@
# Convertor # Convertor
Package convertor contains some functions for data type convertion. Package convertor contains some functions for data type convertion.
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -10,6 +11,7 @@ Package convertor contains some functions for data type convertion.
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/convertor" "github.com/duke-git/lancet/convertor"
@@ -19,26 +21,28 @@ import (
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Index ## Index
- [ColorHexToRGB](#ColorHexToRGB)
- [ColorRGBToHex](#ColorRGBToHex) - [ColorHexToRGB](#ColorHexToRGB)
- [ToBool](#ToBool) - [ColorRGBToHex](#ColorRGBToHex)
- [ToBytes](#ToBytes) - [ToBool](#ToBool)
- [ToChar](#ToChar) - [ToBytes](#ToBytes)
- [ToChannel](#ToChannel) - [ToChar](#ToChar)
- [ToInt](#ToInt) - [ToChannel](#ToChannel)
- [ToJson](#ToJson) - [ToFloat](#ToFloat)
- [ToString](#ToString) - [ToInt](#ToInt)
- [StructToMap](#StructToMap) - [ToJson](#ToJson)
- [EncodeByte](#EncodeByte) - [ToString](#ToString)
- [DecodeByte](#DecodeByte) - [StructToMap](#StructToMap)
- [EncodeByte](#EncodeByte)
- [DecodeByte](#DecodeByte)
- [DeepClone](#DeepClone)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Documentation ## Documentation
### <span id="ColorHexToRGB">ColorHexToRGB</span> ### <span id="ColorHexToRGB">ColorHexToRGB</span>
<p>Convert color hex to color rgb.</p> <p>Convert color hex to color rgb.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -46,6 +50,7 @@ import (
```go ```go
func ColorHexToRGB(colorHex string) (red, green, blue int) func ColorHexToRGB(colorHex string) (red, green, blue int)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -63,8 +68,6 @@ func main() {
} }
``` ```
### <span id="ColorRGBToHex">ColorRGBToHex</span> ### <span id="ColorRGBToHex">ColorRGBToHex</span>
<p>Convert color rgb to color hex.</p> <p>Convert color rgb to color hex.</p>
@@ -74,6 +77,7 @@ func main() {
```go ```go
func ColorRGBToHex(red, green, blue int) string func ColorRGBToHex(red, green, blue int) string
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -94,8 +98,6 @@ func main() {
} }
``` ```
### <span id="ToBool">ToBool</span> ### <span id="ToBool">ToBool</span>
<p>Convert string to a boolean value. Use strconv.ParseBool</p> <p>Convert string to a boolean value. Use strconv.ParseBool</p>
@@ -105,6 +107,7 @@ func main() {
```go ```go
func ToBool(s string) (bool, error) func ToBool(s string) (bool, error)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -130,8 +133,6 @@ func main() {
} }
``` ```
### <span id="ToBytes">ToBytes</span> ### <span id="ToBytes">ToBytes</span>
<p>Convert interface to byte slice.</p> <p>Convert interface to byte slice.</p>
@@ -141,6 +142,7 @@ func main() {
```go ```go
func ToBytes(data interface{}) ([]byte, error) func ToBytes(data interface{}) ([]byte, error)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -160,8 +162,6 @@ func main() {
} }
``` ```
### <span id="ToChar">ToChar</span> ### <span id="ToChar">ToChar</span>
<p>Convert string to char slice.</p> <p>Convert string to char slice.</p>
@@ -171,6 +171,7 @@ func main() {
```go ```go
func ToChar(s string) []string func ToChar(s string) []string
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -193,7 +194,6 @@ func main() {
} }
``` ```
### <span id="ToChannel">ToChannel</span> ### <span id="ToChannel">ToChannel</span>
<p>Convert a collection of elements to a read-only channels.</p> <p>Convert a collection of elements to a read-only channels.</p>
@@ -203,6 +203,7 @@ func main() {
```go ```go
func ToChannel(array []interface{}) <-chan interface{} func ToChannel(array []interface{}) <-chan interface{}
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -230,8 +231,6 @@ func main() {
} }
``` ```
### <span id="ToFloat">ToFloat</span> ### <span id="ToFloat">ToFloat</span>
<p>Convert interface to a float64 value. If param is a invalid floatable, will return 0 and error. </p> <p>Convert interface to a float64 value. If param is a invalid floatable, will return 0 and error. </p>
@@ -241,6 +240,7 @@ func main() {
```go ```go
func ToFloat(value interface{}) (float64, error) func ToFloat(value interface{}) (float64, error)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -263,8 +263,6 @@ func main() {
} }
``` ```
### <span id="ToInt">ToInt</span> ### <span id="ToInt">ToInt</span>
<p>Convert interface to a int64 value. If param is a invalid intable, will return 0 and error. </p> <p>Convert interface to a int64 value. If param is a invalid intable, will return 0 and error. </p>
@@ -274,6 +272,7 @@ func main() {
```go ```go
func ToInt(value interface{}) (int64, error) func ToInt(value interface{}) (int64, error)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -296,8 +295,6 @@ func main() {
} }
``` ```
### <span id="ToJson">ToJson</span> ### <span id="ToJson">ToJson</span>
<p>Convert interface to json string. If param can't be converted, will return "" and error. </p> <p>Convert interface to json string. If param can't be converted, will return "" and error. </p>
@@ -307,6 +304,7 @@ func main() {
```go ```go
func ToJson(value interface{}) (string, error) func ToJson(value interface{}) (string, error)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -324,8 +322,6 @@ func main() {
} }
``` ```
### <span id="ToString">ToString</span> ### <span id="ToString">ToString</span>
<p>Convert interface to string. </p> <p>Convert interface to string. </p>
@@ -335,6 +331,7 @@ func main() {
```go ```go
func ToString(value interface{}) string func ToString(value interface{}) string
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -352,8 +349,6 @@ func main() {
} }
``` ```
### <span id="StructToMap">StructToMap</span> ### <span id="StructToMap">StructToMap</span>
<p>Convert struct to map, only convert exported field, struct field tag `json` should be set.</p> <p>Convert struct to map, only convert exported field, struct field tag `json` should be set.</p>
@@ -363,6 +358,7 @@ func main() {
```go ```go
func StructToMap(value interface{}) (map[string]interface{}, error) func StructToMap(value interface{}) (map[string]interface{}, error)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -388,7 +384,6 @@ func main() {
} }
``` ```
### <span id="EncodeByte">EncodeByte</span> ### <span id="EncodeByte">EncodeByte</span>
<p>Encode data to byte slice.</p> <p>Encode data to byte slice.</p>
@@ -398,6 +393,7 @@ func main() {
```go ```go
func EncodeByte(data any) ([]byte, error) func EncodeByte(data any) ([]byte, error)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -414,8 +410,6 @@ func main() {
} }
``` ```
### <span id="DecodeByte">DecodeByte</span> ### <span id="DecodeByte">DecodeByte</span>
<p>Decode byte data to target object. target should be a pointer instance.</p> <p>Decode byte data to target object. target should be a pointer instance.</p>
@@ -425,6 +419,7 @@ func main() {
```go ```go
func DecodeByte(data []byte, target any) error func DecodeByte(data []byte, target any) error
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -437,8 +432,72 @@ import (
func main() { func main() {
var result string var result string
byteData := []byte{6, 12, 0, 3, 97, 98, 99} byteData := []byte{6, 12, 0, 3, 97, 98, 99}
convertor.DecodeByte(byteData, &result) convertor.DecodeByte(byteData, &result)
fmt.Println(result) //"abc" fmt.Println(result) //"abc"
} }
``` ```
### <span id="DeepClone">DeepClone</span>
<p>Creates a deep copy of passed item, can't clone unexported field of struct.</p>
<b>Signature:</b>
```go
func DeepClone[T any](src T) T
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/convertor"
)
func main() {
type Struct struct {
Str string
Int int
Float float64
Bool bool
Nil interface{}
unexported string
}
cases := []interface{}{
true,
1,
0.1,
map[string]int{
"a": 1,
"b": 2,
},
&Struct{
Str: "test",
Int: 1,
Float: 0.1,
Bool: true,
Nil: nil,
// unexported: "can't be cloned",
},
}
for _, item := range cases {
cloned := convertor.DeepClone(item)
isPointerEqual := &cloned == &item
fmt.Println(cloned, isPointerEqual)
}
// Output:
// true false
// 1 false
// 0.1 false
// map[a:1 b:2] false
// &{test 1 0.1 true <nil> } false
}
```

View File

@@ -1,5 +1,6 @@
# Convertor # Convertor
convertor转换器包支持一些常见的数据类型转换
convertor 转换器包支持一些常见的数据类型转换
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -21,33 +22,27 @@ import (
## 目录 ## 目录
- [Convertor](#convertor) - [ColorHexToRGB](#ColorHexToRGB)
- [源码:](#源码) - [ColorRGBToHex](#ColorRGBToHex)
- [用法:](#用法) - [ToBool](#ToBool)
- [目录](#目录) - [ToBytes](#ToBytes)
- [文档](#文档) - [ToChar](#ToChar)
- [<span id="ColorHexToRGB">ColorHexToRGB</span>](#colorhextorgb) - [ToChannel](#ToChannel)
- [<span id="ColorRGBToHex">ColorRGBToHex</span>](#colorrgbtohex) - [ToFloat](#ToFloat)
- [<span id="ToBool">ToBool</span>](#tobool) - [ToInt](#ToInt)
- [<span id="ToBytes">ToBytes</span>](#tobytes) - [ToJson](#ToJson)
- [<span id="ToChar">ToChar</span>](#tochar) - [ToString](#ToString)
- [<span id="ToChannel">ToChannel</span>](#tochannel) - [StructToMap](#StructToMap)
- [<span id="ToFloat">ToFloat</span>](#tofloat) - [EncodeByte](#EncodeByte)
- [<span id="ToInt">ToInt</span>](#toint) - [DecodeByte](#DecodeByte)
- [<span id="ToJson">ToJson</span>](#tojson) - [DeepClone](#DeepClone)
- [<span id="ToString">ToString</span>](#tostring)
- [<span id="StructToMap">StructToMap</span>](#structtomap)
- [<span id="EncodeByte">EncodeByte</span>](#encodebyte)
- [<span id="DecodeByte">DecodeByte</span>](#decodebyte)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 文档 ## 文档
### <span id="ColorHexToRGB">ColorHexToRGB</span> ### <span id="ColorHexToRGB">ColorHexToRGB</span>
<p>颜色值十六进制转rgb</p> <p>颜色值十六进制转rgb</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -55,6 +50,7 @@ import (
```go ```go
func ColorHexToRGB(colorHex string) (red, green, blue int) func ColorHexToRGB(colorHex string) (red, green, blue int)
``` ```
<b>列子:</b> <b>列子:</b>
```go ```go
@@ -72,8 +68,6 @@ func main() {
} }
``` ```
### <span id="ColorRGBToHex">ColorRGBToHex</span> ### <span id="ColorRGBToHex">ColorRGBToHex</span>
<p>颜色值rgb转十六进制</p> <p>颜色值rgb转十六进制</p>
@@ -83,6 +77,7 @@ func main() {
```go ```go
func ColorRGBToHex(red, green, blue int) string func ColorRGBToHex(red, green, blue int) string
``` ```
<b>列子:</b> <b>列子:</b>
```go ```go
@@ -103,8 +98,6 @@ func main() {
} }
``` ```
### <span id="ToBool">ToBool</span> ### <span id="ToBool">ToBool</span>
<p>字符串转布尔类型使用strconv.ParseBool</p> <p>字符串转布尔类型使用strconv.ParseBool</p>
@@ -114,6 +107,7 @@ func main() {
```go ```go
func ToBool(s string) (bool, error) func ToBool(s string) (bool, error)
``` ```
<b>列子:</b> <b>列子:</b>
```go ```go
@@ -139,8 +133,6 @@ func main() {
} }
``` ```
### <span id="ToBytes">ToBytes</span> ### <span id="ToBytes">ToBytes</span>
<p>interface转字节切片.</p> <p>interface转字节切片.</p>
@@ -150,6 +142,7 @@ func main() {
```go ```go
func ToBytes(data interface{}) ([]byte, error) func ToBytes(data interface{}) ([]byte, error)
``` ```
<b>列子:</b> <b>列子:</b>
```go ```go
@@ -169,8 +162,6 @@ func main() {
} }
``` ```
### <span id="ToChar">ToChar</span> ### <span id="ToChar">ToChar</span>
<p>字符串转字符切片</p> <p>字符串转字符切片</p>
@@ -180,6 +171,7 @@ func main() {
```go ```go
func ToChar(s string) []string func ToChar(s string) []string
``` ```
<b>列子:</b> <b>列子:</b>
```go ```go
@@ -202,8 +194,6 @@ func main() {
} }
``` ```
### <span id="ToChannel">ToChannel</span> ### <span id="ToChannel">ToChannel</span>
<p>将切片转为只读channel</p> <p>将切片转为只读channel</p>
@@ -213,6 +203,7 @@ func main() {
```go ```go
func ToChannel(array []interface{}) <-chan interface{} func ToChannel(array []interface{}) <-chan interface{}
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -240,8 +231,6 @@ func main() {
} }
``` ```
### <span id="ToFloat">ToFloat</span> ### <span id="ToFloat">ToFloat</span>
<p>将interface转成float64类型如果参数无法转换会返回0和error</p> <p>将interface转成float64类型如果参数无法转换会返回0和error</p>
@@ -251,6 +240,7 @@ func main() {
```go ```go
func ToFloat(value interface{}) (float64, error) func ToFloat(value interface{}) (float64, error)
``` ```
<b>列子:</b> <b>列子:</b>
```go ```go
@@ -273,8 +263,6 @@ func main() {
} }
``` ```
### <span id="ToInt">ToInt</span> ### <span id="ToInt">ToInt</span>
<p>将interface转成intt64类型如果参数无法转换会返回0和error</p> <p>将interface转成intt64类型如果参数无法转换会返回0和error</p>
@@ -284,6 +272,7 @@ func main() {
```go ```go
func ToInt(value interface{}) (int64, error) func ToInt(value interface{}) (int64, error)
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -306,8 +295,6 @@ func main() {
} }
``` ```
### <span id="ToJson">ToJson</span> ### <span id="ToJson">ToJson</span>
<p>将interface转成json字符串如果参数无法转换会返回""和error</p> <p>将interface转成json字符串如果参数无法转换会返回""和error</p>
@@ -317,6 +304,7 @@ func main() {
```go ```go
func ToJson(value interface{}) (string, error) func ToJson(value interface{}) (string, error)
``` ```
<b>列子:</b> <b>列子:</b>
```go ```go
@@ -334,8 +322,6 @@ func main() {
} }
``` ```
### <span id="ToString">ToString</span> ### <span id="ToString">ToString</span>
<p>将interface转成字符串</p> <p>将interface转成字符串</p>
@@ -345,6 +331,7 @@ func main() {
```go ```go
func ToString(value interface{}) string func ToString(value interface{}) string
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -362,8 +349,6 @@ func main() {
} }
``` ```
### <span id="StructToMap">StructToMap</span> ### <span id="StructToMap">StructToMap</span>
<p>将struct转成map只会转换struct中可导出的字段。struct中导出字段需要设置json tag标记</p> <p>将struct转成map只会转换struct中可导出的字段。struct中导出字段需要设置json tag标记</p>
@@ -373,6 +358,7 @@ func main() {
```go ```go
func StructToMap(value interface{}) (map[string]interface{}, error) func StructToMap(value interface{}) (map[string]interface{}, error)
``` ```
<b>列子:</b> <b>列子:</b>
```go ```go
@@ -398,7 +384,6 @@ func main() {
} }
``` ```
### <span id="EncodeByte">EncodeByte</span> ### <span id="EncodeByte">EncodeByte</span>
<p>将data编码成字节切片</p> <p>将data编码成字节切片</p>
@@ -408,6 +393,7 @@ func main() {
```go ```go
func EncodeByte(data any) ([]byte, error) func EncodeByte(data any) ([]byte, error)
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -424,8 +410,6 @@ func main() {
} }
``` ```
### <span id="DecodeByte">DecodeByte</span> ### <span id="DecodeByte">DecodeByte</span>
<p>解码字节切片到目标对象,目标对象需要传入一个指针实例子</p> <p>解码字节切片到目标对象,目标对象需要传入一个指针实例子</p>
@@ -435,6 +419,7 @@ func main() {
```go ```go
func DecodeByte(data []byte, target any) error func DecodeByte(data []byte, target any) error
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -447,8 +432,72 @@ import (
func main() { func main() {
var result string var result string
byteData := []byte{6, 12, 0, 3, 97, 98, 99} byteData := []byte{6, 12, 0, 3, 97, 98, 99}
convertor.DecodeByte(byteData, &result) convertor.DecodeByte(byteData, &result)
fmt.Println(result) //"abc" fmt.Println(result) //"abc"
} }
``` ```
### <span id="DeepClone">DeepClone</span>
<p>创建一个传入值的深拷贝, 无法克隆结构体的非导出字段。</p>
<b>函数签名:</b>
```go
func DeepClone[T any](src T) T
```
<b>示例:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/convertor"
)
func main() {
type Struct struct {
Str string
Int int
Float float64
Bool bool
Nil interface{}
unexported string
}
cases := []interface{}{
true,
1,
0.1,
map[string]int{
"a": 1,
"b": 2,
},
&Struct{
Str: "test",
Int: 1,
Float: 0.1,
Bool: true,
Nil: nil,
// unexported: "can't be cloned",
},
}
for _, item := range cases {
cloned := convertor.DeepClone(item)
isPointerEqual := &cloned == &item
fmt.Println(cloned, isPointerEqual)
}
// Output:
// true false
// 1 false
// 0.1 false
// map[a:1 b:2] false
// &{test 1 0.1 true <nil> } false
}
```

View File

@@ -1,18 +1,20 @@
# Cryptor # Cryptor
Package cryptor contains some functions for data encryption and decryption. Support base64, md5, hmac, aes, des, rsa. Package cryptor contains some functions for data encryption and decryption. Support base64, md5, hmac, aes, des, rsa.
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Source: ## Source:
- [https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go](https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go](https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go)
- [https://github.com/duke-git/lancet/blob/v1/cryptor/des.go](https://github.com/duke-git/lancet/blob/v1/cryptor/des.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/des.go](https://github.com/duke-git/lancet/blob/v1/cryptor/des.go)
- [https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go](https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go](https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go)
- [https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/cryptor"
@@ -23,47 +25,43 @@ import (
## Index ## Index
- [AesEcbEncrypt](#AesEcbEncrypt) - [AesEcbEncrypt](#AesEcbEncrypt)
- [AesEcbDecrypt](#AesEcbDecrypt) - [AesEcbDecrypt](#AesEcbDecrypt)
- [AesCbcEncrypt](#AesCbcEncrypt) - [AesCbcEncrypt](#AesCbcEncrypt)
- [AesCbcDecrypt](#AesCbcDecrypt) - [AesCbcDecrypt](#AesCbcDecrypt)
- [AesCtrCrypt](#AesCtrCrypt) - [AesCtrCrypt](#AesCtrCrypt)
- [AesCfbEncrypt](#AesCfbEncrypt) - [AesCfbEncrypt](#AesCfbEncrypt)
- [AesCfbDecrypt](#AesCfbDecrypt) - [AesCfbDecrypt](#AesCfbDecrypt)
- [AesOfbEncrypt](#AesOfbEncrypt) - [AesOfbEncrypt](#AesOfbEncrypt)
- [AesOfbDecrypt](#AesOfbDecrypt) - [AesOfbDecrypt](#AesOfbDecrypt)
- [Base64StdEncode](#Base64StdEncode) - [Base64StdEncode](#Base64StdEncode)
- [Base64StdDecode](#Base64StdDecode) - [Base64StdDecode](#Base64StdDecode)
- [DesEcbEncrypt](#DesEcbEncrypt) - [DesEcbEncrypt](#DesEcbEncrypt)
- [DesEcbDecrypt](#DesEcbDecrypt) - [DesEcbDecrypt](#DesEcbDecrypt)
- [DesCbcEncrypt](#DesCbcEncrypt) - [DesCbcEncrypt](#DesCbcEncrypt)
- [DesCbcDecrypt](#DesCbcDecrypt) - [DesCbcDecrypt](#DesCbcDecrypt)
- [DesCtrCrypt](#DesCtrCrypt) - [DesCtrCrypt](#DesCtrCrypt)
- [DesCfbEncrypt](#DesCfbEncrypt) - [DesCfbEncrypt](#DesCfbEncrypt)
- [DesCfbDecrypt](#DesCfbDecrypt) - [DesCfbDecrypt](#DesCfbDecrypt)
- [DesOfbEncrypt](#DesOfbEncrypt) - [DesOfbEncrypt](#DesOfbEncrypt)
- [DesOfbDecrypt](#DesOfbDecrypt) - [DesOfbDecrypt](#DesOfbDecrypt)
- [HmacMd5](#HmacMd5) - [HmacMd5](#HmacMd5)
- [HmacSha1](#HmacSha1) - [HmacSha1](#HmacSha1)
- [HmacSha256](#HmacSha256) - [HmacSha256](#HmacSha256)
- [HmacSha512](#HmacSha512) - [HmacSha512](#HmacSha512)
- [Md5String](#Md5String)
- [Md5String](#Md5String) - [Md5File](#Md5File)
- [Md5File](#Md5File) - [Sha1](#Sha1)
- [Sha1](#Sha1) - [Sha256](#Sha256)
- [Sha256](#Sha256) - [Sha512](#Sha512)
- [Sha512](#Sha512) - [GenerateRsaKey](#GenerateRsaKey)
- [GenerateRsaKey](#GenerateRsaKey) - [RsaEncrypt](#RsaEncrypt)
- [RsaEncrypt](#RsaEncrypt) - [RsaDecrypt](#RsaDecrypt)
- [RsaDecrypt](#RsaDecrypt)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Documentation ## Documentation
### <span id="AesEcbEncrypt">AesEcbEncrypt</span> ### <span id="AesEcbEncrypt">AesEcbEncrypt</span>
<p>Encrypt data with key use AES ECB algorithm. Length of `key` param should be 16, 24 or 32.</p> <p>Encrypt data with key use AES ECB algorithm. Length of `key` param should be 16, 24 or 32.</p>
@@ -73,6 +71,7 @@ import (
```go ```go
func AesEcbEncrypt(data, key []byte) []byte func AesEcbEncrypt(data, key []byte) []byte
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -85,15 +84,13 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefghijklmnop" key := "abcdefghijklmnop"
encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key)) encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
fmt.Println(string(encrypted)) fmt.Println(string(encrypted))
} }
``` ```
### <span id="AesEcbDecrypt">AesEcbDecrypt</span> ### <span id="AesEcbDecrypt">AesEcbDecrypt</span>
<p>Decrypt data with key use AES ECB algorithm. Length of `key` param should be 16, 24 or 32.</p> <p>Decrypt data with key use AES ECB algorithm. Length of `key` param should be 16, 24 or 32.</p>
@@ -103,6 +100,7 @@ func main() {
```go ```go
func AesEcbDecrypt(encrypted, key []byte) []byte func AesEcbDecrypt(encrypted, key []byte) []byte
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -115,15 +113,13 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefghijklmnop" key := "abcdefghijklmnop"
encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key)) 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 fmt.Println(string(decrypted)) //hello world
} }
``` ```
### <span id="AesCbcEncrypt">AesCbcEncrypt</span> ### <span id="AesCbcEncrypt">AesCbcEncrypt</span>
<p>Encrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.</p> <p>Encrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.</p>
@@ -133,6 +129,7 @@ func main() {
```go ```go
func AesCbcEncrypt(data, key []byte) []byte func AesCbcEncrypt(data, key []byte) []byte
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -145,15 +142,13 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefghijklmnop" key := "abcdefghijklmnop"
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key)) encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
fmt.Println(string(encrypted)) fmt.Println(string(encrypted))
} }
``` ```
### <span id="AesCbcDecrypt">AesCbcDecrypt</span> ### <span id="AesCbcDecrypt">AesCbcDecrypt</span>
<p>Decrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.</p> <p>Decrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.</p>
@@ -176,15 +171,13 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefghijklmnop" key := "abcdefghijklmnop"
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key)) 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 fmt.Println(string(decrypted)) //hello world
} }
``` ```
### <span id="AesCtrCrypt">AesCtrCrypt</span> ### <span id="AesCtrCrypt">AesCtrCrypt</span>
<p>Encrypt or decrypt data with key use AES CTR algorithm. Length of `key` param should be 16, 24 or 32.</p> <p>Encrypt or decrypt data with key use AES CTR algorithm. Length of `key` param should be 16, 24 or 32.</p>
@@ -207,7 +200,7 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefghijklmnop" key := "abcdefghijklmnop"
encrypted := cryptor.AesCtrCrypt([]byte(data), []byte(key)) encrypted := cryptor.AesCtrCrypt([]byte(data), []byte(key))
decrypted := cryptor.AesCtrCrypt(encrypted, []byte(key)) decrypted := cryptor.AesCtrCrypt(encrypted, []byte(key))
@@ -215,8 +208,6 @@ func main() {
} }
``` ```
### <span id="AesCfbEncrypt">AesCfbEncrypt</span> ### <span id="AesCfbEncrypt">AesCfbEncrypt</span>
<p>Encrypt data with key use AES CFB algorithm. Length of `key` param should be 16, 24 or 32.</p> <p>Encrypt data with key use AES CFB algorithm. Length of `key` param should be 16, 24 or 32.</p>
@@ -239,14 +230,12 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefghijklmnop" key := "abcdefghijklmnop"
encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key)) encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key))
fmt.Println(string(encrypted)) fmt.Println(string(encrypted))
} }
``` ```
### <span id="AesCfbDecrypt">AesCfbDecrypt</span> ### <span id="AesCfbDecrypt">AesCfbDecrypt</span>
<p>Decrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.</p> <p>Decrypt data with key use AES CBC algorithm. Length of `key` param should be 16, 24 or 32.</p>
@@ -271,13 +260,11 @@ func main() {
data := "hello world" data := "hello world"
key := "abcdefghijklmnop" key := "abcdefghijklmnop"
encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key)) 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 fmt.Println(string(decrypted)) //hello world
} }
``` ```
### <span id="AesOfbEncrypt">AesOfbEncrypt</span> ### <span id="AesOfbEncrypt">AesOfbEncrypt</span>
<p>Enecrypt data with key use AES OFB algorithm. Length of `key` param should be 16, 24 or 32.</p> <p>Enecrypt data with key use AES OFB algorithm. Length of `key` param should be 16, 24 or 32.</p>
@@ -300,14 +287,12 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefghijklmnop" key := "abcdefghijklmnop"
encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key)) encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key))
fmt.Println(string(encrypted)) fmt.Println(string(encrypted))
} }
``` ```
### <span id="AesCfbDecrypt">AesOfbDecrypt</span> ### <span id="AesCfbDecrypt">AesOfbDecrypt</span>
<p>Decrypt data with key use AES OFB algorithm. Length of `key` param should be 16, 24 or 32.</p> <p>Decrypt data with key use AES OFB algorithm. Length of `key` param should be 16, 24 or 32.</p>
@@ -330,16 +315,14 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefghijklmnop" key := "abcdefghijklmnop"
encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key)) 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 fmt.Println(string(decrypted)) //hello world
} }
``` ```
### <span id="Base64StdEncode">Base64StdEncode</span> ### <span id="Base64StdEncode">Base64StdEncode</span>
<p>Encode string with base64 encoding.</p> <p>Encode string with base64 encoding.</p>
@@ -349,6 +332,7 @@ func main() {
```go ```go
func Base64StdEncode(s string) string func Base64StdEncode(s string) string
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -360,13 +344,11 @@ import (
) )
func main() { func main() {
base64Str := cryptor.Base64StdEncode("hello world") base64Str := cryptor.Base64StdEncode("hello world")
fmt.Println(base64Str) //aGVsbG8gd29ybGQ= fmt.Println(base64Str) //aGVsbG8gd29ybGQ=
} }
``` ```
### <span id="Base64StdDecode">Base64StdDecode</span> ### <span id="Base64StdDecode">Base64StdDecode</span>
<p>Decode a base64 encoded string.</p> <p>Decode a base64 encoded string.</p>
@@ -393,8 +375,6 @@ func main() {
} }
``` ```
### <span id="DesEcbEncrypt">DesEcbEncrypt</span> ### <span id="DesEcbEncrypt">DesEcbEncrypt</span>
<p>Encrypt data with key use DES ECB algorithm. Length of `key` param should be 8.</p> <p>Encrypt data with key use DES ECB algorithm. Length of `key` param should be 8.</p>
@@ -417,15 +397,13 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefgh" key := "abcdefgh"
encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key)) encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key))
fmt.Println(string(encrypted)) fmt.Println(string(encrypted))
} }
``` ```
### <span id="DesEcbDecrypt">DesEcbDecrypt</span> ### <span id="DesEcbDecrypt">DesEcbDecrypt</span>
<p>Decrypt data with key use DES ECB algorithm. Length of `key` param should be 8.</p> <p>Decrypt data with key use DES ECB algorithm. Length of `key` param should be 8.</p>
@@ -448,16 +426,14 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefgh" key := "abcdefgh"
encrypted := cryptor.DesEcbEncrypt([]byte(data), []byt(key) encrypted := cryptor.DesEcbEncrypt([]byte(data), []byt(key)
decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key)) decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world fmt.Println(string(decrypted)) //hello world
} }
``` ```
### <span id="DesCbcEncrypt">DesCbcEncrypt</span> ### <span id="DesCbcEncrypt">DesCbcEncrypt</span>
<p>Encrypt data with key use DES CBC algorithm. Length of `key` param should be 8.</p> <p>Encrypt data with key use DES CBC algorithm. Length of `key` param should be 8.</p>
@@ -480,15 +456,13 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefgh" key := "abcdefgh"
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byt(key) encrypted := cryptor.DesCbcEncrypt([]byte(data), []byt(key)
fmt.Println(string(encrypted)) fmt.Println(string(encrypted))
} }
``` ```
### <span id="DesCbcDecrypt">DesCbcDecrypt</span> ### <span id="DesCbcDecrypt">DesCbcDecrypt</span>
<p>Decrypt data with key use DES CBC algorithm. Length of `key` param should be 8.</p> <p>Decrypt data with key use DES CBC algorithm. Length of `key` param should be 8.</p>
@@ -511,16 +485,14 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefgh" key := "abcdefgh"
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byt(key) encrypted := cryptor.DesCbcEncrypt([]byte(data), []byt(key)
decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key)) decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world fmt.Println(string(decrypted)) //hello world
} }
``` ```
### <span id="DesCtrCrypt">DesCtrCrypt</span> ### <span id="DesCtrCrypt">DesCtrCrypt</span>
<p>Encrypt or decrypt data with key use DES CTR algorithm. Length of `key` param should be 8.</p> <p>Encrypt or decrypt data with key use DES CTR algorithm. Length of `key` param should be 8.</p>
@@ -543,7 +515,7 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefgh" key := "abcdefgh"
encrypted := cryptor.DesCtrCrypt([]byte(data), []byte(key)) encrypted := cryptor.DesCtrCrypt([]byte(data), []byte(key))
decrypted := cryptor.DesCtrCrypt(encrypted, []byte(key)) decrypted := cryptor.DesCtrCrypt(encrypted, []byte(key))
@@ -551,8 +523,6 @@ func main() {
} }
``` ```
### <span id="DesCfbEncrypt">DesCfbEncrypt</span> ### <span id="DesCfbEncrypt">DesCfbEncrypt</span>
<p>Encrypt data with key use DES CFB algorithm. Length of `key` param should be 8.</p> <p>Encrypt data with key use DES CFB algorithm. Length of `key` param should be 8.</p>
@@ -575,14 +545,12 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefgh" key := "abcdefgh"
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byt(key) encrypted := cryptor.DesCfbEncrypt([]byte(data), []byt(key)
fmt.Println(string(encrypted)) fmt.Println(string(encrypted))
} }
``` ```
### <span id="DesCfbDecrypt">DesCfbDecrypt</span> ### <span id="DesCfbDecrypt">DesCfbDecrypt</span>
<p>Decrypt data with key use DES CBC algorithm. Length of `key` param should be 8.</p> <p>Decrypt data with key use DES CBC algorithm. Length of `key` param should be 8.</p>
@@ -605,15 +573,13 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefgh" key := "abcdefgh"
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byt(key) encrypted := cryptor.DesCfbEncrypt([]byte(data), []byt(key)
decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key)) decrypted := cryptor.DesCfbDecrypt(encrypted, []byte(key))
fmt.Println(string(decrypted)) //hello world fmt.Println(string(decrypted)) //hello world
} }
``` ```
### <span id="DesOfbEncrypt">DesOfbEncrypt</span> ### <span id="DesOfbEncrypt">DesOfbEncrypt</span>
<p>Enecrypt data with key use DES OFB algorithm. Length of `key` param should be 8.</p> <p>Enecrypt data with key use DES OFB algorithm. Length of `key` param should be 8.</p>
@@ -636,14 +602,12 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefgh" key := "abcdefgh"
encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key)) encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key))
fmt.Println(string(encrypted)) fmt.Println(string(encrypted))
} }
``` ```
### <span id="DesOfbDecrypt">DesOfbDecrypt</span> ### <span id="DesOfbDecrypt">DesOfbDecrypt</span>
<p>Decrypt data with key use DES OFB algorithm. Length of `key` param should be 8.</p> <p>Decrypt data with key use DES OFB algorithm. Length of `key` param should be 8.</p>
@@ -666,16 +630,14 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefgh" key := "abcdefgh"
encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key)) 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 fmt.Println(string(decrypted)) //hello world
} }
``` ```
### <span id="HmacMd5">HmacMd5</span> ### <span id="HmacMd5">HmacMd5</span>
<p>Get the md5 hmac hash of string.</p> <p>Get the md5 hmac hash of string.</p>
@@ -697,13 +659,11 @@ import (
) )
func main() { func main() {
s := cryptor.HmacMd5("hello world", "12345")) s := cryptor.HmacMd5("hello world", "12345"))
fmt.Println(s) //5f4c9faaff0a1ad3007d9ddc06abe36d fmt.Println(s) //5f4c9faaff0a1ad3007d9ddc06abe36d
} }
``` ```
### <span id="HmacSha1">HmacSha1</span> ### <span id="HmacSha1">HmacSha1</span>
<p>Get the sha1 hmac hash of string.</p> <p>Get the sha1 hmac hash of string.</p>
@@ -725,13 +685,11 @@ import (
) )
func main() { func main() {
s := cryptor.HmacSha1("hello world", "12345")) s := cryptor.HmacSha1("hello world", "12345"))
fmt.Println(s) //3826f812255d8683f051ee97346d1359234d5dbd fmt.Println(s) //3826f812255d8683f051ee97346d1359234d5dbd
} }
``` ```
### <span id="HmacSha256">HmacSha256</span> ### <span id="HmacSha256">HmacSha256</span>
<p>Get the sha256 hmac hash of string</p> <p>Get the sha256 hmac hash of string</p>
@@ -753,13 +711,11 @@ import (
) )
func main() { func main() {
s := cryptor.HmacSha256("hello world", "12345")) s := cryptor.HmacSha256("hello world", "12345"))
fmt.Println(s) //9dce2609f2d67d41f74c7f9efc8ccd44370d41ad2de52982627588dfe7289ab8 fmt.Println(s) //9dce2609f2d67d41f74c7f9efc8ccd44370d41ad2de52982627588dfe7289ab8
} }
``` ```
### <span id="HmacSha512">HmacSha512</span> ### <span id="HmacSha512">HmacSha512</span>
<p>Get the sha512 hmac hash of string.</p> <p>Get the sha512 hmac hash of string.</p>
@@ -781,14 +737,11 @@ import (
) )
func main() { func main() {
s := cryptor.HmacSha512("hello world", "12345")) s := cryptor.HmacSha512("hello world", "12345"))
fmt.Println(s) fmt.Println(s) //5b1563ac4e9b49c9ada8ccb232588fc4f0c30fd12f756b3a0b95af4985c236ca60925253bae10ce2c6bf9af1c1679b51e5395ff3d2826c0a2c7c0d72225d4175
//5b1563ac4e9b49c9ada8ccb232588fc4f0c30fd12f756b3a0b95af4985c236ca60925253bae10ce2c6bf9af1c1679b51e5395ff3d2826c0a2c7c0d72225d4175
} }
``` ```
### <span id="Md5String">Md5String</span> ### <span id="Md5String">Md5String</span>
<p>Get the md5 value of string.</p> <p>Get the md5 value of string.</p>
@@ -810,13 +763,11 @@ import (
) )
func main() { func main() {
s := cryptor.Md5String("hello")) s := cryptor.Md5String("hello"))
fmt.Println(s) //5d41402abc4b2a76b9719d911017c592 fmt.Println(s) //5d41402abc4b2a76b9719d911017c592
} }
``` ```
### <span id="Md5File">Md5File</span> ### <span id="Md5File">Md5File</span>
<p>Get the md5 value of file.</p> <p>Get the md5 value of file.</p>
@@ -838,13 +789,11 @@ import (
) )
func main() { func main() {
s := cryptor.Md5File("./main.go")) s := cryptor.Md5File("./main.go"))
fmt.Println(s) fmt.Println(s)
} }
``` ```
### <span id="Sha1">Sha1</span> ### <span id="Sha1">Sha1</span>
<p>Get the sha1 value of string.</p> <p>Get the sha1 value of string.</p>
@@ -866,13 +815,11 @@ import (
) )
func main() { func main() {
s := cryptor.Sha1("hello world")) s := cryptor.Sha1("hello world"))
fmt.Println(s) //2aae6c35c94fcfb415dbe95f408b9ce91ee846ed fmt.Println(s) //2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
} }
``` ```
### <span id="Sha256">Sha256</span> ### <span id="Sha256">Sha256</span>
<p>Get the sha256 value of string.</p> <p>Get the sha256 value of string.</p>
@@ -894,13 +841,11 @@ import (
) )
func main() { func main() {
s := cryptor.Sha256("hello world")) s := cryptor.Sha256("hello world"))
fmt.Println(s) //b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9 fmt.Println(s) //b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
} }
``` ```
### <span id="Sha512">Sha512</span> ### <span id="Sha512">Sha512</span>
<p>Get the sha512 value of string.</p> <p>Get the sha512 value of string.</p>
@@ -922,13 +867,11 @@ import (
) )
func main() { func main() {
s := cryptor.Sha512("hello world")) s := cryptor.Sha512("hello world"))
fmt.Println(s) //309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f fmt.Println(s) //309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f
} }
``` ```
### <span id="GenerateRsaKey">GenerateRsaKey</span> ### <span id="GenerateRsaKey">GenerateRsaKey</span>
<p>Create the rsa public and private key file in current directory.</p> <p>Create the rsa public and private key file in current directory.</p>
@@ -950,15 +893,13 @@ import (
) )
func main() { func main() {
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem") err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
} }
``` ```
### <span id="RsaEncrypt">RsaEncrypt</span> ### <span id="RsaEncrypt">RsaEncrypt</span>
<p>Encrypt data with public key file useing ras algorithm.</p> <p>Encrypt data with public key file useing ras algorithm.</p>
@@ -980,21 +921,19 @@ import (
) )
func main() { func main() {
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem") err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
data := []byte("hello world") data := []byte("hello world")
encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem") encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem") decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
fmt.Println(string(decrypted)) //hello world fmt.Println(string(decrypted)) //hello world
} }
``` ```
### <span id="RsaDecrypt">RsaDecrypt</span> ### <span id="RsaDecrypt">RsaDecrypt</span>
<p>Decrypt data with private key file useing ras algorithm.</p> <p>Decrypt data with private key file useing ras algorithm.</p>
@@ -1016,18 +955,15 @@ import (
) )
func main() { func main() {
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem") err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
data := []byte("hello world") data := []byte("hello world")
encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem") encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem") decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
fmt.Println(string(decrypted)) //hello world fmt.Println(string(decrypted)) //hello world
} }
``` ```

View File

@@ -1,18 +1,20 @@
# Cryptor # Cryptor
cryptor加密包支持数据加密和解密获取md5hash值。支持base64, md5, hmac, aes, des, rsa。
cryptor 加密包支持数据加密和解密,获取 md5hash 值。支持 base64, md5, hmac, aes, des, rsa。
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 源码: ## 源码:
- [https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go](https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go](https://github.com/duke-git/lancet/blob/v1/cryptor/aes.go)
- [https://github.com/duke-git/lancet/blob/v1/cryptor/des.go](https://github.com/duke-git/lancet/blob/v1/cryptor/des.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/des.go](https://github.com/duke-git/lancet/blob/v1/cryptor/des.go)
- [https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go](https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go](https://github.com/duke-git/lancet/blob/v1/cryptor/basic.go)
- [https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go) - [https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go](https://github.com/duke-git/lancet/blob/v1/cryptor/rsa.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/cryptor" "github.com/duke-git/lancet/cryptor"
@@ -22,48 +24,44 @@ import (
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 目录 ## 目录
- [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](#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)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 文档 ## 文档
### <span id="AesEcbEncrypt">AesEcbEncrypt</span> ### <span id="AesEcbEncrypt">AesEcbEncrypt</span>
<p>使用AES ECB算法模式加密数据. 参数`key`的长度是16, 24 or 32。</p> <p>使用AES ECB算法模式加密数据. 参数`key`的长度是16, 24 or 32。</p>
@@ -73,6 +71,7 @@ import (
```go ```go
func AesEcbEncrypt(data, key []byte) []byte func AesEcbEncrypt(data, key []byte) []byte
``` ```
<b>列子:</b> <b>列子:</b>
```go ```go
@@ -85,15 +84,13 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefghijklmnop" key := "abcdefghijklmnop"
encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key)) encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key))
fmt.Println(string(encrypted)) fmt.Println(string(encrypted))
} }
``` ```
### <span id="AesEcbDecrypt">AesEcbDecrypt</span> ### <span id="AesEcbDecrypt">AesEcbDecrypt</span>
<p>使用AES ECB算法模式解密数据. 参数`key`的长度是16, 24 or 32。 <p>使用AES ECB算法模式解密数据. 参数`key`的长度是16, 24 or 32。
@@ -103,6 +100,7 @@ func main() {
```go ```go
func AesEcbDecrypt(encrypted, key []byte) []byte func AesEcbDecrypt(encrypted, key []byte) []byte
``` ```
<b>列子:</b> <b>列子:</b>
```go ```go
@@ -115,15 +113,13 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefghijklmnop" key := "abcdefghijklmnop"
encrypted := cryptor.AesEcbEncrypt([]byte(data), []byte(key)) 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 fmt.Println(string(decrypted)) //hello world
} }
``` ```
### <span id="AesCbcEncrypt">AesCbcEncrypt</span> ### <span id="AesCbcEncrypt">AesCbcEncrypt</span>
<p>使用AES CBC算法模式加密数据. 参数`key`的长度是16, 24 or 32。</p> <p>使用AES CBC算法模式加密数据. 参数`key`的长度是16, 24 or 32。</p>
@@ -133,6 +129,7 @@ func main() {
```go ```go
func AesCbcEncrypt(data, key []byte) []byte func AesCbcEncrypt(data, key []byte) []byte
``` ```
<b>列子:</b> <b>列子:</b>
```go ```go
@@ -145,15 +142,13 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefghijklmnop" key := "abcdefghijklmnop"
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key)) encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key))
fmt.Println(string(encrypted)) fmt.Println(string(encrypted))
} }
``` ```
### <span id="AesCbcDecrypt">AesCbcDecrypt</span> ### <span id="AesCbcDecrypt">AesCbcDecrypt</span>
<p>使用AES CBC算法模式解密数据. 参数`key`的长度是16, 24 or 32。</p> <p>使用AES CBC算法模式解密数据. 参数`key`的长度是16, 24 or 32。</p>
@@ -176,16 +171,14 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefghijklmnop" key := "abcdefghijklmnop"
encrypted := cryptor.AesCbcEncrypt([]byte(data), []byte(key)) 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 fmt.Println(string(decrypted)) //hello world
} }
``` ```
### <span id="AesCtrCrypt">AesCtrCrypt</span> ### <span id="AesCtrCrypt">AesCtrCrypt</span>
<p>使用AES CTR算法模式加密/解密数据. 参数`key`的长度是16, 24 or 32。</p> <p>使用AES CTR算法模式加密/解密数据. 参数`key`的长度是16, 24 or 32。</p>
@@ -208,7 +201,7 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefghijklmnop" key := "abcdefghijklmnop"
encrypted := cryptor.AesCtrCrypt([]byte(data), []byte(key)) encrypted := cryptor.AesCtrCrypt([]byte(data), []byte(key))
decrypted := cryptor.AesCtrCrypt(encrypted, []byte(key)) decrypted := cryptor.AesCtrCrypt(encrypted, []byte(key))
@@ -216,8 +209,6 @@ func main() {
} }
``` ```
### <span id="AesCfbEncrypt">AesCfbEncrypt</span> ### <span id="AesCfbEncrypt">AesCfbEncrypt</span>
<p>使用AES CFB算法模式加密数据. 参数`key`的长度是16, 24 or 32。</p> <p>使用AES CFB算法模式加密数据. 参数`key`的长度是16, 24 or 32。</p>
@@ -240,14 +231,12 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefghijklmnop" key := "abcdefghijklmnop"
encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key)) encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key))
fmt.Println(string(encrypted)) fmt.Println(string(encrypted))
} }
``` ```
### <span id="AesCfbDecrypt">AesCfbDecrypt</span> ### <span id="AesCfbDecrypt">AesCfbDecrypt</span>
<p>使用AES CFB算法模式解密数据. 参数`key`的长度是16, 24 or 32。</p> <p>使用AES CFB算法模式解密数据. 参数`key`的长度是16, 24 or 32。</p>
@@ -270,15 +259,13 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefghijklmnop" key := "abcdefghijklmnop"
encrypted := cryptor.AesCfbEncrypt([]byte(data), []byte(key)) 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 fmt.Println(string(decrypted)) //hello world
} }
``` ```
### <span id="AesOfbEncrypt">AesOfbEncrypt</span> ### <span id="AesOfbEncrypt">AesOfbEncrypt</span>
<p>使用AES OFB算法模式加密数据. 参数`key`的长度是16, 24 or 32</p> <p>使用AES OFB算法模式加密数据. 参数`key`的长度是16, 24 or 32</p>
@@ -301,14 +288,12 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefghijklmnop" key := "abcdefghijklmnop"
encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key)) encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key))
fmt.Println(string(encrypted)) fmt.Println(string(encrypted))
} }
``` ```
### <span id="AesCfbDecrypt">AesOfbDecrypt</span> ### <span id="AesCfbDecrypt">AesOfbDecrypt</span>
<p>使用AES OFB算法模式解密数据. 参数`key`的长度是16, 24 or 32</p> <p>使用AES OFB算法模式解密数据. 参数`key`的长度是16, 24 or 32</p>
@@ -331,15 +316,13 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefghijklmnop" key := "abcdefghijklmnop"
encrypted := cryptor.AesOfbEncrypt([]byte(data), []byte(key)) 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 fmt.Println(string(decrypted)) //hello world
} }
``` ```
### <span id="Base64StdEncode">Base64StdEncode</span> ### <span id="Base64StdEncode">Base64StdEncode</span>
<p>将字符串base64编码</p> <p>将字符串base64编码</p>
@@ -349,6 +332,7 @@ func main() {
```go ```go
func Base64StdEncode(s string) string func Base64StdEncode(s string) string
``` ```
<b>列子:</b> <b>列子:</b>
```go ```go
@@ -360,13 +344,11 @@ import (
) )
func main() { func main() {
base64Str := cryptor.Base64StdEncode("hello world") base64Str := cryptor.Base64StdEncode("hello world")
fmt.Println(base64Str) //aGVsbG8gd29ybGQ= fmt.Println(base64Str) //aGVsbG8gd29ybGQ=
} }
``` ```
### <span id="Base64StdDecode">Base64StdDecode</span> ### <span id="Base64StdDecode">Base64StdDecode</span>
<p>解码base64字符串</p> <p>解码base64字符串</p>
@@ -388,13 +370,11 @@ import (
) )
func main() { func main() {
str := cryptor.Base64StdDecode("aGVsbG8gd29ybGQ=") str := cryptor.Base64StdDecode("aGVsbG8gd29ybGQ=")
fmt.Println(str) //hello world fmt.Println(str) //hello world
} }
``` ```
### <span id="DesEcbEncrypt">DesEcbEncrypt</span> ### <span id="DesEcbEncrypt">DesEcbEncrypt</span>
<p>使用DES ECB算法模式加密数据. 参数`key`的长度是8</p> <p>使用DES ECB算法模式加密数据. 参数`key`的长度是8</p>
@@ -417,15 +397,13 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefgh" key := "abcdefgh"
encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key)) encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key))
fmt.Println(string(encrypted)) fmt.Println(string(encrypted))
} }
``` ```
### <span id="DesEcbDecrypt">DesEcbDecrypt</span> ### <span id="DesEcbDecrypt">DesEcbDecrypt</span>
<p>使用DES ECB算法模式解密数据. 参数`key`的长度是8</p> <p>使用DES ECB算法模式解密数据. 参数`key`的长度是8</p>
@@ -448,7 +426,7 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefgh" key := "abcdefgh"
encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key)) encrypted := cryptor.DesEcbEncrypt([]byte(data), []byte(key))
decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key)) decrypted := cryptor.DesEcbDecrypt(encrypted, []byte(key))
@@ -456,8 +434,6 @@ func main() {
} }
``` ```
### <span id="DesCbcEncrypt">DesCbcEncrypt</span> ### <span id="DesCbcEncrypt">DesCbcEncrypt</span>
<p>使用DES CBC算法模式加密数据. 参数`key`的长度是8</p> <p>使用DES CBC算法模式加密数据. 参数`key`的长度是8</p>
@@ -480,15 +456,13 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefgh" key := "abcdefgh"
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key)) encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key))
fmt.Println(string(encrypted)) fmt.Println(string(encrypted))
} }
``` ```
### <span id="DesCbcDecrypt">DesCbcDecrypt</span> ### <span id="DesCbcDecrypt">DesCbcDecrypt</span>
<p>使用DES CBC算法模式解密数据. 参数`key`的长度是8</p> <p>使用DES CBC算法模式解密数据. 参数`key`的长度是8</p>
@@ -511,7 +485,7 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefgh" key := "abcdefgh"
encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key)) encrypted := cryptor.DesCbcEncrypt([]byte(data), []byte(key))
decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key)) decrypted := cryptor.DesCbcDecrypt(encrypted, []byte(key))
@@ -519,8 +493,6 @@ func main() {
} }
``` ```
### <span id="DesCtrCrypt">DesCtrCrypt</span> ### <span id="DesCtrCrypt">DesCtrCrypt</span>
<p>使用DES CTR算法模式加密/解密数据. 参数`key`的长度是8</p> <p>使用DES CTR算法模式加密/解密数据. 参数`key`的长度是8</p>
@@ -543,7 +515,7 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefgh" key := "abcdefgh"
encrypted := cryptor.DesCtrCrypt([]byte(data), []byte(key)) encrypted := cryptor.DesCtrCrypt([]byte(data), []byte(key))
decrypted := cryptor.DesCtrCrypt(encrypted, []byte(key)) decrypted := cryptor.DesCtrCrypt(encrypted, []byte(key))
@@ -551,8 +523,6 @@ func main() {
} }
``` ```
### <span id="DesCfbEncrypt">DesCfbEncrypt</span> ### <span id="DesCfbEncrypt">DesCfbEncrypt</span>
<p>使用DES CFB算法模式加密数据. 参数`key`的长度是8</p> <p>使用DES CFB算法模式加密数据. 参数`key`的长度是8</p>
@@ -575,14 +545,12 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefgh" key := "abcdefgh"
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key)) encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key))
fmt.Println(string(encrypted)) fmt.Println(string(encrypted))
} }
``` ```
### <span id="DesCfbDecrypt">DesCfbDecrypt</span> ### <span id="DesCfbDecrypt">DesCfbDecrypt</span>
<p>使用DES CFB算法模式解密数据. 参数`key`的长度是8</p> <p>使用DES CFB算法模式解密数据. 参数`key`的长度是8</p>
@@ -605,15 +573,13 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefgh" key := "abcdefgh"
encrypted := cryptor.DesCfbEncrypt([]byte(data), []byte(key)) 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 fmt.Println(string(decrypted)) //hello world
} }
``` ```
### <span id="DesOfbEncrypt">DesOfbEncrypt</span> ### <span id="DesOfbEncrypt">DesOfbEncrypt</span>
<p>使用DES OFB算法模式加密数据. 参数`key`的长度是8</p> <p>使用DES OFB算法模式加密数据. 参数`key`的长度是8</p>
@@ -636,14 +602,12 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefgh" key := "abcdefgh"
encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key)) encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key))
fmt.Println(string(encrypted)) fmt.Println(string(encrypted))
} }
``` ```
### <span id="DesOfbDecrypt">DesOfbDecrypt</span> ### <span id="DesOfbDecrypt">DesOfbDecrypt</span>
<p>使用DES OFB算法模式解密数据. 参数`key`的长度是8</p> <p>使用DES OFB算法模式解密数据. 参数`key`的长度是8</p>
@@ -666,15 +630,13 @@ import (
func main() { func main() {
data := "hello world" data := "hello world"
key := "abcdefgh" key := "abcdefgh"
encrypted := cryptor.DesOfbEncrypt([]byte(data), []byte(key)) 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 fmt.Println(string(decrypted)) //hello world
} }
``` ```
### <span id="HmacMd5">HmacMd5</span> ### <span id="HmacMd5">HmacMd5</span>
<p>获取字符串md5 hmac值</p> <p>获取字符串md5 hmac值</p>
@@ -696,13 +658,11 @@ import (
) )
func main() { func main() {
s := cryptor.HmacMd5("hello world", "12345")) s := cryptor.HmacMd5("hello world", "12345"))
fmt.Println(s) //5f4c9faaff0a1ad3007d9ddc06abe36d fmt.Println(s) //5f4c9faaff0a1ad3007d9ddc06abe36d
} }
``` ```
### <span id="HmacSha1">HmacSha1</span> ### <span id="HmacSha1">HmacSha1</span>
<p>获取字符串sha1 hmac值</p> <p>获取字符串sha1 hmac值</p>
@@ -724,13 +684,11 @@ import (
) )
func main() { func main() {
s := cryptor.HmacSha1("hello world", "12345")) s := cryptor.HmacSha1("hello world", "12345"))
fmt.Println(s) //3826f812255d8683f051ee97346d1359234d5dbd fmt.Println(s) //3826f812255d8683f051ee97346d1359234d5dbd
} }
``` ```
### <span id="HmacSha256">HmacSha256</span> ### <span id="HmacSha256">HmacSha256</span>
<p>获取字符串sha256 hmac值</p> <p>获取字符串sha256 hmac值</p>
@@ -752,13 +710,11 @@ import (
) )
func main() { func main() {
s := cryptor.HmacSha256("hello world", "12345")) s := cryptor.HmacSha256("hello world", "12345"))
fmt.Println(s) //9dce2609f2d67d41f74c7f9efc8ccd44370d41ad2de52982627588dfe7289ab8 fmt.Println(s) //9dce2609f2d67d41f74c7f9efc8ccd44370d41ad2de52982627588dfe7289ab8
} }
``` ```
### <span id="HmacSha512">HmacSha512</span> ### <span id="HmacSha512">HmacSha512</span>
<p>获取字符串sha512 hmac值</p> <p>获取字符串sha512 hmac值</p>
@@ -780,14 +736,12 @@ import (
) )
func main() { func main() {
s := cryptor.HmacSha512("hello world", "12345")) s := cryptor.HmacSha512("hello world", "12345"))
fmt.Println(s) fmt.Println(s)
//5b1563ac4e9b49c9ada8ccb232588fc4f0c30fd12f756b3a0b95af4985c236ca60925253bae10ce2c6bf9af1c1679b51e5395ff3d2826c0a2c7c0d72225d4175 //5b1563ac4e9b49c9ada8ccb232588fc4f0c30fd12f756b3a0b95af4985c236ca60925253bae10ce2c6bf9af1c1679b51e5395ff3d2826c0a2c7c0d72225d4175
} }
``` ```
### <span id="Md5String">Md5String</span> ### <span id="Md5String">Md5String</span>
<p>获取字符串md5值</p> <p>获取字符串md5值</p>
@@ -809,13 +763,11 @@ import (
) )
func main() { func main() {
s := cryptor.Md5String("hello")) s := cryptor.Md5String("hello"))
fmt.Println(s) //5d41402abc4b2a76b9719d911017c592 fmt.Println(s) //5d41402abc4b2a76b9719d911017c592
} }
``` ```
### <span id="Md5File">Md5File</span> ### <span id="Md5File">Md5File</span>
<p>获取文件md5值.</p> <p>获取文件md5值.</p>
@@ -837,13 +789,11 @@ import (
) )
func main() { func main() {
s := cryptor.Md5File("./main.go")) s := cryptor.Md5File("./main.go"))
fmt.Println(s) fmt.Println(s)
} }
``` ```
### <span id="Sha1">Sha1</span> ### <span id="Sha1">Sha1</span>
<p>获取字符串sha1值</p> <p>获取字符串sha1值</p>
@@ -865,13 +815,11 @@ import (
) )
func main() { func main() {
s := cryptor.Sha1("hello world")) s := cryptor.Sha1("hello world"))
fmt.Println(s) //2aae6c35c94fcfb415dbe95f408b9ce91ee846ed fmt.Println(s) //2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
} }
``` ```
### <span id="Sha256">Sha256</span> ### <span id="Sha256">Sha256</span>
<p>获取字符串sha256值</p> <p>获取字符串sha256值</p>
@@ -893,13 +841,11 @@ import (
) )
func main() { func main() {
s := cryptor.Sha256("hello world")) s := cryptor.Sha256("hello world"))
fmt.Println(s) //b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9 fmt.Println(s) //b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
} }
``` ```
### <span id="Sha512">Sha512</span> ### <span id="Sha512">Sha512</span>
<p>获取字符串sha512值</p> <p>获取字符串sha512值</p>
@@ -921,13 +867,11 @@ import (
) )
func main() { func main() {
s := cryptor.Sha512("hello world")) s := cryptor.Sha512("hello world"))
fmt.Println(s) //309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f fmt.Println(s) //309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f
} }
``` ```
### <span id="GenerateRsaKey">GenerateRsaKey</span> ### <span id="GenerateRsaKey">GenerateRsaKey</span>
<p>在当前目录下创建rsa私钥文件和公钥文件</p> <p>在当前目录下创建rsa私钥文件和公钥文件</p>
@@ -949,15 +893,13 @@ import (
) )
func main() { func main() {
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem") err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
} }
``` ```
### <span id="RsaEncrypt">RsaEncrypt</span> ### <span id="RsaEncrypt">RsaEncrypt</span>
<p>用公钥文件ras加密数据</p> <p>用公钥文件ras加密数据</p>
@@ -979,19 +921,18 @@ import (
) )
func main() { func main() {
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem") err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
data := []byte("hello world")
data := []byte("hello world")
encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem") encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem") decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
fmt.Println(string(decrypted)) //hello world fmt.Println(string(decrypted)) //hello world
} }
``` ```
### <span id="RsaDecrypt">RsaDecrypt</span> ### <span id="RsaDecrypt">RsaDecrypt</span>
<p>用私钥文件rsa解密数据</p> <p>用私钥文件rsa解密数据</p>
@@ -1013,16 +954,14 @@ import (
) )
func main() { func main() {
err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem") err := cryptor.GenerateRsaKey(4096, "rsa_private.pem", "rsa_public.pem")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
data := []byte("hello world")
data := []byte("hello world")
encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem") encrypted := cryptor.RsaEncrypt(data, "rsa_public.pem")
decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem") decrypted := cryptor.RsaDecrypt(encrypted, "rsa_private.pem")
fmt.Println(string(decrypted)) //hello world fmt.Println(string(decrypted)) //hello world
} }
``` ```

View File

@@ -1,4 +1,5 @@
# Datetime # Datetime
Package datetime supports date and time format and compare. Package datetime supports date and time format and compare.
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -10,6 +11,7 @@ Package datetime supports date and time format and compare.
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/datetime"
@@ -19,66 +21,67 @@ import (
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Index ## Index
- [AddDay](#AddDay)
- [AddHour](#AddHour)
- [AddMinute](#AddMinute)
- [BeginOfMinute](#BeginOfMinute)
- [BeginOfHour](#BeginOfHour)
- [BeginOfDay](#BeginOfDay)
- [BeginOfWeek](#BeginOfWeek)
- [BeginOfMonth](#BeginOfMonth)
- [BeginOfYear](#BeginOfYear)
- [EndOfMinute](#EndOfMinute) - [AddDay](#AddDay)
- [EndOfHour](#EndOfHour) - [AddHour](#AddHour)
- [EndOfDay](#EndOfDay) - [AddMinute](#AddMinute)
- [EndOfWeek](#EndOfWeek) - [BeginOfMinute](#BeginOfMinute)
- [EndOfMonth](#EndOfMonth) - [BeginOfHour](#BeginOfHour)
- [EndOfYear](#EndOfYear) - [BeginOfDay](#BeginOfDay)
- [GetNowDate](#GetNowDate) - [BeginOfWeek](#BeginOfWeek)
- [GetNowTime](#GetNowTime) - [BeginOfMonth](#BeginOfMonth)
- [GetNowDateTime](#GetNowDateTime) - [BeginOfYear](#BeginOfYear)
- [GetZeroHourTimestamp](#GetZeroHourTimestamp) - [EndOfMinute](#EndOfMinute)
- [GetNightTimestamp](#GetNightTimestamp) - [EndOfHour](#EndOfHour)
- [FormatTimeToStr](#FormatTimeToStr) - [EndOfDay](#EndOfDay)
- [EndOfWeek](#EndOfWeek)
- [FormatStrToTime](#FormatStrToTime) - [EndOfMonth](#EndOfMonth)
- [NewUnixNow](#NewUnixNow) - [EndOfYear](#EndOfYear)
- [NewUnix](#NewUnix) - [GetNowDate](#GetNowDate)
- [NewFormat](#NewFormat) - [GetNowTime](#GetNowTime)
- [NewISO8601](#NewISO8601) - [GetNowDateTime](#GetNowDateTime)
- [ToUnix](#ToUnix) - [GetZeroHourTimestamp](#GetZeroHourTimestamp)
- [ToFormat](#ToFormat) - [GetNightTimestamp](#GetNightTimestamp)
- [ToFormatForTpl](#ToFormatForTpl) - [FormatTimeToStr](#FormatTimeToStr)
- [ToIso8601](#ToIso8601) - [FormatStrToTime](#FormatStrToTime)
- [NewUnixNow](#NewUnixNow)
- [NewUnix](#NewUnix)
- [NewFormat](#NewFormat)
- [NewISO8601](#NewISO8601)
- [ToUnix](#ToUnix)
- [ToFormat](#ToFormat)
- [ToFormatForTpl](#ToFormatForTpl)
- [ToIso8601](#ToIso8601)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Documentation ## Documentation
## Note: ## 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
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
### <span id="AddDay">AddDay</span> ### <span id="AddDay">AddDay</span>
<p>Add or sub days to time.</p> <p>Add or sub days to time.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -86,6 +89,7 @@ import (
```go ```go
func AddDay(t time.Time, day int64) time.Time func AddDay(t time.Time, day int64) time.Time
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -106,8 +110,8 @@ func main() {
} }
``` ```
### <span id="AddHour">AddHour</span> ### <span id="AddHour">AddHour</span>
<p>Add or sub hours to time.</p> <p>Add or sub hours to time.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -115,6 +119,7 @@ func main() {
```go ```go
func AddHour(t time.Time, hour int64) time.Time func AddHour(t time.Time, hour int64) time.Time
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -136,6 +141,7 @@ func main() {
``` ```
### <span id="AddMinute">AddMinute</span> ### <span id="AddMinute">AddMinute</span>
<p>Add or sub minutes to time.</p> <p>Add or sub minutes to time.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -143,6 +149,7 @@ func main() {
```go ```go
func AddMinute(t time.Time, minute int64) time.Time func AddMinute(t time.Time, minute int64) time.Time
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -164,6 +171,7 @@ func main() {
``` ```
### <span id="BeginOfMinute">BeginOfMinute</span> ### <span id="BeginOfMinute">BeginOfMinute</span>
<p>Return beginning minute time of day.</p> <p>Return beginning minute time of day.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -171,6 +179,7 @@ func main() {
```go ```go
func BeginOfMinute(t time.Time) time.Time func BeginOfMinute(t time.Time) time.Time
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -190,6 +199,7 @@ func main() {
``` ```
### <span id="BeginOfHour">BeginOfHour</span> ### <span id="BeginOfHour">BeginOfHour</span>
<p>Return zero time of day.</p> <p>Return zero time of day.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -197,6 +207,7 @@ func main() {
```go ```go
func BeginOfHour(t time.Time) time.Time func BeginOfHour(t time.Time) time.Time
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -216,6 +227,7 @@ func main() {
``` ```
### <span id="BeginOfDay">BeginOfDay</span> ### <span id="BeginOfDay">BeginOfDay</span>
<p>Return begin time of day.</p> <p>Return begin time of day.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -223,6 +235,7 @@ func main() {
```go ```go
func BeginOfDay(t time.Time) time.Time func BeginOfDay(t time.Time) time.Time
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -241,9 +254,8 @@ func main() {
} }
``` ```
### <span id="BeginOfWeek">BeginOfWeek</span> ### <span id="BeginOfWeek">BeginOfWeek</span>
<p>Return beginning time of week, week begin from Sunday.</p> <p>Return beginning time of week, week begin from Sunday.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -251,6 +263,7 @@ func main() {
```go ```go
func BeginOfWeek(t time.Time) time.Time func BeginOfWeek(t time.Time) time.Time
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -269,9 +282,8 @@ func main() {
} }
``` ```
### <span id="BeginOfMonth">BeginOfMonth</span> ### <span id="BeginOfMonth">BeginOfMonth</span>
<p>Return beginning time of month</p> <p>Return beginning time of month</p>
<b>Signature:</b> <b>Signature:</b>
@@ -279,6 +291,7 @@ func main() {
```go ```go
func BeginOfMonth(t time.Time) time.Time func BeginOfMonth(t time.Time) time.Time
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -297,8 +310,8 @@ func main() {
} }
``` ```
### <span id="BeginOfYear">BeginOfYear</span> ### <span id="BeginOfYear">BeginOfYear</span>
<p>Return beginning time of year.</p> <p>Return beginning time of year.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -306,6 +319,7 @@ func main() {
```go ```go
func BeginOfYear(t time.Time) time.Time func BeginOfYear(t time.Time) time.Time
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -324,9 +338,8 @@ func main() {
} }
``` ```
### <span id="EndOfMinute">EndOfMinute</span> ### <span id="EndOfMinute">EndOfMinute</span>
<p>Return end time minute of day.</p> <p>Return end time minute of day.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -334,6 +347,7 @@ func main() {
```go ```go
func EndOfMinute(t time.Time) time.Time func EndOfMinute(t time.Time) time.Time
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -353,6 +367,7 @@ func main() {
``` ```
### <span id="EndOfHour">EndOfHour</span> ### <span id="EndOfHour">EndOfHour</span>
<p>Return end time hour of day.</p> <p>Return end time hour of day.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -360,6 +375,7 @@ func main() {
```go ```go
func EndOfHour(t time.Time) time.Time func EndOfHour(t time.Time) time.Time
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -379,6 +395,7 @@ func main() {
``` ```
### <span id="EndOfDay">EndOfDay</span> ### <span id="EndOfDay">EndOfDay</span>
<p>Return end time hour of day.</p> <p>Return end time hour of day.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -386,6 +403,7 @@ func main() {
```go ```go
func EndOfDay(t time.Time) time.Time func EndOfDay(t time.Time) time.Time
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -404,9 +422,8 @@ func main() {
} }
``` ```
### <span id="EndOfWeek">EndOfWeek</span> ### <span id="EndOfWeek">EndOfWeek</span>
<p>Return end time of week, week end with Saturday.</p> <p>Return end time of week, week end with Saturday.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -414,6 +431,7 @@ func main() {
```go ```go
func EndOfWeek(t time.Time) time.Time func EndOfWeek(t time.Time) time.Time
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -432,9 +450,8 @@ func main() {
} }
``` ```
### <span id="EndOfMonth">EndOfMonth</span> ### <span id="EndOfMonth">EndOfMonth</span>
<p>Return end time of month</p> <p>Return end time of month</p>
<b>Signature:</b> <b>Signature:</b>
@@ -442,6 +459,7 @@ func main() {
```go ```go
func EndOfMonth(t time.Time) time.Time func EndOfMonth(t time.Time) time.Time
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -460,8 +478,8 @@ func main() {
} }
``` ```
### <span id="EndOfYear">EndOfYear</span> ### <span id="EndOfYear">EndOfYear</span>
<p>Return beginning time of year.</p> <p>Return beginning time of year.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -469,6 +487,7 @@ func main() {
```go ```go
func EndOfYear(t time.Time) time.Time func EndOfYear(t time.Time) time.Time
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -487,8 +506,8 @@ func main() {
} }
``` ```
### <span id="GetNowDate">GetNowDate</span> ### <span id="GetNowDate">GetNowDate</span>
<p>Get current date string, format is yyyy-mm-dd.</p> <p>Get current date string, format is yyyy-mm-dd.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -496,6 +515,7 @@ func main() {
```go ```go
func GetNowDate() string func GetNowDate() string
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -514,8 +534,8 @@ func main() {
} }
``` ```
### <span id="GetNowTime">GetNowTime</span> ### <span id="GetNowTime">GetNowTime</span>
<p>Get current time string, format is hh:mm:ss.</p> <p>Get current time string, format is hh:mm:ss.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -523,6 +543,7 @@ func main() {
```go ```go
func GetNowTime() string func GetNowTime() string
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -541,8 +562,8 @@ func main() {
} }
``` ```
### <span id="GetNowDateTime">GetNowDateTime</span> ### <span id="GetNowDateTime">GetNowDateTime</span>
<p>Get current date time string, format is yyyy-mm-dd hh:mm:ss.</p> <p>Get current date time string, format is yyyy-mm-dd hh:mm:ss.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -550,6 +571,7 @@ func main() {
```go ```go
func GetNowDateTime() string func GetNowDateTime() string
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -568,8 +590,8 @@ func main() {
} }
``` ```
### <span id="GetZeroHourTimestamp">GetZeroHourTimestamp</span> ### <span id="GetZeroHourTimestamp">GetZeroHourTimestamp</span>
<p>Return timestamp of zero hour (timestamp of 00:00).</p> <p>Return timestamp of zero hour (timestamp of 00:00).</p>
<b>Signature:</b> <b>Signature:</b>
@@ -577,6 +599,7 @@ func main() {
```go ```go
func GetZeroHourTimestamp() int64 func GetZeroHourTimestamp() int64
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -595,8 +618,8 @@ func main() {
} }
``` ```
### <span id="GetNightTimestamp">GetNightTimestamp</span> ### <span id="GetNightTimestamp">GetNightTimestamp</span>
<p>Return timestamp of zero hour (timestamp of 23:59).</p> <p>Return timestamp of zero hour (timestamp of 23:59).</p>
<b>Signature:</b> <b>Signature:</b>
@@ -604,6 +627,7 @@ func main() {
```go ```go
func GetNightTimestamp() int64 func GetNightTimestamp() int64
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -623,6 +647,7 @@ func main() {
``` ```
### <span id="FormatTimeToStr">FormatTimeToStr</span> ### <span id="FormatTimeToStr">FormatTimeToStr</span>
<p>Format time to string, `format` param specification see note 1.</p> <p>Format time to string, `format` param specification see note 1.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -630,6 +655,7 @@ func main() {
```go ```go
func FormatTimeToStr(t time.Time, format string) string func FormatTimeToStr(t time.Time, format string) string
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -648,8 +674,8 @@ func main() {
} }
``` ```
### <span id="FormatStrToTime">FormatStrToTime</span> ### <span id="FormatStrToTime">FormatStrToTime</span>
<p>Format string to time, `format` param specification see note 1.</p> <p>Format string to time, `format` param specification see note 1.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -657,6 +683,7 @@ func main() {
```go ```go
func FormatStrToTime(str, format string) (time.Time, error) func FormatStrToTime(str, format string) (time.Time, error)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -673,19 +700,19 @@ func main() {
} }
``` ```
### <span id="NewUnixNow">NewUnixNow</span> ### <span id="NewUnixNow">NewUnixNow</span>
<p>Return unix timestamp of current time</p> <p>Return unix timestamp of current time</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
type theTime struct { type theTime struct {
unix int64 unix int64
} }
func NewUnixNow() *theTime func NewUnixNow() *theTime
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -702,18 +729,19 @@ func main() {
} }
``` ```
### <span id="NewUnix">NewUnix</span> ### <span id="NewUnix">NewUnix</span>
<p>Return unix timestamp of specified int64 value.</p> <p>Return unix timestamp of specified int64 value.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
type theTime struct { type theTime struct {
unix int64 unix int64
} }
func NewUnix(unix int64) *theTime func NewUnix(unix int64) *theTime
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -730,19 +758,19 @@ func main() {
} }
``` ```
### <span id="NewFormat">NewFormat</span> ### <span id="NewFormat">NewFormat</span>
<p>Return unix timestamp of specified time string, t should be "yyyy-mm-dd hh:mm:ss".</p> <p>Return unix timestamp of specified time string, t should be "yyyy-mm-dd hh:mm:ss".</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
type theTime struct { type theTime struct {
unix int64 unix int64
} }
func NewFormat(t string) (*theTime, error) func NewFormat(t string) (*theTime, error)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -759,20 +787,19 @@ func main() {
} }
``` ```
### <span id="NewISO8601">NewISO8601</span> ### <span id="NewISO8601">NewISO8601</span>
<p>Return unix timestamp of specified iso8601 time string.</p> <p>Return unix timestamp of specified iso8601 time string.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
type theTime struct { type theTime struct {
unix int64 unix int64
} }
func NewISO8601(iso8601 string) (*theTime, error) func NewISO8601(iso8601 string) (*theTime, error)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -789,9 +816,8 @@ func main() {
} }
``` ```
### <span id="ToUnix">ToUnix</span> ### <span id="ToUnix">ToUnix</span>
<p>Return unix timestamp.</p> <p>Return unix timestamp.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -799,6 +825,7 @@ func main() {
```go ```go
func (t *theTime) ToUnix() int64 func (t *theTime) ToUnix() int64
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -815,9 +842,8 @@ func main() {
} }
``` ```
### <span id="ToFormat">ToFormat</span> ### <span id="ToFormat">ToFormat</span>
<p>Return time string 'yyyy-mm-dd hh:mm:ss'.</p> <p>Return time string 'yyyy-mm-dd hh:mm:ss'.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -825,6 +851,7 @@ func main() {
```go ```go
func (t *theTime) ToFormat() string func (t *theTime) ToFormat() string
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -841,9 +868,8 @@ func main() {
} }
``` ```
### <span id="ToFormatForTpl">ToFormatForTpl</span> ### <span id="ToFormatForTpl">ToFormatForTpl</span>
<p>Return the time string which format is specified tpl.</p> <p>Return the time string which format is specified tpl.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -851,6 +877,7 @@ func main() {
```go ```go
func (t *theTime) ToFormatForTpl(tpl string) string func (t *theTime) ToFormatForTpl(tpl string) string
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -868,8 +895,8 @@ func main() {
} }
``` ```
### <span id="ToIso8601">ToIso8601</span> ### <span id="ToIso8601">ToIso8601</span>
<p>Return iso8601 time string.</p> <p>Return iso8601 time string.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -877,6 +904,7 @@ func main() {
```go ```go
func (t *theTime) ToIso8601() string func (t *theTime) ToIso8601() string
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go

View File

@@ -1,5 +1,6 @@
# Datetime # Datetime
datetime日期时间处理包格式化日期比较日期。
datetime 日期时间处理包,格式化日期,比较日期。
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -10,6 +11,7 @@ datetime日期时间处理包格式化日期比较日期。
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/datetime" "github.com/duke-git/lancet/datetime"
@@ -19,65 +21,67 @@ import (
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 目录 ## 目录
- [AddDay](#AddDay)
- [AddHour](#AddHour)
- [AddMinute](#AddMinute)
- [BeginOfMinute](#BeginOfMinute)
- [BeginOfHour](#BeginOfHour)
- [BeginOfDay](#BeginOfDay)
- [BeginOfWeek](#BeginOfWeek)
- [BeginOfMonth](#BeginOfMonth)
- [BeginOfYear](#BeginOfYear)
- [EndOfMinute](#EndOfMinute) - [AddDay](#AddDay)
- [EndOfHour](#EndOfHour) - [AddHour](#AddHour)
- [EndOfDay](#EndOfDay) - [AddMinute](#AddMinute)
- [EndOfWeek](#EndOfWeek) - [BeginOfMinute](#BeginOfMinute)
- [EndOfMonth](#EndOfMonth) - [BeginOfHour](#BeginOfHour)
- [EndOfYear](#EndOfYear) - [BeginOfDay](#BeginOfDay)
- [GetNowDate](#GetNowDate) - [BeginOfWeek](#BeginOfWeek)
- [GetNowTime](#GetNowTime) - [BeginOfMonth](#BeginOfMonth)
- [GetNowDateTime](#GetNowDateTime) - [BeginOfYear](#BeginOfYear)
- [GetZeroHourTimestamp](#GetZeroHourTimestamp) - [EndOfMinute](#EndOfMinute)
- [GetNightTimestamp](#GetNightTimestamp) - [EndOfHour](#EndOfHour)
- [FormatTimeToStr](#FormatTimeToStr) - [EndOfDay](#EndOfDay)
- [FormatStrToTime](#FormatStrToTime) - [EndOfWeek](#EndOfWeek)
- [NewUnixNow](#NewUnixNow) - [EndOfMonth](#EndOfMonth)
- [NewUnix](#NewUnix) - [EndOfYear](#EndOfYear)
- [NewFormat](#NewFormat) - [GetNowDate](#GetNowDate)
- [NewISO8601](#NewISO8601) - [GetNowTime](#GetNowTime)
- [ToUnix](#ToUnix) - [GetNowDateTime](#GetNowDateTime)
- [ToFormat](#ToFormat) - [GetZeroHourTimestamp](#GetZeroHourTimestamp)
- [ToFormatForTpl](#ToFormatForTpl) - [GetNightTimestamp](#GetNightTimestamp)
- [ToIso8601](#ToIso8601) - [FormatTimeToStr](#FormatTimeToStr)
- [FormatStrToTime](#FormatStrToTime)
- [NewUnixNow](#NewUnixNow)
- [NewUnix](#NewUnix)
- [NewFormat](#NewFormat)
- [NewISO8601](#NewISO8601)
- [ToUnix](#ToUnix)
- [ToFormat](#ToFormat)
- [ToFormatForTpl](#ToFormatForTpl)
- [ToIso8601](#ToIso8601)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 文档 ## 文档
## 注: ## 注:
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
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
### <span id="AddDay">AddDay</span> ### <span id="AddDay">AddDay</span>
<p>将日期加/减天数</p> <p>将日期加/减天数</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -85,6 +89,7 @@ import (
```go ```go
func AddDay(t time.Time, day int64) time.Time func AddDay(t time.Time, day int64) time.Time
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -98,15 +103,15 @@ import (
func main() { func main() {
now := time.Now() now := time.Now()
after2Days := datetime.AddDay(now, 2) after2Days := datetime.AddDay(now, 2)
before2Days := datetime.AddDay(now, -2) before2Days := datetime.AddDay(now, -2)
fmt.Println(after2Days, before2Days) fmt.Println(after2Days, before2Days)
} }
``` ```
### <span id="AddHour">AddHour</span> ### <span id="AddHour">AddHour</span>
<p>将日期加/减小时数</p> <p>将日期加/减小时数</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -114,6 +119,7 @@ func main() {
```go ```go
func AddHour(t time.Time, hour int64) time.Time func AddHour(t time.Time, hour int64) time.Time
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -135,6 +141,7 @@ func main() {
``` ```
### <span id="AddMinute">AddMinute</span> ### <span id="AddMinute">AddMinute</span>
<p>将日期加/减分钟数</p> <p>将日期加/减分钟数</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -142,6 +149,7 @@ func main() {
```go ```go
func AddMinute(t time.Time, minute int64) time.Time func AddMinute(t time.Time, minute int64) time.Time
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -163,6 +171,7 @@ func main() {
``` ```
### <span id="BeginOfMinute">BeginOfMinute</span> ### <span id="BeginOfMinute">BeginOfMinute</span>
<p>返回指定时间的分钟开始时间</p> <p>返回指定时间的分钟开始时间</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -170,6 +179,7 @@ func main() {
```go ```go
func BeginOfMinute(t time.Time) time.Time func BeginOfMinute(t time.Time) time.Time
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -189,6 +199,7 @@ func main() {
``` ```
### <span id="BeginOfHour">BeginOfHour</span> ### <span id="BeginOfHour">BeginOfHour</span>
<p>返回指定时间的小时开始时间</p> <p>返回指定时间的小时开始时间</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -196,6 +207,7 @@ func main() {
```go ```go
func BeginOfHour(t time.Time) time.Time func BeginOfHour(t time.Time) time.Time
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -215,6 +227,7 @@ func main() {
``` ```
### <span id="BeginOfDay">BeginOfDay</span> ### <span id="BeginOfDay">BeginOfDay</span>
<p>返回指定时间的当天开始时间</p> <p>返回指定时间的当天开始时间</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -222,6 +235,7 @@ func main() {
```go ```go
func BeginOfDay(t time.Time) time.Time func BeginOfDay(t time.Time) time.Time
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -240,9 +254,8 @@ func main() {
} }
``` ```
### <span id="BeginOfWeek">BeginOfWeek</span> ### <span id="BeginOfWeek">BeginOfWeek</span>
<p>返回指定时间的星期开始时间</p> <p>返回指定时间的星期开始时间</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -250,6 +263,7 @@ func main() {
```go ```go
func BeginOfWeek(t time.Time) time.Time func BeginOfWeek(t time.Time) time.Time
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -268,9 +282,8 @@ func main() {
} }
``` ```
### <span id="BeginOfMonth">BeginOfMonth</span> ### <span id="BeginOfMonth">BeginOfMonth</span>
<p>返回指定时间的当月开始时间</p> <p>返回指定时间的当月开始时间</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -278,6 +291,7 @@ func main() {
```go ```go
func BeginOfMonth(t time.Time) time.Time func BeginOfMonth(t time.Time) time.Time
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -296,8 +310,8 @@ func main() {
} }
``` ```
### <span id="BeginOfYear">BeginOfYear</span> ### <span id="BeginOfYear">BeginOfYear</span>
<p>返回指定时间的当年开始时间</p> <p>返回指定时间的当年开始时间</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -305,6 +319,7 @@ func main() {
```go ```go
func BeginOfYear(t time.Time) time.Time func BeginOfYear(t time.Time) time.Time
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -323,9 +338,8 @@ func main() {
} }
``` ```
### <span id="EndOfMinute">EndOfMinute</span> ### <span id="EndOfMinute">EndOfMinute</span>
<p>返回指定时间的分钟结束时间</p> <p>返回指定时间的分钟结束时间</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -333,6 +347,7 @@ func main() {
```go ```go
func EndOfMinute(t time.Time) time.Time func EndOfMinute(t time.Time) time.Time
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -352,6 +367,7 @@ func main() {
``` ```
### <span id="EndOfHour">EndOfHour</span> ### <span id="EndOfHour">EndOfHour</span>
<p>返回指定时间的小时结束时间</p> <p>返回指定时间的小时结束时间</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -359,6 +375,7 @@ func main() {
```go ```go
func EndOfHour(t time.Time) time.Time func EndOfHour(t time.Time) time.Time
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -378,6 +395,7 @@ func main() {
``` ```
### <span id="EndOfDay">EndOfDay</span> ### <span id="EndOfDay">EndOfDay</span>
<p>返回指定时间的当天结束时间.</p> <p>返回指定时间的当天结束时间.</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -385,6 +403,7 @@ func main() {
```go ```go
func EndOfDay(t time.Time) time.Time func EndOfDay(t time.Time) time.Time
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -403,9 +422,8 @@ func main() {
} }
``` ```
### <span id="EndOfWeek">EndOfWeek</span> ### <span id="EndOfWeek">EndOfWeek</span>
<p>返回指定时间的星期结束时间</p> <p>返回指定时间的星期结束时间</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -413,6 +431,7 @@ func main() {
```go ```go
func EndOfWeek(t time.Time) time.Time func EndOfWeek(t time.Time) time.Time
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -431,9 +450,8 @@ func main() {
} }
``` ```
### <span id="EndOfMonth">EndOfMonth</span> ### <span id="EndOfMonth">EndOfMonth</span>
<p>返回指定时间的月份结束时间</p> <p>返回指定时间的月份结束时间</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -441,6 +459,7 @@ func main() {
```go ```go
func EndOfMonth(t time.Time) time.Time func EndOfMonth(t time.Time) time.Time
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -459,8 +478,8 @@ func main() {
} }
``` ```
### <span id="EndOfYear">EndOfYear</span> ### <span id="EndOfYear">EndOfYear</span>
<p>返回指定时间的年份结束时间</p> <p>返回指定时间的年份结束时间</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -468,6 +487,7 @@ func main() {
```go ```go
func EndOfYear(t time.Time) time.Time func EndOfYear(t time.Time) time.Time
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -486,8 +506,8 @@ func main() {
} }
``` ```
### <span id="GetNowDate">GetNowDate</span> ### <span id="GetNowDate">GetNowDate</span>
<p>获取当天日期返回格式yyyy-mm-dd</p> <p>获取当天日期返回格式yyyy-mm-dd</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -495,6 +515,7 @@ func main() {
```go ```go
func GetNowDate() string func GetNowDate() string
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -508,13 +529,13 @@ import (
func main() { func main() {
now := time.Now() now := time.Now()
currentDate := datetime.GetNowDate() currentDate := datetime.GetNowDate()
fmt.Println(currentDate) // 2022-01-28 fmt.Println(currentDate) // 2022-01-28
} }
``` ```
### <span id="GetNowTime">GetNowTime</span> ### <span id="GetNowTime">GetNowTime</span>
<p>获取当时时间返回格式hh:mm:ss</p> <p>获取当时时间返回格式hh:mm:ss</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -522,6 +543,7 @@ func main() {
```go ```go
func GetNowTime() string func GetNowTime() string
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -540,8 +562,8 @@ func main() {
} }
``` ```
### <span id="GetNowDateTime">GetNowDateTime</span> ### <span id="GetNowDateTime">GetNowDateTime</span>
<p>获取当时日期和时间返回格式yyyy-mm-dd hh:mm:ss.</p> <p>获取当时日期和时间返回格式yyyy-mm-dd hh:mm:ss.</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -549,6 +571,7 @@ func main() {
```go ```go
func GetNowDateTime() string func GetNowDateTime() string
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -567,8 +590,8 @@ func main() {
} }
``` ```
### <span id="GetZeroHourTimestamp">GetZeroHourTimestamp</span> ### <span id="GetZeroHourTimestamp">GetZeroHourTimestamp</span>
<p>获取零时时间戳(timestamp of 00:00).</p> <p>获取零时时间戳(timestamp of 00:00).</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -576,6 +599,7 @@ func main() {
```go ```go
func GetZeroHourTimestamp() int64 func GetZeroHourTimestamp() int64
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -594,8 +618,8 @@ func main() {
} }
``` ```
### <span id="GetNightTimestamp">GetNightTimestamp</span> ### <span id="GetNightTimestamp">GetNightTimestamp</span>
<p>获取午夜时间戳(timestamp of 23:59).</p> <p>获取午夜时间戳(timestamp of 23:59).</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -603,6 +627,7 @@ func main() {
```go ```go
func GetNightTimestamp() int64 func GetNightTimestamp() int64
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -622,6 +647,7 @@ func main() {
``` ```
### <span id="FormatTimeToStr">FormatTimeToStr</span> ### <span id="FormatTimeToStr">FormatTimeToStr</span>
<p>将日期格式化成字符串,`format` 参数格式参考注<sup>1</sup></p> <p>将日期格式化成字符串,`format` 参数格式参考注<sup>1</sup></p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -629,6 +655,7 @@ func main() {
```go ```go
func FormatTimeToStr(t time.Time, format string) string func FormatTimeToStr(t time.Time, format string) string
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -647,8 +674,8 @@ func main() {
} }
``` ```
### <span id="FormatStrToTime">FormatStrToTime</span> ### <span id="FormatStrToTime">FormatStrToTime</span>
<p>将字符串格式化成时间,`format` 参数格式参考注<sup>1</sup></p> <p>将字符串格式化成时间,`format` 参数格式参考注<sup>1</sup></p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -656,6 +683,7 @@ func main() {
```go ```go
func FormatStrToTime(str, format string) (time.Time, error) func FormatStrToTime(str, format string) (time.Time, error)
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -672,19 +700,19 @@ func main() {
} }
``` ```
### <span id="NewUnixNow">NewUnixNow</span> ### <span id="NewUnixNow">NewUnixNow</span>
<p>创建一个当前时间的unix时间戳</p> <p>创建一个当前时间的unix时间戳</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
type theTime struct { type theTime struct {
unix int64 unix int64
} }
func NewUnixNow() *theTime func NewUnixNow() *theTime
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -701,18 +729,19 @@ func main() {
} }
``` ```
### <span id="NewUnix">NewUnix</span> ### <span id="NewUnix">NewUnix</span>
<p>创建一个unix时间戳</p> <p>创建一个unix时间戳</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
type theTime struct { type theTime struct {
unix int64 unix int64
} }
func NewUnix(unix int64) *theTime func NewUnix(unix int64) *theTime
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -729,19 +758,19 @@ func main() {
} }
``` ```
### <span id="NewFormat">NewFormat</span> ### <span id="NewFormat">NewFormat</span>
<p>创建一个yyyy-mm-dd hh:mm:ss格式时间字符串的unix时间戳</p> <p>创建一个yyyy-mm-dd hh:mm:ss格式时间字符串的unix时间戳</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
type theTime struct { type theTime struct {
unix int64 unix int64
} }
func NewFormat(t string) (*theTime, error) func NewFormat(t string) (*theTime, error)
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -758,20 +787,19 @@ func main() {
} }
``` ```
### <span id="NewISO8601">NewISO8601</span> ### <span id="NewISO8601">NewISO8601</span>
<p>创建一个iso8601格式时间字符串的unix时间戳</p> <p>创建一个iso8601格式时间字符串的unix时间戳</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
type theTime struct { type theTime struct {
unix int64 unix int64
} }
func NewISO8601(iso8601 string) (*theTime, error) func NewISO8601(iso8601 string) (*theTime, error)
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -788,9 +816,8 @@ func main() {
} }
``` ```
### <span id="ToUnix">ToUnix</span> ### <span id="ToUnix">ToUnix</span>
<p>返回unix时间戳</p> <p>返回unix时间戳</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -798,6 +825,7 @@ func main() {
```go ```go
func (t *theTime) ToUnix() int64 func (t *theTime) ToUnix() int64
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -814,9 +842,8 @@ func main() {
} }
``` ```
### <span id="ToFormat">ToFormat</span> ### <span id="ToFormat">ToFormat</span>
<p>返回格式'yyyy-mm-dd hh:mm:ss'的日期字符串</p> <p>返回格式'yyyy-mm-dd hh:mm:ss'的日期字符串</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -824,6 +851,7 @@ func main() {
```go ```go
func (t *theTime) ToFormat() string func (t *theTime) ToFormat() string
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -840,9 +868,8 @@ func main() {
} }
``` ```
### <span id="ToFormatForTpl">ToFormatForTpl</span> ### <span id="ToFormatForTpl">ToFormatForTpl</span>
<p>返回tpl格式指定的日期字符串</p> <p>返回tpl格式指定的日期字符串</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -850,6 +877,7 @@ func main() {
```go ```go
func (t *theTime) ToFormatForTpl(tpl string) string func (t *theTime) ToFormatForTpl(tpl string) string
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -867,8 +895,8 @@ func main() {
} }
``` ```
### <span id="ToIso8601">ToIso8601</span> ### <span id="ToIso8601">ToIso8601</span>
<p>返回iso8601日期字符串</p> <p>返回iso8601日期字符串</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -876,6 +904,7 @@ func main() {
```go ```go
func (t *theTime) ToIso8601() string func (t *theTime) ToIso8601() string
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -892,4 +921,3 @@ func main() {
fmt.Println(ts) //"2006-01-02T23:04:05+08:00" fmt.Println(ts) //"2006-01-02T23:04:05+08:00"
} }
``` ```

View File

@@ -1,4 +1,5 @@
# Fileutil # Fileutil
Package fileutil implements some basic functions for file operations. Package fileutil implements some basic functions for file operations.
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -10,6 +11,7 @@ Package fileutil implements some basic functions for file operations.
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/fileutil"
@@ -19,30 +21,29 @@ import (
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Index ## Index
- [ClearFile](#ClearFile)
- [CreateFile](#CreateFile)
- [CreateDir](#CreateDir) - [ClearFile](#ClearFile)
- [CopyFile](#CopyFile) - [CreateFile](#CreateFile)
- [FileMode](#FileMode) - [CreateDir](#CreateDir)
- [MiMeType](#MiMeType) - [CopyFile](#CopyFile)
- [IsExist](#IsExist) - [FileMode](#FileMode)
- [IsLink](#IsLink) - [MiMeType](#MiMeType)
- [IsDir](#IsDir) - [IsExist](#IsExist)
- [ListFileNames](#ListFileNames) - [IsLink](#IsLink)
- [RemoveFile](#RemoveFile) - [IsDir](#IsDir)
- [ReadFileToString](#ReadFileToString) - [ListFileNames](#ListFileNames)
- [ReadFileByLine](#ReadFileByLine) - [RemoveFile](#RemoveFile)
- [Zip](#Zip) - [ReadFileToString](#ReadFileToString)
- [UnZip](#UnZip) - [ReadFileByLine](#ReadFileByLine)
- [Zip](#Zip)
- [UnZip](#UnZip)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Documentation ## Documentation
### <span id="ClearFile">ClearFile</span> ### <span id="ClearFile">ClearFile</span>
<p>Clear the file content, write empty string to the file.</p> <p>Clear the file content, write empty string to the file.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -50,6 +51,7 @@ import (
```go ```go
func ClearFile(path string) error func ClearFile(path string) error
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -68,9 +70,8 @@ func main() {
} }
``` ```
### <span id="CreateDir">CreateDir</span> ### <span id="CreateDir">CreateDir</span>
<p>Create directory in absolute path. param `absPath` like /a/, /a/b/.</p> <p>Create directory in absolute path. param `absPath` like /a/, /a/b/.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -78,6 +79,7 @@ func main() {
```go ```go
func CreateDir(absPath string) error func CreateDir(absPath string) error
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -94,9 +96,8 @@ func main() {
} }
``` ```
### <span id="CreateFile">CreateFile</span> ### <span id="CreateFile">CreateFile</span>
<p>Create file in path. return true if create succeed.</p> <p>Create file in path. return true if create succeed.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -104,6 +105,7 @@ func main() {
```go ```go
func CreateFile(path string) bool func CreateFile(path string) bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -120,8 +122,8 @@ func main() {
} }
``` ```
### <span id="CopyFile">CopyFile</span> ### <span id="CopyFile">CopyFile</span>
<p>Copy src file to dest file. If dest file exist will overwrite it.</p> <p>Copy src file to dest file. If dest file exist will overwrite it.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -129,6 +131,7 @@ func main() {
```go ```go
func CopyFile(srcFilePath string, dstFilePath string) error func CopyFile(srcFilePath string, dstFilePath string) error
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -141,15 +144,14 @@ import (
func main() { func main() {
err := fileutil.CopyFile("./test.txt", "./test_copy.txt") err := fileutil.CopyFile("./test.txt", "./test_copy.txt")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
} }
``` ```
### <span id="FileMode">FileMode</span> ### <span id="FileMode">FileMode</span>
<p>Return file mode infomation.</p> <p>Return file mode infomation.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -157,6 +159,7 @@ func main() {
```go ```go
func FileMode(path string) (fs.FileMode, error) func FileMode(path string) (fs.FileMode, error)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -169,16 +172,15 @@ import (
func main() { func main() {
mode, err := fileutil.FileMode("./test.txt") mode, err := fileutil.FileMode("./test.txt")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
fmt.Println(mode) fmt.Println(mode)
} }
``` ```
### <span id="MiMeType">MiMeType</span> ### <span id="MiMeType">MiMeType</span>
<p>Get file mime type, 'file' param's type should be string or *os.File.</p> <p>Get file mime type, 'file' param's type should be string or *os.File.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -186,6 +188,7 @@ func main() {
```go ```go
func MiMeType(file interface{}) string func MiMeType(file interface{}) string
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -207,10 +210,8 @@ func main() {
} }
``` ```
### <span id="IsExist">IsExist</span> ### <span id="IsExist">IsExist</span>
<p>Checks if a file or directory exists.</p> <p>Checks if a file or directory exists.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -218,6 +219,7 @@ func main() {
```go ```go
func IsExist(path string) bool func IsExist(path string) bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -235,9 +237,8 @@ func main() {
} }
``` ```
### <span id="IsLink">IsLink</span> ### <span id="IsLink">IsLink</span>
<p>Checks if a file is symbol link or not.</p> <p>Checks if a file is symbol link or not.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -245,6 +246,7 @@ func main() {
```go ```go
func IsLink(path string) bool func IsLink(path string) bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -261,9 +263,8 @@ func main() {
} }
``` ```
### <span id="IsDir">IsDir</span> ### <span id="IsDir">IsDir</span>
<p>Checks if the path is directy or not.</p> <p>Checks if the path is directy or not.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -271,6 +272,7 @@ func main() {
```go ```go
func IsDir(path string) bool func IsDir(path string) bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -290,9 +292,8 @@ func main() {
} }
``` ```
### <span id="ListFileNames">ListFileNames</span> ### <span id="ListFileNames">ListFileNames</span>
<p>List all file names in given path.</p> <p>List all file names in given path.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -300,6 +301,7 @@ func main() {
```go ```go
func ListFileNames(path string) ([]string, error) func ListFileNames(path string) ([]string, error)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -316,9 +318,8 @@ func main() {
} }
``` ```
### <span id="RemoveFile">RemoveFile</span> ### <span id="RemoveFile">RemoveFile</span>
<p>Remove the file of path.</p> <p>Remove the file of path.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -326,6 +327,7 @@ func main() {
```go ```go
func RemoveFile(path string) error func RemoveFile(path string) error
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -339,13 +341,13 @@ import (
func main() { func main() {
err := fileutil.RemoveFile("./test.txt") err := fileutil.RemoveFile("./test.txt")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
} }
``` ```
### <span id="ReadFileToString">ReadFileToString</span> ### <span id="ReadFileToString">ReadFileToString</span>
<p>Return string of file content.</p> <p>Return string of file content.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -353,6 +355,7 @@ func main() {
```go ```go
func ReadFileToString(path string) (string, error) func ReadFileToString(path string) (string, error)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -366,19 +369,18 @@ import (
func main() { func main() {
path := "./test.txt" path := "./test.txt"
fileutil.CreateFile(path) fileutil.CreateFile(path)
f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777) f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
f.WriteString("hello world") f.WriteString("hello world")
content, _ := fileutil.ReadFileToString(path) content, _ := fileutil.ReadFileToString(path)
fmt.Println(content) //hello world fmt.Println(content) //hello world
} }
``` ```
### <span id="ReadFileByLine">ReadFileByLine</span> ### <span id="ReadFileByLine">ReadFileByLine</span>
<p>Read file line by line, and return slice of lines</p> <p>Read file line by line, and return slice of lines</p>
<b>Signature:</b> <b>Signature:</b>
@@ -386,6 +388,7 @@ func main() {
```go ```go
func ReadFileByLine(path string)([]string, error) func ReadFileByLine(path string)([]string, error)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -399,20 +402,19 @@ import (
func main() { func main() {
path := "./text.txt" path := "./text.txt"
fileutil.CreateFile(path) fileutil.CreateFile(path)
f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777) f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
defer f.Close() defer f.Close()
f.WriteString("hello\nworld") f.WriteString("hello\nworld")
contents, _ := fileutil.ReadFileByLine(path) contents, _ := fileutil.ReadFileByLine(path)
fmt.Println(contents) //[]string{"hello", "world"} fmt.Println(contents) //[]string{"hello", "world"}
} }
``` ```
### <span id="Zip">Zip</span> ### <span id="Zip">Zip</span>
<p>Create a zip file of fpath, fpath could be a file or a directory.</p> <p>Create a zip file of fpath, fpath could be a file or a directory.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -420,6 +422,7 @@ func main() {
```go ```go
func Zip(fpath string, destPath string) error func Zip(fpath string, destPath string) error
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -431,17 +434,15 @@ import (
) )
func main() { func main() {
err := fileutil.Zip("./test.txt", "./test.zip") err := fileutil.Zip("./test.txt", "./test.zip")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
} }
``` ```
### <span id="UnZip">UnZip</span> ### <span id="UnZip">UnZip</span>
<p>Unzip the file and save it to dest path.</p> <p>Unzip the file and save it to dest path.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -449,6 +450,7 @@ func main() {
```go ```go
func UnZip(zipFile string, destPath string) error func UnZip(zipFile string, destPath string) error
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -460,14 +462,9 @@ import (
) )
func main() { func main() {
err := fileutil.Zip("./test.zip", "./unzip/test.txt") err := fileutil.Zip("./test.zip", "./unzip/test.txt")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
} }
``` ```

View File

@@ -1,5 +1,6 @@
# Fileutil # Fileutil
fileutil包支持文件基本操作。
fileutil 包支持文件基本操作。
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -10,6 +11,7 @@ fileutil包支持文件基本操作。
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/fileutil" "github.com/duke-git/lancet/fileutil"
@@ -19,30 +21,29 @@ import (
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 目录 ## 目录
- [ClearFile](#ClearFile)
- [CreateFile](#CreateFile)
- [CreateDir](#CreateDir)
- [CopyFile](#CopyFile)
- [FileMode](#FileMode)
- [MiMeType](#MiMeType)
- [IsExist](#IsExist)
- [IsLink](#IsLink)
- [IsDir](#IsDir)
- [ListFileNames](#ListFileNames) - [ClearFile](#ClearFile)
- [RemoveFile](#RemoveFile) - [CreateFile](#CreateFile)
- [ReadFileToString](#ReadFileToString) - [CreateDir](#CreateDir)
- [ReadFileByLine](#ReadFileByLine) - [CopyFile](#CopyFile)
- [Zip](#Zip) - [FileMode](#FileMode)
- [UnZip](#UnZip) - [MiMeType](#MiMeType)
- [IsExist](#IsExist)
- [IsLink](#IsLink)
- [IsDir](#IsDir)
- [ListFileNames](#ListFileNames)
- [RemoveFile](#RemoveFile)
- [ReadFileToString](#ReadFileToString)
- [ReadFileByLine](#ReadFileByLine)
- [Zip](#Zip)
- [UnZip](#UnZip)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 文档 ## 文档
### <span id="ClearFile">ClearFile</span> ### <span id="ClearFile">ClearFile</span>
<p>清空文件内容</p> <p>清空文件内容</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -50,6 +51,7 @@ import (
```go ```go
func ClearFile(path string) error func ClearFile(path string) error
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -68,8 +70,8 @@ func main() {
} }
``` ```
### <span id="CreateDir">CreateDir</span> ### <span id="CreateDir">CreateDir</span>
<p>使用绝对路径创建嵌套目录,例如/a/, /a/b/</p> <p>使用绝对路径创建嵌套目录,例如/a/, /a/b/</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -77,6 +79,7 @@ func main() {
```go ```go
func CreateDir(absPath string) error func CreateDir(absPath string) error
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -93,9 +96,8 @@ func main() {
} }
``` ```
### <span id="CreateFile">CreateFile</span> ### <span id="CreateFile">CreateFile</span>
<p>创建文件创建成功返回true, 否则返回false</p> <p>创建文件创建成功返回true, 否则返回false</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -103,6 +105,7 @@ func main() {
```go ```go
func CreateFile(path string) bool func CreateFile(path string) bool
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -119,8 +122,8 @@ func main() {
} }
``` ```
### <span id="CopyFile">CopyFile</span> ### <span id="CopyFile">CopyFile</span>
<p>拷贝文件,会覆盖原有的拷贝文件</p> <p>拷贝文件,会覆盖原有的拷贝文件</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -128,6 +131,7 @@ func main() {
```go ```go
func CopyFile(srcFilePath string, dstFilePath string) error func CopyFile(srcFilePath string, dstFilePath string) error
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -140,15 +144,14 @@ import (
func main() { func main() {
err := fileutil.CopyFile("./test.txt", "./test_copy.txt") err := fileutil.CopyFile("./test.txt", "./test_copy.txt")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
} }
``` ```
### <span id="FileMode">FileMode</span> ### <span id="FileMode">FileMode</span>
<p>获取文件mode信息</p> <p>获取文件mode信息</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -156,6 +159,7 @@ func main() {
```go ```go
func FileMode(path string) (fs.FileMode, error) func FileMode(path string) (fs.FileMode, error)
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -168,16 +172,15 @@ import (
func main() { func main() {
mode, err := fileutil.FileMode("./test.txt") mode, err := fileutil.FileMode("./test.txt")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
fmt.Println(mode) fmt.Println(mode)
} }
``` ```
### <span id="MiMeType">MiMeType</span> ### <span id="MiMeType">MiMeType</span>
<p>获取文件mime类型, 'file'参数的类型必须是string或者*os.File</p> <p>获取文件mime类型, 'file'参数的类型必须是string或者*os.File</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -185,6 +188,7 @@ func main() {
```go ```go
func MiMeType(file interface{}) string func MiMeType(file interface{}) string
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -206,10 +210,8 @@ func main() {
} }
``` ```
### <span id="IsExist">IsExist</span> ### <span id="IsExist">IsExist</span>
<p>判断文件或目录是否存在</p> <p>判断文件或目录是否存在</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -217,6 +219,7 @@ func main() {
```go ```go
func IsExist(path string) bool func IsExist(path string) bool
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -234,9 +237,8 @@ func main() {
} }
``` ```
### <span id="IsLink">IsLink</span> ### <span id="IsLink">IsLink</span>
<p>判断文件是否是符号链接</p> <p>判断文件是否是符号链接</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -244,6 +246,7 @@ func main() {
```go ```go
func IsLink(path string) bool func IsLink(path string) bool
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -260,9 +263,8 @@ func main() {
} }
``` ```
### <span id="IsDir">IsDir</span> ### <span id="IsDir">IsDir</span>
<p>判断目录是否存在</p> <p>判断目录是否存在</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -270,6 +272,7 @@ func main() {
```go ```go
func IsDir(path string) bool func IsDir(path string) bool
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -289,9 +292,8 @@ func main() {
} }
``` ```
### <span id="ListFileNames">ListFileNames</span> ### <span id="ListFileNames">ListFileNames</span>
<p>返回目录下所有文件名</p> <p>返回目录下所有文件名</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -299,6 +301,7 @@ func main() {
```go ```go
func ListFileNames(path string) ([]string, error) func ListFileNames(path string) ([]string, error)
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -315,9 +318,8 @@ func main() {
} }
``` ```
### <span id="RemoveFile">RemoveFile</span> ### <span id="RemoveFile">RemoveFile</span>
<p>删除文件</p> <p>删除文件</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -325,6 +327,7 @@ func main() {
```go ```go
func RemoveFile(path string) error func RemoveFile(path string) error
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -338,13 +341,13 @@ import (
func main() { func main() {
err := fileutil.RemoveFile("./test.txt") err := fileutil.RemoveFile("./test.txt")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
} }
``` ```
### <span id="ReadFileToString">ReadFileToString</span> ### <span id="ReadFileToString">ReadFileToString</span>
<p>读取文件内容并返回字符串</p> <p>读取文件内容并返回字符串</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -352,6 +355,7 @@ func main() {
```go ```go
func ReadFileToString(path string) (string, error) func ReadFileToString(path string) (string, error)
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -365,19 +369,18 @@ import (
func main() { func main() {
path := "./test.txt" path := "./test.txt"
fileutil.CreateFile(path) fileutil.CreateFile(path)
f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777) f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
f.WriteString("hello world") f.WriteString("hello world")
content, _ := fileutil.ReadFileToString(path) content, _ := fileutil.ReadFileToString(path)
fmt.Println(content) //hello world fmt.Println(content) //hello world
} }
``` ```
### <span id="ReadFileByLine">ReadFileByLine</span> ### <span id="ReadFileByLine">ReadFileByLine</span>
<p>按行读取文件内容,返回字符串切片包含每一行</p> <p>按行读取文件内容,返回字符串切片包含每一行</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -385,6 +388,7 @@ func main() {
```go ```go
func ReadFileByLine(path string)([]string, error) func ReadFileByLine(path string)([]string, error)
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -398,20 +402,19 @@ import (
func main() { func main() {
path := "./text.txt" path := "./text.txt"
fileutil.CreateFile(path) fileutil.CreateFile(path)
f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777) f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777)
defer f.Close() defer f.Close()
f.WriteString("hello\nworld") f.WriteString("hello\nworld")
contents, _ := fileutil.ReadFileByLine(path) contents, _ := fileutil.ReadFileByLine(path)
fmt.Println(contents) //[]string{"hello", "world"} fmt.Println(contents) //[]string{"hello", "world"}
} }
``` ```
### <span id="Zip">Zip</span> ### <span id="Zip">Zip</span>
<p>zip压缩文件, fpath参数可以是文件或目录</p> <p>zip压缩文件, fpath参数可以是文件或目录</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -419,6 +422,7 @@ func main() {
```go ```go
func Zip(fpath string, destPath string) error func Zip(fpath string, destPath string) error
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -430,17 +434,15 @@ import (
) )
func main() { func main() {
err := fileutil.Zip("./test.txt", "./test.zip") err := fileutil.Zip("./test.txt", "./test.zip")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
} }
``` ```
### <span id="UnZip">UnZip</span> ### <span id="UnZip">UnZip</span>
<p>zip解压缩文件并保存在目录中</p> <p>zip解压缩文件并保存在目录中</p>
<b>Signature:</b> <b>Signature:</b>
@@ -448,6 +450,7 @@ func main() {
```go ```go
func UnZip(zipFile string, destPath string) error func UnZip(zipFile string, destPath string) error
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -459,14 +462,9 @@ import (
) )
func main() { func main() {
err := fileutil.Zip("./test.zip", "./unzip/test.txt") err := fileutil.Zip("./test.zip", "./unzip/test.txt")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
} }
``` ```

View File

@@ -1,4 +1,5 @@
# Formatter # Formatter
formatter contains some functions for data formatting. formatter contains some functions for data formatting.
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -10,6 +11,7 @@ formatter contains some functions for data formatting.
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/formatter" "github.com/duke-git/lancet/formatter"
@@ -19,15 +21,15 @@ import (
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Index ## Index
- [Comma](#Comma)
- [Comma](#Comma)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Documentation ## Documentation
### <span id="Comma">Comma</span> ### <span id="Comma">Comma</span>
<p>Add comma to number by every 3 numbers from right. ahead by symbol char. <p>Add comma to number by every 3 numbers from right. ahead by symbol char.
Param should be number or numberic string.</p> Param should be number or numberic string.</p>
@@ -36,6 +38,7 @@ Param should be number or numberic string.</p>
```go ```go
func Comma(v interface{}, symbol string) string func Comma(v interface{}, symbol string) string
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go

View File

@@ -1,5 +1,6 @@
# Formatter # Formatter
formatter格式化器包含一些数据格式化处理方法。
formatter 格式化器包含一些数据格式化处理方法。
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -10,6 +11,7 @@ formatter格式化器包含一些数据格式化处理方法。
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/formatter" "github.com/duke-git/lancet/formatter"
@@ -19,15 +21,15 @@ import (
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 目录 ## 目录
- [Comma](#Comma)
- [Comma](#Comma)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 文档 ## 文档
### <span id="Comma">Comma</span> ### <span id="Comma">Comma</span>
<p>用逗号每隔3位分割数字/字符串,签名添加符号。参数必须是数字或者可以转为数字的字符串</p> <p>用逗号每隔3位分割数字/字符串,签名添加符号。参数必须是数字或者可以转为数字的字符串</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -35,6 +37,7 @@ import (
```go ```go
func Comma(v interface{}, symbol string) string func Comma(v interface{}, symbol string) string
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go

View File

@@ -1,4 +1,5 @@
# Function # Function
Package function can control the flow of function execution and support part of functional programming. Package function can control the flow of function execution and support part of functional programming.
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -11,6 +12,7 @@ Package function can control the flow of function execution and support part of
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/function" "github.com/duke-git/lancet/function"
@@ -20,21 +22,23 @@ import (
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Index ## Index
- [After](#After)
- [Before](#Before) - [After](#After)
- [Curry](#Curry) - [Before](#Before)
- [Compose](#Compose) - [Curry](#Curry)
- [Debounced](#Debounced) - [Compose](#Compose)
- [Delay](#Delay) - [Debounced](#Debounced)
- [Watcher](#Watcher) - [Delay](#Delay)
- [Pipeline](#Pipeline)
- [Schedule](#Schedule)
- [Watcher](#Watcher)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Documentation ## Documentation
### <span id="After">After</span> ### <span id="After">After</span>
<p>Creates a function that invokes given func once it's called n or more times.</p> <p>Creates a function that invokes given func once it's called n or more times.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -42,6 +46,7 @@ import (
```go ```go
func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -53,22 +58,22 @@ import (
) )
func main() { func main() {
arr := []string{"a", "b"} arr := []string{"a", "b"}
f := function.After(len(arr), func(i int) int { f := function.After(len(arr), func(i int) int {
fmt.Println("last print") fmt.Println("last print")
return i return i
}) })
type cb func(args ...interface{}) []reflect.Value type cb func(args ...interface{}) []reflect.Value
print := func(i int, s string, fn cb) { print := func(i int, s string, fn cb) {
fmt.Printf("arr[%d] is %s \n", i, s) fmt.Printf("arr[%d] is %s \n", i, s)
fn(i) fn(i)
} }
fmt.Println("arr is", arr) fmt.Println("arr is", arr)
for i := 0; i < len(arr); i++ { for i := 0; i < len(arr); i++ {
print(i, arr[i], f) print(i, arr[i], f)
} }
//output: //output:
// arr is [a b] // arr is [a b]
@@ -78,8 +83,6 @@ func main() {
} }
``` ```
### <span id="Before">Before</span> ### <span id="Before">Before</span>
<p>creates a function that invokes func once it's called less than n times.</p> <p>creates a function that invokes func once it's called less than n times.</p>
@@ -89,6 +92,7 @@ func main() {
```go ```go
func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -103,29 +107,27 @@ import (
func main() { func main() {
assert := internal.NewAssert(t, "TestBefore") assert := internal.NewAssert(t, "TestBefore")
arr := []string{"a", "b", "c", "d", "e"} arr := []string{"a", "b", "c", "d", "e"}
f := function.Before(3, func(i int) int { f := function.Before(3, func(i int) int {
return i return i
}) })
var res []int64 var res []int64
type cb func(args ...interface{}) []reflect.Value type cb func(args ...interface{}) []reflect.Value
appendStr := func(i int, s string, fn cb) { appendStr := func(i int, s string, fn cb) {
v := fn(i) v := fn(i)
res = append(res, v[0].Int()) res = append(res, v[0].Int())
} }
for i := 0; i < len(arr); i++ { for i := 0; i < len(arr); i++ {
appendStr(i, arr[i], f) appendStr(i, arr[i], f)
} }
expected := []int64{0, 1, 2, 2, 2} expected := []int64{0, 1, 2, 2, 2}
assert.Equal(expected, res) assert.Equal(expected, res)
} }
``` ```
### <span id="Curry">Curry</span> ### <span id="Curry">Curry</span>
<p>Make a curry function.</p> <p>Make a curry function.</p>
@@ -136,6 +138,7 @@ func main() {
type Fn func(...interface{}) interface{} type Fn func(...interface{}) interface{}
func (f Fn) Curry(i interface{}) func(...interface{}) interface{} func (f Fn) Curry(i interface{}) func(...interface{}) interface{}
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -148,19 +151,17 @@ import (
func main() { func main() {
add := func(a, b int) int { add := func(a, b int) int {
return a + b return a + b
} }
var addCurry function.Fn = func(values ...interface{}) interface{} { var addCurry function.Fn = func(values ...interface{}) interface{} {
return add(values[0].(int), values[1].(int)) return add(values[0].(int), values[1].(int))
} }
add1 := addCurry.Curry(1) add1 := addCurry.Curry(1)
result := add1(2) result := add1(2)
fmt.Println(result) //3 fmt.Println(result) //3
} }
``` ```
### <span id="Compose">Compose</span> ### <span id="Compose">Compose</span>
<p>Compose the function list from right to left, then return the composed function.</p> <p>Compose the function list from right to left, then return the composed function.</p>
@@ -170,6 +171,7 @@ func main() {
```go ```go
func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) interface{} func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) interface{}
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -182,21 +184,19 @@ import (
func main() { func main() {
add1 := func(v ...interface{}) interface{} { add1 := func(v ...interface{}) interface{} {
return v[0].(int) + 1 return v[0].(int) + 1
} }
add2 := func(v ...interface{}) interface{} { add2 := func(v ...interface{}) interface{} {
return v[0].(int) + 2 return v[0].(int) + 2
} }
add3 := function.Compose(add1, add2) add3 := function.Compose(add1, add2)
result := add3(1) result := add3(1)
fmt.Println(result) //4 fmt.Println(result) //4
} }
``` ```
### <span id="Debounced">Debounced</span> ### <span id="Debounced">Debounced</span>
<p>Creates a debounced function that delays invoking fn until after wait duration have elapsed since the last time the debounced function was invoked.</p> <p>Creates a debounced function that delays invoking fn until after wait duration have elapsed since the last time the debounced function was invoked.</p>
@@ -206,6 +206,7 @@ func main() {
```go ```go
func Debounced(fn func(), duration time.Duration) func() func Debounced(fn func(), duration time.Duration) func()
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -218,27 +219,25 @@ import (
func main() { func main() {
count := 0 count := 0
add := func() { add := func() {
count++ count++
} }
debouncedAdd := function.Debounced(add, 50*time.Microsecond) debouncedAdd := function.Debounced(add, 50*time.Microsecond)
function.debouncedAdd() function.debouncedAdd()
function.debouncedAdd() function.debouncedAdd()
function.debouncedAdd() function.debouncedAdd()
function.debouncedAdd() function.debouncedAdd()
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
fmt.Println(count) //1 fmt.Println(count) //1
function.debouncedAdd() function.debouncedAdd()
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
fmt.Println(count) //2 fmt.Println(count) //2
} }
``` ```
### <span id="Delay">Delay</span> ### <span id="Delay">Delay</span>
<p>Invoke function after delayed time.</p> <p>Invoke function after delayed time.</p>
@@ -248,6 +247,7 @@ func main() {
```go ```go
func Delay(delay time.Duration, fn interface{}, args ...interface{}) func Delay(delay time.Duration, fn interface{}, args ...interface{})
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -259,15 +259,13 @@ import (
) )
func main() { func main() {
var print = func(s string) { var print = func(s string) {
fmt.Println(count) //test delay fmt.Println(count) //test delay
} }
function.Delay(2*time.Second, print, "test delay") function.Delay(2*time.Second, print, "test delay")
} }
``` ```
### <span id="Schedule">Schedule</span> ### <span id="Schedule">Schedule</span>
<p>Invoke function every duration time, until close the returned bool chan.</p> <p>Invoke function every duration time, until close the returned bool chan.</p>
@@ -277,6 +275,7 @@ func main() {
```go ```go
func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -289,19 +288,60 @@ import (
func main() { func main() {
var res []string var res []string
appendStr := func(s string) { appendStr := func(s string) {
res = append(res, s) res = append(res, s)
} }
stop := function.Schedule(1*time.Second, appendStr, "*") stop := function.Schedule(1*time.Second, appendStr, "*")
time.Sleep(5 * time.Second) time.Sleep(5 * time.Second)
close(stop) close(stop)
fmt.Println(res) //[* * * * *] fmt.Println(res) //[* * * * *]
} }
``` ```
### <span id="Pipeline">Pipeline</span>
<p>Pipeline takes a list of functions and returns a function whose param will be passed into
the functions one by one.</p>
<b>Signature:</b>
```go
func Pipeline(funcs ...func(interface{}) interface{}) func(interface{}) interface{}
```
<b>Example:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/function"
)
func main() {
addOne := func(x interface{}) interface{} {
return x.(int) + 1
}
double := func(x interface{}) interface{} {
return 2 * x.(int)
}
square := func(x interface{}) interface{} {
return x.(int) * x.(int)
}
f := function.Pipeline(addOne, double, square)
result := fn(2)
fmt.Println(result)
// Output:
// 36
}
```
### <span id="Watcher">Watcher</span> ### <span id="Watcher">Watcher</span>
@@ -311,15 +351,16 @@ func main() {
```go ```go
type Watcher struct { type Watcher struct {
startTime int64 startTime int64
stopTime int64 stopTime int64
excuting bool excuting bool
} }
func (w *Watcher) Start() //start the watcher func (w *Watcher) Start() //start the watcher
func (w *Watcher) Stop() //stop the watcher func (w *Watcher) Stop() //stop the watcher
func (w *Watcher) Reset() //reset the watcher func (w *Watcher) Reset() //reset the watcher
func (w *Watcher) GetElapsedTime() time.Duration //get the elapsed time of function execution func (w *Watcher) GetElapsedTime() time.Duration //get the elapsed time of function execution
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -332,33 +373,30 @@ import (
func main() { func main() {
w := &function.Watcher{} w := &function.Watcher{}
w.Start() w.Start()
longRunningTask() longRunningTask()
fmt.Println(w.excuting) //true fmt.Println(w.excuting) //true
w.Stop() w.Stop()
eapsedTime := w.GetElapsedTime().Milliseconds() eapsedTime := w.GetElapsedTime().Milliseconds()
fmt.Println(eapsedTime) fmt.Println(eapsedTime)
w.Reset() w.Reset()
fmt.Println(w.excuting) //false fmt.Println(w.excuting) //false
fmt.Println(w.startTime) //0 fmt.Println(w.startTime) //0
fmt.Println(w.stopTime) //0 fmt.Println(w.stopTime) //0
} }
func longRunningTask() { func longRunningTask() {
var slice []int64 var slice []int64
for i := 0; i < 10000000; i++ { for i := 0; i < 10000000; i++ {
slice = append(slice, int64(i)) slice = append(slice, int64(i))
} }
} }
``` ```

View File

@@ -1,5 +1,6 @@
# Function # Function
function函数包控制函数执行流程包含部分函数式编程。
function 函数包控制函数执行流程,包含部分函数式编程。
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -11,6 +12,7 @@ function函数包控制函数执行流程包含部分函数式编程。
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/function" "github.com/duke-git/lancet/function"
@@ -20,21 +22,23 @@ import (
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 目录 ## 目录
- [After](#After)
- [Before](#Before) - [After](#After)
- [Curry](#Curry) - [Before](#Before)
- [Compose](#Compose) - [Curry](#Curry)
- [Debounced](#Debounced) - [Compose](#Compose)
- [Delay](#Delay) - [Debounced](#Debounced)
- [Watcher](#Watcher) - [Delay](#Delay)
- [Pipeline](#Pipeline)
- [Schedule](#Schedule)
- [Watcher](#Watcher)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 文档 ## 文档
### <span id="After">After</span> ### <span id="After">After</span>
<p>创建一个函数当他被调用n或更多次之后将马上触发fn</p> <p>创建一个函数当他被调用n或更多次之后将马上触发fn</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -42,6 +46,7 @@ import (
```go ```go
func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value func After(n int, fn interface{}) func(args ...interface{}) []reflect.Value
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -53,22 +58,22 @@ import (
) )
func main() { func main() {
arr := []string{"a", "b"} arr := []string{"a", "b"}
f := function.After(len(arr), func(i int) int { f := function.After(len(arr), func(i int) int {
fmt.Println("last print") fmt.Println("last print")
return i return i
}) })
type cb func(args ...interface{}) []reflect.Value type cb func(args ...interface{}) []reflect.Value
print := func(i int, s string, fn cb) { print := func(i int, s string, fn cb) {
fmt.Printf("arr[%d] is %s \n", i, s) fmt.Printf("arr[%d] is %s \n", i, s)
fn(i) fn(i)
} }
fmt.Println("arr is", arr) fmt.Println("arr is", arr)
for i := 0; i < len(arr); i++ { for i := 0; i < len(arr); i++ {
print(i, arr[i], f) print(i, arr[i], f)
} }
//output: //output:
// arr is [a b] // arr is [a b]
@@ -78,8 +83,6 @@ func main() {
} }
``` ```
### <span id="Before">Before</span> ### <span id="Before">Before</span>
<p>创建一个函数调用次数不超过n次之后再调用这个函数将返回一次最后调用fn的结果</p> <p>创建一个函数调用次数不超过n次之后再调用这个函数将返回一次最后调用fn的结果</p>
@@ -89,6 +92,7 @@ func main() {
```go ```go
func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value func Before(n int, fn interface{}) func(args ...interface{}) []reflect.Value
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -101,31 +105,29 @@ import (
) )
func main() { func main() {
assert := internal.NewAssert(t, "TestBefore") assert := internal.NewAssert(t, "TestBefore")
arr := []string{"a", "b", "c", "d", "e"} arr := []string{"a", "b", "c", "d", "e"}
f := function.Before(3, func(i int) int { f := function.Before(3, func(i int) int {
return i return i
}) })
var res []int64 var res []int64
type cb func(args ...interface{}) []reflect.Value type cb func(args ...interface{}) []reflect.Value
appendStr := func(i int, s string, fn cb) { appendStr := func(i int, s string, fn cb) {
v := fn(i) v := fn(i)
res = append(res, v[0].Int()) res = append(res, v[0].Int())
} }
for i := 0; i < len(arr); i++ { for i := 0; i < len(arr); i++ {
appendStr(i, arr[i], f) appendStr(i, arr[i], f)
} }
expected := []int64{0, 1, 2, 2, 2} expected := []int64{0, 1, 2, 2, 2}
assert.Equal(expected, res) assert.Equal(expected, res)
} }
``` ```
### <span id="Curry">Curry</span> ### <span id="Curry">Curry</span>
<p>创建一个柯里化的函数</p> <p>创建一个柯里化的函数</p>
@@ -136,6 +138,7 @@ func main() {
type Fn func(...interface{}) interface{} type Fn func(...interface{}) interface{}
func (f Fn) Curry(i interface{}) func(...interface{}) interface{} func (f Fn) Curry(i interface{}) func(...interface{}) interface{}
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -147,20 +150,18 @@ import (
) )
func main() { func main() {
add := func(a, b int) int { add := func(a, b int) int {
return a + b return a + b
} }
var addCurry function.Fn = func(values ...interface{}) interface{} { var addCurry function.Fn = func(values ...interface{}) interface{} {
return add(values[0].(int), values[1].(int)) return add(values[0].(int), values[1].(int))
} }
add1 := addCurry.Curry(1) add1 := addCurry.Curry(1)
result := add1(2) result := add1(2)
fmt.Println(result) //3 fmt.Println(result) //3
} }
``` ```
### <span id="Compose">Compose</span> ### <span id="Compose">Compose</span>
<p>从右至左组合函数列表fnList 返回组合后的函数</p> <p>从右至左组合函数列表fnList 返回组合后的函数</p>
@@ -170,6 +171,7 @@ func main() {
```go ```go
func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) interface{} func Compose(fnList ...func(...interface{}) interface{}) func(...interface{}) interface{}
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -181,22 +183,20 @@ import (
) )
func main() { func main() {
add1 := func(v ...interface{}) interface{} { add1 := func(v ...interface{}) interface{} {
return v[0].(int) + 1 return v[0].(int) + 1
} }
add2 := func(v ...interface{}) interface{} { add2 := func(v ...interface{}) interface{} {
return v[0].(int) + 2 return v[0].(int) + 2
} }
add3 := function.Compose(add1, add2) add3 := function.Compose(add1, add2)
result := add3(1) result := add3(1)
fmt.Println(result) //4 fmt.Println(result) //4
} }
``` ```
### <span id="Debounced">Debounced</span> ### <span id="Debounced">Debounced</span>
<p>创建一个 debounced 函数,该函数延迟调用 fn 直到自上次调用 debounced 函数后等待持续时间过去。</p> <p>创建一个 debounced 函数,该函数延迟调用 fn 直到自上次调用 debounced 函数后等待持续时间过去。</p>
@@ -206,6 +206,7 @@ func main() {
```go ```go
func Debounced(fn func(), duration time.Duration) func() func Debounced(fn func(), duration time.Duration) func()
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -217,28 +218,26 @@ import (
) )
func main() { func main() {
count := 0 count := 0
add := func() { add := func() {
count++ count++
} }
debouncedAdd := function.Debounced(add, 50*time.Microsecond) debouncedAdd := function.Debounced(add, 50*time.Microsecond)
function.debouncedAdd() function.debouncedAdd()
function.debouncedAdd() function.debouncedAdd()
function.debouncedAdd() function.debouncedAdd()
function.debouncedAdd() function.debouncedAdd()
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
fmt.Println(count) //1 fmt.Println(count) //1
function.debouncedAdd() function.debouncedAdd()
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
fmt.Println(count) //2 fmt.Println(count) //2
} }
``` ```
### <span id="Delay">Delay</span> ### <span id="Delay">Delay</span>
<p>延迟delay时间后调用函数</p> <p>延迟delay时间后调用函数</p>
@@ -248,6 +247,7 @@ func main() {
```go ```go
func Delay(delay time.Duration, fn interface{}, args ...interface{}) func Delay(delay time.Duration, fn interface{}, args ...interface{})
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -259,15 +259,13 @@ import (
) )
func main() { func main() {
var print = func(s string) { var print = func(s string) {
fmt.Println(count) //test delay fmt.Println(count) //test delay
} }
function.Delay(2*time.Second, print, "test delay") function.Delay(2*time.Second, print, "test delay")
} }
``` ```
### <span id="Schedule">Schedule</span> ### <span id="Schedule">Schedule</span>
<p>每次持续时间调用函数,直到关闭返回的 bool chan</p> <p>每次持续时间调用函数,直到关闭返回的 bool chan</p>
@@ -277,6 +275,7 @@ func main() {
```go ```go
func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -289,19 +288,59 @@ import (
func main() { func main() {
var res []string var res []string
appendStr := func(s string) { appendStr := func(s string) {
res = append(res, s) res = append(res, s)
} }
stop := function.Schedule(1*time.Second, appendStr, "*") stop := function.Schedule(1*time.Second, appendStr, "*")
time.Sleep(5 * time.Second) time.Sleep(5 * time.Second)
close(stop) close(stop)
fmt.Println(res) //[* * * * *] fmt.Println(res) //[* * * * *]
} }
``` ```
### <span id="Pipeline">Pipeline</span>
<p>管道执行多个函数</p>
<b>函数签名:</b>
```go
func Pipeline(funcs ...func(interface{}) interface{}) func(interface{}) interface{}
```
<b>例子:</b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/function"
)
func main() {
addOne := func(x interface{}) interface{} {
return x.(int) + 1
}
double := func(x interface{}) interface{} {
return 2 * x.(int)
}
square := func(x interface{}) interface{} {
return x.(int) * x.(int)
}
f := function.Pipeline(addOne, double, square)
result := fn(2)
fmt.Println(result)
// Output:
// 36
}
```
### <span id="Watcher">Watcher</span> ### <span id="Watcher">Watcher</span>
@@ -311,15 +350,16 @@ func main() {
```go ```go
type Watcher struct { type Watcher struct {
startTime int64 startTime int64
stopTime int64 stopTime int64
excuting bool excuting bool
} }
func (w *Watcher) Start() //start the watcher func (w *Watcher) Start() //start the watcher
func (w *Watcher) Stop() //stop the watcher func (w *Watcher) Stop() //stop the watcher
func (w *Watcher) Reset() //reset the watcher func (w *Watcher) Reset() //reset the watcher
func (w *Watcher) GetElapsedTime() time.Duration //get the elapsed time of function execution func (w *Watcher) GetElapsedTime() time.Duration //get the elapsed time of function execution
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -332,33 +372,30 @@ import (
func main() { func main() {
w := &function.Watcher{} w := &function.Watcher{}
w.Start() w.Start()
longRunningTask() longRunningTask()
fmt.Println(w.excuting) //true fmt.Println(w.excuting) //true
w.Stop() w.Stop()
eapsedTime := w.GetElapsedTime().Milliseconds() eapsedTime := w.GetElapsedTime().Milliseconds()
fmt.Println(eapsedTime) fmt.Println(eapsedTime)
w.Reset() w.Reset()
fmt.Println(w.excuting) //false fmt.Println(w.excuting) //false
fmt.Println(w.startTime) //0 fmt.Println(w.startTime) //0
fmt.Println(w.stopTime) //0 fmt.Println(w.stopTime) //0
} }
func longRunningTask() { func longRunningTask() {
var slice []int64 var slice []int64
for i := 0; i < 10000000; i++ { for i := 0; i < 10000000; i++ {
slice = append(slice, int64(i)) slice = append(slice, int64(i))
} }
} }
``` ```

View File

@@ -1,4 +1,5 @@
# Mathutil # Mathutil
Package mathutil implements some functions for math calculation. Package mathutil implements some functions for math calculation.
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -7,10 +8,10 @@ Package mathutil implements some functions for math calculation.
[https://github.com/duke-git/lancet/blob/v1/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/v1/mathutil/mathutil.go) [https://github.com/duke-git/lancet/blob/v1/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/v1/mathutil/mathutil.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Example: ## Example:
```go ```go
import ( import (
"github.com/duke-git/lancet/mathutil" "github.com/duke-git/lancet/mathutil"
@@ -20,20 +21,21 @@ import (
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Index ## Index
- [Exponent](#Exponent)
- [Fibonacci](#Fibonacci) - [Exponent](#Exponent)
- [Factorial](#Factorial) - [Fibonacci](#Fibonacci)
- [Percent](#Percent) - [Factorial](#Factorial)
- [RoundToFloat](#RoundToFloat) - [Percent](#Percent)
- [RoundToString](#RoundToString) - [RoundToFloat](#RoundToFloat)
- [TruncRound](#TruncRound) - [RoundToString](#RoundToString)
- [TruncRound](#TruncRound)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Documentation ## Documentation
### <span id="Exponent">Exponent</span> ### <span id="Exponent">Exponent</span>
<p>Calculate x to the nth power.</p> <p>Calculate x to the nth power.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -41,6 +43,7 @@ import (
```go ```go
func Exponent(x, n int64) int64 func Exponent(x, n int64) int64
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -52,15 +55,14 @@ import (
) )
func main() { func main() {
fmt.Println(mathutil.Exponent(10, 0)) //1 fmt.Println(mathutil.Exponent(10, 0)) //1
fmt.Println(mathutil.Exponent(10, 1)) //10 fmt.Println(mathutil.Exponent(10, 1)) //10
fmt.Println(mathutil.Exponent(10, 2)) //100 fmt.Println(mathutil.Exponent(10, 2)) //100
} }
``` ```
### <span id="Fibonacci">Fibonacci</span> ### <span id="Fibonacci">Fibonacci</span>
<p>Calculate the nth number of fibonacci sequence.</p> <p>Calculate the nth number of fibonacci sequence.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -68,6 +70,7 @@ func main() {
```go ```go
func Fibonacci(first, second, n int) int func Fibonacci(first, second, n int) int
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -79,17 +82,16 @@ import (
) )
func main() { func main() {
fmt.Println(mathutil.Fibonacci(1, 1, 1)) //1 fmt.Println(mathutil.Fibonacci(1, 1, 1)) //1
fmt.Println(mathutil.Fibonacci(1, 1, 2)) //1 fmt.Println(mathutil.Fibonacci(1, 1, 2)) //1
fmt.Println(mathutil.Fibonacci(1, 1, 3)) //2 fmt.Println(mathutil.Fibonacci(1, 1, 3)) //2
fmt.Println(mathutil.Fibonacci(1, 1, 4)) //3 fmt.Println(mathutil.Fibonacci(1, 1, 4)) //3
fmt.Println(mathutil.Fibonacci(1, 1, 5)) //5 fmt.Println(mathutil.Fibonacci(1, 1, 5)) //5
} }
``` ```
### <span id="Factorial">Factorial</span> ### <span id="Factorial">Factorial</span>
<p>Calculate the factorial of x.</p> <p>Calculate the factorial of x.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -97,6 +99,7 @@ func main() {
```go ```go
func Factorial(x uint) uint func Factorial(x uint) uint
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -108,16 +111,15 @@ import (
) )
func main() { func main() {
fmt.Println(mathutil.Factorial(0)) //1 fmt.Println(mathutil.Factorial(0)) //1
fmt.Println(mathutil.Factorial(1)) //1 fmt.Println(mathutil.Factorial(1)) //1
fmt.Println(mathutil.Factorial(2)) //2 fmt.Println(mathutil.Factorial(2)) //2
fmt.Println(mathutil.Factorial(3)) //6 fmt.Println(mathutil.Factorial(3)) //6
} }
``` ```
### <span id="Percent">Percent</span> ### <span id="Percent">Percent</span>
<p>calculate the percentage of val to total, retain n decimal places.</p> <p>calculate the percentage of val to total, retain n decimal places.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -125,6 +127,7 @@ func main() {
```go ```go
func Percent(val, total float64, n int) float64 func Percent(val, total float64, n int) float64
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -136,14 +139,13 @@ import (
) )
func main() { func main() {
fmt.Println(mathutil.Percent(1, 2, 2)) //1 fmt.Println(mathutil.Percent(1, 2, 2)) //1
fmt.Println(mathutil.Percent(0.1, 0.3, 2)) //33.33 fmt.Println(mathutil.Percent(0.1, 0.3, 2)) //33.33
} }
``` ```
### <span id="RoundToFloat">RoundToFloat</span> ### <span id="RoundToFloat">RoundToFloat</span>
<p>Round float up to n decimal places.</p> <p>Round float up to n decimal places.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -151,6 +153,7 @@ func main() {
```go ```go
func RoundToFloat(x float64, n int) float64 func RoundToFloat(x float64, n int) float64
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -162,18 +165,16 @@ import (
) )
func main() { func main() {
fmt.Println(mathutil.RoundToFloat(0, 0)) //0 fmt.Println(mathutil.RoundToFloat(0, 0)) //0
fmt.Println(mathutil.RoundToFloat(0, 1)) //0 fmt.Println(mathutil.RoundToFloat(0, 1)) //0
fmt.Println(mathutil.RoundToFloat(0.124, 2)) //0.12 fmt.Println(mathutil.RoundToFloat(0.124, 2)) //0.12
fmt.Println(mathutil.RoundToFloat(0.125, 2)) //0.13 fmt.Println(mathutil.RoundToFloat(0.125, 2)) //0.13
fmt.Println(mathutil.RoundToFloat(0.125, 3)) //0.125 fmt.Println(mathutil.RoundToFloat(0.125, 3)) //0.125
} }
``` ```
### <span id="RoundToString">RoundToString</span> ### <span id="RoundToString">RoundToString</span>
<p>Round float up to n decimal places. will return string.</p> <p>Round float up to n decimal places. will return string.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -181,6 +182,7 @@ func main() {
```go ```go
func RoundToString(x float64, n int) string func RoundToString(x float64, n int) string
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -192,17 +194,16 @@ import (
) )
func main() { func main() {
fmt.Println(mathutil.RoundToString(0, 0)) //"0" fmt.Println(mathutil.RoundToString(0, 0)) //"0"
fmt.Println(mathutil.RoundToString(0, 1)) //"0.0: fmt.Println(mathutil.RoundToString(0, 1)) //"0.0:
fmt.Println(mathutil.RoundToString(0.124, 2)) //"0.12" fmt.Println(mathutil.RoundToString(0.124, 2)) //"0.12"
fmt.Println(mathutil.RoundToString(0.125, 2)) //"0.13" fmt.Println(mathutil.RoundToString(0.125, 2)) //"0.13"
fmt.Println(mathutil.RoundToString(0.125, 3)) //"0.125" fmt.Println(mathutil.RoundToString(0.125, 3)) //"0.125"
} }
``` ```
### <span id="TruncRound">TruncRound</span> ### <span id="TruncRound">TruncRound</span>
<p>Round float off n decimal places.</p> <p>Round float off n decimal places.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -210,6 +211,7 @@ func main() {
```go ```go
func TruncRound(x float64, n int) float64 func TruncRound(x float64, n int) float64
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -221,13 +223,10 @@ import (
) )
func main() { func main() {
fmt.Println(mathutil.TruncRound(0, 0)) //0 fmt.Println(mathutil.TruncRound(0, 0)) //0
fmt.Println(mathutil.TruncRound(0, 1)) //0 fmt.Println(mathutil.TruncRound(0, 1)) //0
fmt.Println(mathutil.TruncRound(0.124, 2)) //0.12 fmt.Println(mathutil.TruncRound(0.124, 2)) //0.12
fmt.Println(mathutil.TruncRound(0.125, 2)) //0.12 fmt.Println(mathutil.TruncRound(0.125, 2)) //0.12
fmt.Println(mathutil.TruncRound(0.125, 3)) //0.125 fmt.Println(mathutil.TruncRound(0.125, 3)) //0.125
} }
``` ```

View File

@@ -1,5 +1,6 @@
# Mathutil # Mathutil
mathutil包实现了一些数学计算的函数.
mathutil 包实现了一些数学计算的函数.
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -7,10 +8,10 @@ mathutil包实现了一些数学计算的函数.
[https://github.com/duke-git/lancet/blob/v1/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/v1/mathutil/mathutil.go) [https://github.com/duke-git/lancet/blob/v1/mathutil/mathutil.go](https://github.com/duke-git/lancet/blob/v1/mathutil/mathutil.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/mathutil" "github.com/duke-git/lancet/mathutil"
@@ -20,21 +21,22 @@ import (
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 目录 ## 目录
- [Exponent](#Exponent)
- [Fibonacci](#Fibonacci)
- [Factorial](#Factorial)
- [Percent](#Percent) - [Exponent](#Exponent)
- [RoundToFloat](#RoundToFloat) - [Fibonacci](#Fibonacci)
- [RoundToString](#RoundToString) - [Factorial](#Factorial)
- [TruncRound](#TruncRound)
- [Percent](#Percent)
- [RoundToFloat](#RoundToFloat)
- [RoundToString](#RoundToString)
- [TruncRound](#TruncRound)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Documentation ## Documentation
### <span id="Exponent">Exponent</span> ### <span id="Exponent">Exponent</span>
<p>指数计算x的n次方</p> <p>指数计算x的n次方</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -42,6 +44,7 @@ import (
```go ```go
func Exponent(x, n int64) int64 func Exponent(x, n int64) int64
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -53,15 +56,14 @@ import (
) )
func main() { func main() {
fmt.Println(mathutil.Exponent(10, 0)) //1 fmt.Println(mathutil.Exponent(10, 0)) //1
fmt.Println(mathutil.Exponent(10, 1)) //10 fmt.Println(mathutil.Exponent(10, 1)) //10
fmt.Println(mathutil.Exponent(10, 2)) //100 fmt.Println(mathutil.Exponent(10, 2)) //100
} }
``` ```
### <span id="Fibonacci">Fibonacci</span> ### <span id="Fibonacci">Fibonacci</span>
<p>计算斐波那契数列的第n个数</p> <p>计算斐波那契数列的第n个数</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -69,6 +71,7 @@ func main() {
```go ```go
func Fibonacci(first, second, n int) int func Fibonacci(first, second, n int) int
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -80,17 +83,16 @@ import (
) )
func main() { func main() {
fmt.Println(mathutil.Fibonacci(1, 1, 1)) //1 fmt.Println(mathutil.Fibonacci(1, 1, 1)) //1
fmt.Println(mathutil.Fibonacci(1, 1, 2)) //1 fmt.Println(mathutil.Fibonacci(1, 1, 2)) //1
fmt.Println(mathutil.Fibonacci(1, 1, 3)) //2 fmt.Println(mathutil.Fibonacci(1, 1, 3)) //2
fmt.Println(mathutil.Fibonacci(1, 1, 4)) //3 fmt.Println(mathutil.Fibonacci(1, 1, 4)) //3
fmt.Println(mathutil.Fibonacci(1, 1, 5)) //5 fmt.Println(mathutil.Fibonacci(1, 1, 5)) //5
} }
``` ```
### <span id="Factorial">Factorial</span> ### <span id="Factorial">Factorial</span>
<p>计算阶乘</p> <p>计算阶乘</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -98,6 +100,7 @@ func main() {
```go ```go
func Factorial(x uint) uint func Factorial(x uint) uint
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -109,16 +112,15 @@ import (
) )
func main() { func main() {
fmt.Println(mathutil.Factorial(0)) //1 fmt.Println(mathutil.Factorial(0)) //1
fmt.Println(mathutil.Factorial(1)) //1 fmt.Println(mathutil.Factorial(1)) //1
fmt.Println(mathutil.Factorial(2)) //2 fmt.Println(mathutil.Factorial(2)) //2
fmt.Println(mathutil.Factorial(3)) //6 fmt.Println(mathutil.Factorial(3)) //6
} }
``` ```
### <span id="Percent">Percent</span> ### <span id="Percent">Percent</span>
<p>计算百分比保留n位小数</p> <p>计算百分比保留n位小数</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -126,6 +128,7 @@ func main() {
```go ```go
func Percent(val, total float64, n int) float64 func Percent(val, total float64, n int) float64
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -137,14 +140,13 @@ import (
) )
func main() { func main() {
fmt.Println(mathutil.Percent(1, 2, 2)) //1 fmt.Println(mathutil.Percent(1, 2, 2)) //1
fmt.Println(mathutil.Percent(0.1, 0.3, 2)) //33.33 fmt.Println(mathutil.Percent(0.1, 0.3, 2)) //33.33
} }
``` ```
### <span id="RoundToFloat">RoundToFloat</span> ### <span id="RoundToFloat">RoundToFloat</span>
<p>四舍五入保留n位小数</p> <p>四舍五入保留n位小数</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -152,6 +154,7 @@ func main() {
```go ```go
func RoundToFloat(x float64, n int) float64 func RoundToFloat(x float64, n int) float64
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -163,18 +166,16 @@ import (
) )
func main() { func main() {
fmt.Println(mathutil.RoundToFloat(0, 0)) //0 fmt.Println(mathutil.RoundToFloat(0, 0)) //0
fmt.Println(mathutil.RoundToFloat(0, 1)) //0 fmt.Println(mathutil.RoundToFloat(0, 1)) //0
fmt.Println(mathutil.RoundToFloat(0.124, 2)) //0.12 fmt.Println(mathutil.RoundToFloat(0.124, 2)) //0.12
fmt.Println(mathutil.RoundToFloat(0.125, 2)) //0.13 fmt.Println(mathutil.RoundToFloat(0.125, 2)) //0.13
fmt.Println(mathutil.RoundToFloat(0.125, 3)) //0.125 fmt.Println(mathutil.RoundToFloat(0.125, 3)) //0.125
} }
``` ```
### <span id="RoundToString">RoundToString</span> ### <span id="RoundToString">RoundToString</span>
<p>四舍五入保留n位小数返回字符串</p> <p>四舍五入保留n位小数返回字符串</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -182,6 +183,7 @@ func main() {
```go ```go
func RoundToString(x float64, n int) string func RoundToString(x float64, n int) string
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -193,17 +195,16 @@ import (
) )
func main() { func main() {
fmt.Println(mathutil.RoundToString(0, 0)) //"0" fmt.Println(mathutil.RoundToString(0, 0)) //"0"
fmt.Println(mathutil.RoundToString(0, 1)) //"0.0: fmt.Println(mathutil.RoundToString(0, 1)) //"0.0:
fmt.Println(mathutil.RoundToString(0.124, 2)) //"0.12" fmt.Println(mathutil.RoundToString(0.124, 2)) //"0.12"
fmt.Println(mathutil.RoundToString(0.125, 2)) //"0.13" fmt.Println(mathutil.RoundToString(0.125, 2)) //"0.13"
fmt.Println(mathutil.RoundToString(0.125, 3)) //"0.125" fmt.Println(mathutil.RoundToString(0.125, 3)) //"0.125"
} }
``` ```
### <span id="TruncRound">TruncRound</span> ### <span id="TruncRound">TruncRound</span>
<p>截短n位小数不进行四舍五入</p> <p>截短n位小数不进行四舍五入</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -211,6 +212,7 @@ func main() {
```go ```go
func TruncRound(x float64, n int) float64 func TruncRound(x float64, n int) float64
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -222,13 +224,10 @@ import (
) )
func main() { func main() {
fmt.Println(mathutil.TruncRound(0, 0)) //0 fmt.Println(mathutil.TruncRound(0, 0)) //0
fmt.Println(mathutil.TruncRound(0, 1)) //0 fmt.Println(mathutil.TruncRound(0, 1)) //0
fmt.Println(mathutil.TruncRound(0.124, 2)) //0.12 fmt.Println(mathutil.TruncRound(0.124, 2)) //0.12
fmt.Println(mathutil.TruncRound(0.125, 2)) //0.12 fmt.Println(mathutil.TruncRound(0.125, 2)) //0.12
fmt.Println(mathutil.TruncRound(0.125, 3)) //0.125 fmt.Println(mathutil.TruncRound(0.125, 3)) //0.125
} }
``` ```

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -26,7 +26,6 @@ import (
- [RandInt](#RandInt) - [RandInt](#RandInt)
- [RandString](#RandString) - [RandString](#RandString)
- [RandUpper](#RandUpper) - [RandUpper](#RandUpper)
- [RandLower](#RandLower) - [RandLower](#RandLower)
- [RandNumeral](#RandNumeral) - [RandNumeral](#RandNumeral)
- [RandNumeralOrLetter](#RandNumeralOrLetter) - [RandNumeralOrLetter](#RandNumeralOrLetter)
@@ -57,8 +56,8 @@ import (
) )
func main() { func main() {
randBytes := random.RandBytes(4) randBytes := random.RandBytes(4)
fmt.Println(randBytes) fmt.Println(randBytes)
} }
``` ```
@@ -83,8 +82,8 @@ import (
) )
func main() { func main() {
rInt := random.RandInt(1, 10) rInt := random.RandInt(1, 10)
fmt.Println(rInt) fmt.Println(rInt)
} }
``` ```
@@ -109,8 +108,8 @@ import (
) )
func main() { func main() {
randStr := random.RandString(6) randStr := random.RandString(6)
fmt.Println(randStr) //pGWsze fmt.Println(randStr) //pGWsze
} }
``` ```
@@ -135,8 +134,8 @@ import (
) )
func main() { func main() {
randStr := random.RandString(6) randStr := random.RandString(6)
fmt.Println(randStr) //PACWGF fmt.Println(randStr) //PACWGF
} }
``` ```
@@ -161,8 +160,8 @@ import (
) )
func main() { func main() {
randStr := random.RandLower(6) randStr := random.RandLower(6)
fmt.Println(randStr) //siqbew fmt.Println(randStr) //siqbew
} }
``` ```
@@ -187,8 +186,8 @@ import (
) )
func main() { func main() {
randStr := random.RandNumeral(6) randStr := random.RandNumeral(6)
fmt.Println(randStr) //035172 fmt.Println(randStr) //035172
} }
``` ```
@@ -213,8 +212,8 @@ import (
) )
func main() { func main() {
randStr := random.RandNumeralOrLetter(6) randStr := random.RandNumeralOrLetter(6)
fmt.Println(randStr) //0aW7cQ fmt.Println(randStr) //0aW7cQ
} }
``` ```
@@ -239,10 +238,10 @@ import (
) )
func main() { func main() {
uuid, err := random.UUIdV4() uuid, err := random.UUIdV4()
if err != nil { if err != nil {
return return
} }
fmt.Println(uuid) fmt.Println(uuid)
} }
``` ```

View File

@@ -26,7 +26,6 @@ import (
- [RandInt](#RandInt) - [RandInt](#RandInt)
- [RandString](#RandString) - [RandString](#RandString)
- [RandUpper](#RandUpper) - [RandUpper](#RandUpper)
- [RandLower](#RandLower) - [RandLower](#RandLower)
- [RandNumeral](#RandNumeral) - [RandNumeral](#RandNumeral)
- [RandNumeralOrLetter](#RandNumeralOrLetter) - [RandNumeralOrLetter](#RandNumeralOrLetter)
@@ -57,8 +56,8 @@ import (
) )
func main() { func main() {
randBytes := random.RandBytes(4) randBytes := random.RandBytes(4)
fmt.Println(randBytes) fmt.Println(randBytes)
} }
``` ```
@@ -83,8 +82,8 @@ import (
) )
func main() { func main() {
rInt := random.RandInt(1, 10) rInt := random.RandInt(1, 10)
fmt.Println(rInt) fmt.Println(rInt)
} }
``` ```
@@ -109,8 +108,8 @@ import (
) )
func main() { func main() {
randStr := random.RandString(6) randStr := random.RandString(6)
fmt.Println(randStr) //pGWsze fmt.Println(randStr) //pGWsze
} }
``` ```
@@ -135,8 +134,8 @@ import (
) )
func main() { func main() {
randStr := random.RandString(6) randStr := random.RandString(6)
fmt.Println(randStr) //PACWGF fmt.Println(randStr) //PACWGF
} }
``` ```
@@ -161,8 +160,8 @@ import (
) )
func main() { func main() {
randStr := random.RandLower(6) randStr := random.RandLower(6)
fmt.Println(randStr) //siqbew fmt.Println(randStr) //siqbew
} }
``` ```
@@ -187,8 +186,8 @@ import (
) )
func main() { func main() {
randStr := random.RandNumeral(6) randStr := random.RandNumeral(6)
fmt.Println(randStr) //035172 fmt.Println(randStr) //035172
} }
``` ```
@@ -213,8 +212,8 @@ import (
) )
func main() { func main() {
randStr := random.RandNumeralOrLetter(6) randStr := random.RandNumeralOrLetter(6)
fmt.Println(randStr) //0aW7cQ fmt.Println(randStr) //0aW7cQ
} }
``` ```
@@ -239,10 +238,10 @@ import (
) )
func main() { func main() {
uuid, err := random.UUIdV4() uuid, err := random.UUIdV4()
if err != nil { if err != nil {
return return
} }
fmt.Println(uuid) fmt.Println(uuid)
} }
``` ```

View File

@@ -1,4 +1,5 @@
# Retry # Retry
Package retry is for executing a function repeatedly until it was successful or canceled by the context. Package retry is for executing a function repeatedly until it was successful or canceled by the context.
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -7,10 +8,10 @@ Package retry is for executing a function repeatedly until it was successful or
[https://github.com/duke-git/lancet/blob/v1/retry/retry.go](https://github.com/duke-git/lancet/blob/v1/retry/retry.go) [https://github.com/duke-git/lancet/blob/v1/retry/retry.go](https://github.com/duke-git/lancet/blob/v1/retry/retry.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/retry" "github.com/duke-git/lancet/retry"
@@ -20,18 +21,19 @@ import (
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Index ## Index
- [Context](#Context)
- [Retry](#Retry) - [Context](#Context)
- [RetryFunc](#RetryFunc) - [Retry](#Retry)
- [RetryDuration](#RetryDuration) - [RetryFunc](#RetryFunc)
- [RetryTimes](#RetryTimes) - [RetryDuration](#RetryDuration)
- [RetryTimes](#RetryTimes)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Documentation ## Documentation
### <span id="Context">Context</span> ### <span id="Context">Context</span>
<p>Set retry context config, can cancel the retry with context.</p> <p>Set retry context config, can cancel the retry with context.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -39,43 +41,42 @@ import (
```go ```go
func Context(ctx context.Context) func Context(ctx context.Context)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"github.com/duke-git/lancet/retry" "github.com/duke-git/lancet/retry"
"time" "time"
) )
func main() { func main() {
ctx, cancel := context.WithCancel(context.TODO()) ctx, cancel := context.WithCancel(context.TODO())
var number int var number int
increaseNumber := func() error { increaseNumber := func() error {
number++ number++
if number > 3 { if number > 3 {
cancel() cancel()
} }
return errors.New("error occurs") return errors.New("error occurs")
} }
err := retry.Retry(increaseNumber, err := retry.Retry(increaseNumber,
retry.RetryDuration(time.Microsecond*50), retry.RetryDuration(time.Microsecond*50),
retry.Context(ctx), retry.Context(ctx),
) )
if err != nil { if err != nil {
fmt.Println(err) //retry is cancelled fmt.Println(err) //retry is cancelled
} }
} }
``` ```
### <span id="RetryFunc">RetryFunc</span> ### <span id="RetryFunc">RetryFunc</span>
<p>Function that retry executes.</p> <p>Function that retry executes.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -83,6 +84,7 @@ func main() {
```go ```go
type RetryFunc func() error type RetryFunc func() error
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -98,26 +100,25 @@ import (
func main() { func main() {
var number int var number int
var increaseNumber retry.RetryFunc var increaseNumber retry.RetryFunc
increaseNumber = func() error { increaseNumber = func() error {
number++ number++
if number == 3 { if number == 3 {
return nil return nil
} }
return errors.New("error occurs") return errors.New("error occurs")
} }
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50)) err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
fmt.Println(number) //3 fmt.Println(number) //3
} }
``` ```
### <span id="RetryTimes">RetryTimes</span> ### <span id="RetryTimes">RetryTimes</span>
<p>Set times of retry. Default times is 5.</p> <p>Set times of retry. Default times is 5.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -125,6 +126,7 @@ func main() {
```go ```go
func RetryTimes(n uint) func RetryTimes(n uint)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -139,24 +141,23 @@ import (
func main() { func main() {
var number int var number int
increaseNumber := func() error { increaseNumber := func() error {
number++ number++
if number == 3 { if number == 3 {
return nil return nil
} }
return errors.New("error occurs") return errors.New("error occurs")
} }
err := retry.Retry(increaseNumber, retry.RetryTimes(2)) err := retry.Retry(increaseNumber, retry.RetryTimes(2))
if err != nil { 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 log.Fatal(err) //2022/02/01 18:42:25 function main.main.func1 run failed after 2 times retry exit status 1
} }
} }
``` ```
### <span id="RetryDuration">RetryDuration</span> ### <span id="RetryDuration">RetryDuration</span>
<p>Set duration of retries. Default duration is 3 second.</p> <p>Set duration of retries. Default duration is 3 second.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -164,6 +165,7 @@ func main() {
```go ```go
func RetryDuration(d time.Duration) func RetryDuration(d time.Duration)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -178,25 +180,25 @@ import (
func main() { func main() {
var number int var number int
increaseNumber := func() error { increaseNumber := func() error {
number++ number++
if number == 3 { if number == 3 {
return nil return nil
} }
return errors.New("error occurs") return errors.New("error occurs")
} }
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50)) err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
fmt.Println(number) //3 fmt.Println(number) //3
} }
``` ```
### <span id="Retry">Retry</span> ### <span id="Retry">Retry</span>
<p>Executes the retryFunc repeatedly until it was successful or canceled by the context.</p> <p>Executes the retryFunc repeatedly until it was successful or canceled by the context.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -204,6 +206,7 @@ func main() {
```go ```go
func Retry(retryFunc RetryFunc, opts ...Option) error func Retry(retryFunc RetryFunc, opts ...Option) error
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
@@ -218,18 +221,18 @@ import (
func main() { func main() {
var number int var number int
increaseNumber := func() error { increaseNumber := func() error {
number++ number++
if number == 3 { if number == 3 {
return nil return nil
} }
return errors.New("error occurs") return errors.New("error occurs")
} }
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50)) err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
fmt.Println(number) //3 fmt.Println(number) //3
} }

View File

@@ -1,5 +1,6 @@
# Retry # Retry
retry重试执行函数直到函数运行成功或被context cancel。
retry 重试执行函数直到函数运行成功或被 context cancel。
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -7,10 +8,10 @@ retry重试执行函数直到函数运行成功或被context cancel。
[https://github.com/duke-git/lancet/blob/v1/retry/retry.go](https://github.com/duke-git/lancet/blob/v1/retry/retry.go) [https://github.com/duke-git/lancet/blob/v1/retry/retry.go](https://github.com/duke-git/lancet/blob/v1/retry/retry.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/retry" "github.com/duke-git/lancet/retry"
@@ -20,20 +21,19 @@ import (
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 目录 ## 目录
- [Context](#Context)
- [Retry](#Retry)
- [RetryFunc](#RetryFunc)
- [RetryDuration](#RetryDuration)
- [RetryTimes](#RetryTimes)
- [Context](#Context)
- [Retry](#Retry)
- [RetryFunc](#RetryFunc)
- [RetryDuration](#RetryDuration)
- [RetryTimes](#RetryTimes)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Document 文档
## Document文档
### <span id="Context">Context</span> ### <span id="Context">Context</span>
<p>设置重试context参数</p> <p>设置重试context参数</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -41,43 +41,42 @@ import (
```go ```go
func Context(ctx context.Context) func Context(ctx context.Context)
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"lancet-demo/retry" "lancet-demo/retry"
"time" "time"
) )
func main() { func main() {
ctx, cancel := context.WithCancel(context.TODO()) ctx, cancel := context.WithCancel(context.TODO())
var number int var number int
increaseNumber := func() error { increaseNumber := func() error {
number++ number++
if number > 3 { if number > 3 {
cancel() cancel()
} }
return errors.New("error occurs") return errors.New("error occurs")
} }
err := retry.Retry(increaseNumber, err := retry.Retry(increaseNumber,
retry.RetryDuration(time.Microsecond*50), retry.RetryDuration(time.Microsecond*50),
retry.Context(ctx), retry.Context(ctx),
) )
if err != nil { if err != nil {
fmt.Println(err) //retry is cancelled fmt.Println(err) //retry is cancelled
} }
} }
``` ```
### <span id="RetryFunc">RetryFunc</span> ### <span id="RetryFunc">RetryFunc</span>
<p>被重试执行的函数</p> <p>被重试执行的函数</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -85,6 +84,7 @@ func main() {
```go ```go
type RetryFunc func() error type RetryFunc func() error
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -100,26 +100,25 @@ import (
func main() { func main() {
var number int var number int
var increaseNumber retry.RetryFunc var increaseNumber retry.RetryFunc
increaseNumber = func() error { increaseNumber = func() error {
number++ number++
if number == 3 { if number == 3 {
return nil return nil
} }
return errors.New("error occurs") return errors.New("error occurs")
} }
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50)) err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
fmt.Println(number) //3 fmt.Println(number) //3
} }
``` ```
### <span id="RetryTimes">RetryTimes</span> ### <span id="RetryTimes">RetryTimes</span>
<p>设置重试次数默认5</p> <p>设置重试次数默认5</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -127,6 +126,7 @@ func main() {
```go ```go
func RetryTimes(n uint) func RetryTimes(n uint)
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -141,24 +141,23 @@ import (
func main() { func main() {
var number int var number int
increaseNumber := func() error { increaseNumber := func() error {
number++ number++
if number == 3 { if number == 3 {
return nil return nil
} }
return errors.New("error occurs") return errors.New("error occurs")
} }
err := retry.Retry(increaseNumber, retry.RetryTimes(2)) err := retry.Retry(increaseNumber, retry.RetryTimes(2))
if err != nil { 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 log.Fatal(err) //2022/02/01 18:42:25 function main.main.func1 run failed after 2 times retry exit status 1
} }
} }
``` ```
### <span id="RetryDuration">RetryDuration</span> ### <span id="RetryDuration">RetryDuration</span>
<p>设置重试间隔时间默认3秒</p> <p>设置重试间隔时间默认3秒</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -166,6 +165,7 @@ func main() {
```go ```go
func RetryDuration(d time.Duration) func RetryDuration(d time.Duration)
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -180,25 +180,25 @@ import (
func main() { func main() {
var number int var number int
increaseNumber := func() error { increaseNumber := func() error {
number++ number++
if number == 3 { if number == 3 {
return nil return nil
} }
return errors.New("error occurs") return errors.New("error occurs")
} }
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50)) err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
fmt.Println(number) //3 fmt.Println(number) //3
} }
``` ```
### <span id="Retry">Retry</span> ### <span id="Retry">Retry</span>
<p>重试执行函数retryFunc直到函数运行成功或被context停止</p> <p>重试执行函数retryFunc直到函数运行成功或被context停止</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -206,6 +206,7 @@ func main() {
```go ```go
func Retry(retryFunc RetryFunc, opts ...Option) error func Retry(retryFunc RetryFunc, opts ...Option) error
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
@@ -220,18 +221,18 @@ import (
func main() { func main() {
var number int var number int
increaseNumber := func() error { increaseNumber := func() error {
number++ number++
if number == 3 { if number == 3 {
return nil return nil
} }
return errors.New("error occurs") return errors.New("error occurs")
} }
err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50)) err := retry.Retry(increaseNumber, retry.RetryDuration(time.Microsecond*50))
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
fmt.Println(number) //3 fmt.Println(number) //3
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
# System # System
Package system contains some functions about os, runtime, shell command. Package system contains some functions about os, runtime, shell command.
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -7,10 +8,10 @@ Package system contains some functions about os, runtime, shell command.
[https://github.com/duke-git/lancet/blob/v1/system/os.go](https://github.com/duke-git/lancet/blob/v1/system/os.go) [https://github.com/duke-git/lancet/blob/v1/system/os.go](https://github.com/duke-git/lancet/blob/v1/system/os.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Usage: ## Usage:
```go ```go
import ( import (
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/system"
@@ -20,23 +21,23 @@ import (
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Index ## Index
- [IsWindows](#IsWindows)
- [IsLinux](#IsLinux)
- [IsMac](#IsMac)
- [GetOsEnv](#GetOsEnv)
- [SetOsEnv](#SetOsEnv)
- [RemoveOsEnv](#RemoveOsEnv)
- [CompareOsEnv](#CompareOsEnv)
- [ExecCommand](#ExecCommand)
- [GetOsBits](#GetOsBits)
- [IsWindows](#IsWindows)
- [IsLinux](#IsLinux)
- [IsMac](#IsMac)
- [GetOsEnv](#GetOsEnv)
- [SetOsEnv](#SetOsEnv)
- [RemoveOsEnv](#RemoveOsEnv)
- [CompareOsEnv](#CompareOsEnv)
- [ExecCommand](#ExecCommand)
- [GetOsBits](#GetOsBits)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Documentation ## Documentation
### <span id="IsWindows">IsWindows</span> ### <span id="IsWindows">IsWindows</span>
<p>Check if current os is windows.</p> <p>Check if current os is windows.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -44,24 +45,23 @@ import (
```go ```go
func IsWindows() bool func IsWindows() bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
isOsWindows := system.IsWindows() isOsWindows := system.IsWindows()
fmt.Println(isOsWindows) fmt.Println(isOsWindows)
} }
``` ```
### <span id="IsLinux">IsLinux</span> ### <span id="IsLinux">IsLinux</span>
<p>Check if current os is linux.</p> <p>Check if current os is linux.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -69,23 +69,23 @@ func main() {
```go ```go
func IsLinux() bool func IsLinux() bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
isOsLinux := system.IsLinux() isOsLinux := system.IsLinux()
fmt.Println(isOsLinux) fmt.Println(isOsLinux)
} }
``` ```
### <span id="IsMac">IsMac</span> ### <span id="IsMac">IsMac</span>
<p>Check if current os is macos.</p> <p>Check if current os is macos.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -93,23 +93,23 @@ func main() {
```go ```go
func IsMac() bool func IsMac() bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
isOsMac := system.IsMac isOsMac := system.IsMac
fmt.Println(isOsMac) fmt.Println(isOsMac)
} }
``` ```
### <span id="GetOsEnv">GetOsEnv</span> ### <span id="GetOsEnv">GetOsEnv</span>
<p>Gets the value of the environment variable named by the key.</p> <p>Gets the value of the environment variable named by the key.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -117,23 +117,23 @@ func main() {
```go ```go
func GetOsEnv(key string) string func GetOsEnv(key string) string
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
fooEnv := system.GetOsEnv("foo") fooEnv := system.GetOsEnv("foo")
fmt.Println(fooEnv) fmt.Println(fooEnv)
} }
``` ```
### <span id="SetOsEnv">SetOsEnv</span> ### <span id="SetOsEnv">SetOsEnv</span>
<p>Sets the value of the environment variable named by the key.</p> <p>Sets the value of the environment variable named by the key.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -141,24 +141,23 @@ func main() {
```go ```go
func SetOsEnv(key, value string) error func SetOsEnv(key, value string) error
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
err := system.SetOsEnv("foo", "foo_value") err := system.SetOsEnv("foo", "foo_value")
fmt.Println(err) fmt.Println(err)
} }
``` ```
### <span id="RemoveOsEnv">RemoveOsEnv</span> ### <span id="RemoveOsEnv">RemoveOsEnv</span>
<p>Remove a single environment variable.</p> <p>Remove a single environment variable.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -166,25 +165,25 @@ func main() {
```go ```go
func RemoveOsEnv(key string) error func RemoveOsEnv(key string) error
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
err := system.RemoveOsEnv("foo") err := system.RemoveOsEnv("foo")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
} }
``` ```
### <span id="CompareOsEnv">CompareOsEnv</span> ### <span id="CompareOsEnv">CompareOsEnv</span>
<p>Get env named by the key and compare it with comparedEnv.</p> <p>Get env named by the key and compare it with comparedEnv.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -192,25 +191,24 @@ func main() {
```go ```go
func CompareOsEnv(key, comparedEnv string) bool func CompareOsEnv(key, comparedEnv string) bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
system.SetOsEnv("foo", "foo_value") system.SetOsEnv("foo", "foo_value")
res := system.CompareOsEnv("foo", "foo_value") res := system.CompareOsEnv("foo", "foo_value")
fmt.Println(res) //true fmt.Println(res) //true
} }
``` ```
### <span id="ExecCommand">CompareOsEnv</span> ### <span id="ExecCommand">CompareOsEnv</span>
<p>use shell /bin/bash -c(linux) or cmd (windows) to execute command.</p> <p>use shell /bin/bash -c(linux) or cmd (windows) to execute command.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -218,25 +216,25 @@ func main() {
```go ```go
func ExecCommand(command string) (stdout, stderr string, err error) func ExecCommand(command string) (stdout, stderr string, err error)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
out, errout, err := system.ExecCommand("ls") out, errout, err := system.ExecCommand("ls")
fmt.Println(out) fmt.Println(out)
fmt.Println(errout) fmt.Println(errout)
fmt.Println(err) fmt.Println(err)
} }
``` ```
### <span id="GetOsBits">GetOsBits</span> ### <span id="GetOsBits">GetOsBits</span>
<p>获取当前操作系统位数返回32或64</p> <p>获取当前操作系统位数返回32或64</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -244,20 +242,17 @@ func main() {
```go ```go
func GetOsBits() int func GetOsBits() int
``` ```
<b>例子:</b> <b>例子:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
osBit := system.GetOsBits() osBit := system.GetOsBits()
fmt.Println(osBit) fmt.Println(osBit)
} }
``` ```

View File

@@ -1,5 +1,6 @@
# System # System
system包含os, runtime, shell command相关函数。
system 包含 os, runtime, shell command 相关函数。
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -7,10 +8,10 @@ system包含os, runtime, shell command相关函数。
[https://github.com/duke-git/lancet/blob/v1/system/os.go](https://github.com/duke-git/lancet/blob/v1/system/os.go) [https://github.com/duke-git/lancet/blob/v1/system/os.go](https://github.com/duke-git/lancet/blob/v1/system/os.go)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 用法: ## 用法:
```go ```go
import ( import (
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/system"
@@ -20,23 +21,23 @@ import (
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## 目录 ## 目录
- [IsWindows](#IsWindows)
- [IsLinux](#IsLinux)
- [IsMac](#IsMac)
- [GetOsEnv](#GetOsEnv)
- [SetOsEnv](#SetOsEnv)
- [RemoveOsEnv](#RemoveOsEnv)
- [CompareOsEnv](#CompareOsEnv)
- [ExecCommand](#ExecCommand)
- [GetOsBits](#GetOsBits)
- [IsWindows](#IsWindows)
- [IsLinux](#IsLinux)
- [IsMac](#IsMac)
- [GetOsEnv](#GetOsEnv)
- [SetOsEnv](#SetOsEnv)
- [RemoveOsEnv](#RemoveOsEnv)
- [CompareOsEnv](#CompareOsEnv)
- [ExecCommand](#ExecCommand)
- [GetOsBits](#GetOsBits)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
## Documentation文档 ## Documentation 文档
### <span id="IsWindows">IsWindows</span> ### <span id="IsWindows">IsWindows</span>
<p>检查当前操作系统是否是windows</p> <p>检查当前操作系统是否是windows</p>
<b>Signature:</b> <b>Signature:</b>
@@ -44,24 +45,23 @@ import (
```go ```go
func IsWindows() bool func IsWindows() bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
isOsWindows := system.IsWindows() isOsWindows := system.IsWindows()
fmt.Println(isOsWindows) fmt.Println(isOsWindows)
} }
``` ```
### <span id="IsLinux">IsLinux</span> ### <span id="IsLinux">IsLinux</span>
<p>检查当前操作系统是否是linux</p> <p>检查当前操作系统是否是linux</p>
<b>Signature:</b> <b>Signature:</b>
@@ -69,23 +69,23 @@ func main() {
```go ```go
func IsLinux() bool func IsLinux() bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
isOsLinux := system.IsLinux() isOsLinux := system.IsLinux()
fmt.Println(isOsLinux) fmt.Println(isOsLinux)
} }
``` ```
### <span id="IsMac">IsMac</span> ### <span id="IsMac">IsMac</span>
<p>检查当前操作系统是否是macos</p> <p>检查当前操作系统是否是macos</p>
<b>Signature:</b> <b>Signature:</b>
@@ -93,23 +93,23 @@ func main() {
```go ```go
func IsMac() bool func IsMac() bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
isOsMac := system.IsMac isOsMac := system.IsMac
fmt.Println(isOsMac) fmt.Println(isOsMac)
} }
``` ```
### <span id="GetOsEnv">GetOsEnv</span> ### <span id="GetOsEnv">GetOsEnv</span>
<p>获取key命名的环境变量的值</p> <p>获取key命名的环境变量的值</p>
<b>Signature:</b> <b>Signature:</b>
@@ -117,23 +117,23 @@ func main() {
```go ```go
func GetOsEnv(key string) string func GetOsEnv(key string) string
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
fooEnv := system.GetOsEnv("foo") fooEnv := system.GetOsEnv("foo")
fmt.Println(fooEnv) fmt.Println(fooEnv)
} }
``` ```
### <span id="SetOsEnv">SetOsEnv</span> ### <span id="SetOsEnv">SetOsEnv</span>
<p>设置由key命名的环境变量的值</p> <p>设置由key命名的环境变量的值</p>
<b>Signature:</b> <b>Signature:</b>
@@ -141,24 +141,23 @@ func main() {
```go ```go
func SetOsEnv(key, value string) error func SetOsEnv(key, value string) error
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
err := system.SetOsEnv("foo", "foo_value") err := system.SetOsEnv("foo", "foo_value")
fmt.Println(err) fmt.Println(err)
} }
``` ```
### <span id="RemoveOsEnv">RemoveOsEnv</span> ### <span id="RemoveOsEnv">RemoveOsEnv</span>
<p>删除单个环境变量</p> <p>删除单个环境变量</p>
<b>Signature:</b> <b>Signature:</b>
@@ -166,25 +165,25 @@ func main() {
```go ```go
func RemoveOsEnv(key string) error func RemoveOsEnv(key string) error
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
err := system.RemoveOsEnv("foo") err := system.RemoveOsEnv("foo")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
} }
``` ```
### <span id="CompareOsEnv">CompareOsEnv</span> ### <span id="CompareOsEnv">CompareOsEnv</span>
<p>获取key命名的环境变量值并与compareEnv进行比较</p> <p>获取key命名的环境变量值并与compareEnv进行比较</p>
<b>Signature:</b> <b>Signature:</b>
@@ -192,25 +191,24 @@ func main() {
```go ```go
func CompareOsEnv(key, comparedEnv string) bool func CompareOsEnv(key, comparedEnv string) bool
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
system.SetOsEnv("foo", "foo_value") system.SetOsEnv("foo", "foo_value")
res := system.CompareOsEnv("foo", "foo_value") res := system.CompareOsEnv("foo", "foo_value")
fmt.Println(res) //true fmt.Println(res) //true
} }
``` ```
### <span id="ExecCommand">CompareOsEnv</span> ### <span id="ExecCommand">CompareOsEnv</span>
<p>使用shell /bin/bash -c(linux) 或 cmd (windows) 执行shell命令</p> <p>使用shell /bin/bash -c(linux) 或 cmd (windows) 执行shell命令</p>
<b>Signature:</b> <b>Signature:</b>
@@ -218,25 +216,25 @@ func main() {
```go ```go
func ExecCommand(command string) (stdout, stderr string, err error) func ExecCommand(command string) (stdout, stderr string, err error)
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
out, errout, err := system.ExecCommand("ls") out, errout, err := system.ExecCommand("ls")
fmt.Println(out) fmt.Println(out)
fmt.Println(errout) fmt.Println(errout)
fmt.Println(err) fmt.Println(err)
} }
``` ```
### <span id="GetOsBits">GetOsBits</span> ### <span id="GetOsBits">GetOsBits</span>
<p>Get current os bits, 32bit or 64bit. return 32 or 64</p> <p>Get current os bits, 32bit or 64bit. return 32 or 64</p>
<b>Signature:</b> <b>Signature:</b>
@@ -244,20 +242,17 @@ func main() {
```go ```go
func GetOsBits() int func GetOsBits() int
``` ```
<b>Example:</b> <b>Example:</b>
```go ```go
import ( import (
"fmt" "fmt"
"github.com/duke-git/lancet/system" "github.com/duke-git/lancet/system"
) )
func main() { func main() {
osBit := system.GetOsBits() osBit := system.GetOsBits()
fmt.Println(osBit) fmt.Println(osBit)
} }
``` ```

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -113,3 +113,15 @@ func Schedule(d time.Duration, fn interface{}, args ...interface{}) chan bool {
return quit return quit
} }
// Pipeline takes a list of functions and returns a function whose param will be passed into
// the functions one by one.
func Pipeline(funcs ...func(interface{}) interface{}) func(interface{}) interface{} {
return func(arg interface{}) (result interface{}) {
result = arg
for _, fn := range funcs {
result = fn(result)
}
return
}
}

View File

@@ -130,3 +130,21 @@ func TestSchedule(t *testing.T) {
expected := []string{"*", "*", "*", "*", "*"} expected := []string{"*", "*", "*", "*", "*"}
assert.Equal(expected, res) assert.Equal(expected, res)
} }
func TestPipeline(t *testing.T) {
assert := internal.NewAssert(t, "TestPipeline")
addOne := func(x interface{}) interface{} {
return x.(int) + 1
}
double := func(x interface{}) interface{} {
return 2 * x.(int)
}
square := func(x interface{}) interface{} {
return x.(int) * x.(int)
}
f := Pipeline(addOne, double, square)
assert.Equal(36, f(2))
}

2
go.mod
View File

@@ -1,3 +1,5 @@
module github.com/duke-git/lancet module github.com/duke-git/lancet
go 1.16 go 1.16
require golang.org/x/text v0.5.0

25
go.sum Normal file
View File

@@ -0,0 +1,25 @@
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@@ -19,16 +19,21 @@ const (
LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
) )
func init() {
rand.Seed(time.Now().UnixNano())
}
// RandInt generate random int between min and max, maybe min, not be max // RandInt generate random int between min and max, maybe min, not be max
func RandInt(min, max int) int { func RandInt(min, max int) int {
if min == max { if min == max {
return min return min
} }
if max < min { if max < min {
min, max = max, min min, max = max, min
} }
r := rand.New(rand.NewSource(time.Now().UnixNano()))
return r.Intn(max-min) + min return rand.Intn(max-min) + min
} }
// RandBytes generate random byte slice // RandBytes generate random byte slice
@@ -72,9 +77,12 @@ func RandNumeralOrLetter(length int) string {
// random generate a random string based on given string range // random generate a random string based on given string range
func random(s string, length int) string { func random(s string, length int) string {
b := make([]byte, length) b := make([]byte, length)
r := rand.New(rand.NewSource(time.Now().UnixNano()))
// fix: https://github.com/duke-git/lancet/issues/75
// r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := range b { for i := range b {
b[i] = s[r.Int63()%int64(len(s))] b[i] = s[rand.Int63()%int64(len(s))]
} }
return string(b) return string(b)
} }

View File

@@ -5,53 +5,41 @@
package strutil package strutil
import ( import (
"regexp"
"strings" "strings"
"unicode" "unicode"
"unicode/utf8" "unicode/utf8"
) )
// CamelCase covert string to camelCase string. // CamelCase covert string to camelCase string.
// non letters and numbers will be ignored
// eg. "Foo-#1😄$_%^&*(1bar" => "foo11Bar"
func CamelCase(s string) string { func CamelCase(s string) string {
if len(s) == 0 { var builder strings.Builder
return ""
}
res := "" strs := splitIntoStrings(s, false)
blankSpace := " " for i, str := range strs {
regex, _ := regexp.Compile("[-_&]+")
ss := regex.ReplaceAllString(s, blankSpace)
for i, v := range strings.Split(ss, blankSpace) {
vv := []rune(v)
if i == 0 { if i == 0 {
if vv[i] >= 65 && vv[i] <= 96 { builder.WriteString(strings.ToLower(str))
vv[0] += 32
}
res += string(vv)
} else { } else {
res += Capitalize(v) builder.WriteString(Capitalize(str))
} }
} }
return res return builder.String()
} }
// Capitalize converts the first character of a string to upper case and the remaining to lower case. // Capitalize converts the first character of a string to upper case and the remaining to lower case.
func Capitalize(s string) string { func Capitalize(s string) string {
if len(s) == 0 { result := make([]rune, len(s))
return ""
}
out := make([]rune, len(s))
for i, v := range s { for i, v := range s {
if i == 0 { if i == 0 {
out[i] = unicode.ToUpper(v) result[i] = unicode.ToUpper(v)
} else { } else {
out[i] = unicode.ToLower(v) result[i] = unicode.ToLower(v)
} }
} }
return string(out) return string(result)
} }
// UpperFirst converts the first character of string to upper case. // UpperFirst converts the first character of string to upper case.
@@ -78,86 +66,54 @@ func LowerFirst(s string) string {
return string(r) + s[size:] return string(r) + s[size:]
} }
// PadEnd pads string on the right side if it's shorter than size. // PadStart pads string on the left and right side if it's shorter than size.
// Padding characters are truncated if they exceed size. // Padding characters are truncated if they exceed size.
func PadEnd(source string, size int, padStr string) string { func Pad(source string, size int, padStr string) string {
len1 := len(source) return padAtPosition(source, size, padStr, 0)
len2 := len(padStr)
if len1 >= size {
return source
}
fill := ""
if len2 >= size-len1 {
fill = padStr[0 : size-len1]
} else {
fill = strings.Repeat(padStr, size-len1)
}
return source + fill[0:size-len1]
} }
// PadStart pads string on the left side if it's shorter than size. // PadStart pads string on the left side if it's shorter than size.
// Padding characters are truncated if they exceed size. // Padding characters are truncated if they exceed size.
func PadStart(source string, size int, padStr string) string { func PadStart(source string, size int, padStr string) string {
len1 := len(source) return padAtPosition(source, size, padStr, 1)
len2 := len(padStr) }
if len1 >= size { // PadEnd pads string on the right side if it's shorter than size.
return source // Padding characters are truncated if they exceed size.
} func PadEnd(source string, size int, padStr string) string {
return padAtPosition(source, size, padStr, 2)
fill := ""
if len2 >= size-len1 {
fill = padStr[0 : size-len1]
} else {
fill = strings.Repeat(padStr, size-len1)
}
return fill[0:size-len1] + source
} }
// KebabCase covert string to kebab-case // KebabCase covert string to kebab-case
// non letters and numbers will be ignored
// eg. "Foo-#1😄$_%^&*(1bar" => "foo-1-1-bar"
func KebabCase(s string) string { func KebabCase(s string) string {
if len(s) == 0 { result := splitIntoStrings(s, false)
return "" return strings.Join(result, "-")
} }
regex := regexp.MustCompile(`[\W|_]+`) // UpperKebabCase covert string to upper KEBAB-CASE
blankSpace := " " // non letters and numbers will be ignored
match := regex.ReplaceAllString(s, blankSpace) // eg. "Foo-#1😄$_%^&*(1bar" => "FOO-1-1-BAR"
rs := strings.Split(match, blankSpace) func UpperKebabCase(s string) string {
result := splitIntoStrings(s, true)
var res []string return strings.Join(result, "-")
for _, v := range rs {
splitWords := splitWordsToLower(v)
if len(splitWords) > 0 {
res = append(res, splitWords...)
}
}
return strings.Join(res, "-")
} }
// SnakeCase covert string to snake_case // SnakeCase covert string to snake_case
// non letters and numbers will be ignored
// eg. "Foo-#1😄$_%^&*(1bar" => "foo_1_1_bar"
func SnakeCase(s string) string { func SnakeCase(s string) string {
if len(s) == 0 { result := splitIntoStrings(s, false)
return "" return strings.Join(result, "_")
} }
regex := regexp.MustCompile(`[\W|_]+`) // UpperSnakeCase covert string to upper SNAKE_CASE
blankSpace := " " // non letters and numbers will be ignored
match := regex.ReplaceAllString(s, blankSpace) // eg. "Foo-#1😄$_%^&*(1bar" => "FOO_1_1_BAR"
rs := strings.Split(match, blankSpace) func UpperSnakeCase(s string) string {
result := splitIntoStrings(s, true)
var res []string return strings.Join(result, "_")
for _, v := range rs {
splitWords := splitWordsToLower(v)
if len(splitWords) > 0 {
res = append(res, splitWords...)
}
}
return strings.Join(res, "_")
} }
// Before create substring in source string before position when char first appear // Before create substring in source string before position when char first appear
@@ -297,3 +253,74 @@ func SplitEx(s, sep string, removeEmptyString bool) []string {
return ret return ret
} }
// SplitWords splits a string into words, word only contains alphabetic characters.
func SplitWords(s string) []string {
var word string
var words []string
var r rune
var size, pos int
isWord := false
for len(s) > 0 {
r, size = utf8.DecodeRuneInString(s)
switch {
case isLetter(r):
if !isWord {
isWord = true
word = s
pos = 0
}
case isWord && (r == '\'' || r == '-'):
// is word
default:
if isWord {
isWord = false
words = append(words, word[:pos])
}
}
pos += size
s = s[size:]
}
if isWord {
words = append(words, word[:pos])
}
return words
}
// WordCount return the number of meaningful word, word only contains alphabetic characters.
func WordCount(s string) int {
var r rune
var size, count int
isWord := false
for len(s) > 0 {
r, size = utf8.DecodeRuneInString(s)
switch {
case isLetter(r):
if !isWord {
isWord = true
count++
}
case isWord && (r == '\'' || r == '-'):
// is word
default:
isWord = false
}
s = s[size:]
}
return count
}

View File

@@ -1,40 +1,167 @@
package strutil package strutil
import "strings" import "unicode"
// splitWordsToLower split a string into worlds by uppercase char func splitIntoStrings(s string, upperCase bool) []string {
func splitWordsToLower(s string) []string { var runes [][]rune
var res []string lastCharType := 0
charType := 0
upperIndexes := upperIndex(s) // split into fields based on type of unicode character
l := len(upperIndexes) for _, r := range s {
if upperIndexes == nil || l == 0 { switch true {
if s != "" { case isLower(r):
res = append(res, s) charType = 1
case isUpper(r):
charType = 2
case isDigit(r):
charType = 3
default:
charType = 4
} }
return res
} if charType == lastCharType {
for i := 0; i < l; i++ { runes[len(runes)-1] = append(runes[len(runes)-1], r)
if i < l-1 {
res = append(res, strings.ToLower(s[upperIndexes[i]:upperIndexes[i+1]]))
} else { } else {
res = append(res, strings.ToLower(s[upperIndexes[i]:])) runes = append(runes, []rune{r})
} }
} lastCharType = charType
return res
}
// upperIndex get a int slice which elements are all the uppercase char index of a string
func upperIndex(s string) []int {
var res []int
for i := 0; i < len(s); i++ {
if 64 < s[i] && s[i] < 91 {
res = append(res, i)
}
}
if len(s) > 0 && res != nil && res[0] != 0 {
res = append([]int{0}, res...)
} }
return res for i := 0; i < len(runes)-1; i++ {
if isUpper(runes[i][0]) && isLower(runes[i+1][0]) {
runes[i+1] = append([]rune{runes[i][len(runes[i])-1]}, runes[i+1]...)
runes[i] = runes[i][:len(runes[i])-1]
}
}
// filter all none letters and none digit
var result []string
for _, rs := range runes {
if len(rs) > 0 && (unicode.IsLetter(rs[0]) || isDigit(rs[0])) {
if upperCase {
result = append(result, string(toUpperAll(rs)))
} else {
result = append(result, string(toLowerAll(rs)))
}
}
}
return result
}
// isDigit checks if a character is digit ('0' to '9')
func isDigit(r rune) bool {
return r >= '0' && r <= '9'
}
// isLower checks if a character is lower case ('a' to 'z')
func isLower(r rune) bool {
return r >= 'a' && r <= 'z'
}
// isUpper checks if a character is upper case ('A' to 'Z')
func isUpper(r rune) bool {
return r >= 'A' && r <= 'Z'
}
// toLower converts a character 'A' to 'Z' to its lower case
func toLower(r rune) rune {
if r >= 'A' && r <= 'Z' {
return r + 32
}
return r
}
// toLowerAll converts a character 'A' to 'Z' to its lower case
func toLowerAll(rs []rune) []rune {
for i := range rs {
rs[i] = toLower(rs[i])
}
return rs
}
// toUpper converts a character 'a' to 'z' to its upper case
func toUpper(r rune) rune {
if r >= 'a' && r <= 'z' {
return r - 32
}
return r
}
// toUpperAll converts a character 'a' to 'z' to its upper case
func toUpperAll(rs []rune) []rune {
for i := range rs {
rs[i] = toUpper(rs[i])
}
return rs
}
func padAtPosition(str string, length int, padStr string, position int) string {
if len(str) >= length {
return str
}
if padStr == "" {
padStr = " "
}
length = length - len(str)
startPadLen := 0
if position == 0 {
startPadLen = length / 2
} else if position == 1 {
startPadLen = length
}
endPadLen := length - startPadLen
charLen := len(padStr)
leftPad := ""
cur := 0
for cur < startPadLen {
leftPad += string(padStr[cur%charLen])
cur++
}
cur = 0
rightPad := ""
for cur < endPadLen {
rightPad += string(padStr[cur%charLen])
cur++
}
return leftPad + str + rightPad
}
// isLetter checks r is a letter but not CJK character.
func isLetter(r rune) bool {
if !unicode.IsLetter(r) {
return false
}
switch {
// cjk char: /[\u3040-\u30ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff\uff66-\uff9f]/
// hiragana and katakana (Japanese only)
case r >= '\u3034' && r < '\u30ff':
return false
// CJK unified ideographs extension A (Chinese, Japanese, and Korean)
case r >= '\u3400' && r < '\u4dbf':
return false
// CJK unified ideographs (Chinese, Japanese, and Korean)
case r >= '\u4e00' && r < '\u9fff':
return false
// CJK compatibility ideographs (Chinese, Japanese, and Korean)
case r >= '\uf900' && r < '\ufaff':
return false
// half-width katakana (Japanese only)
case r >= '\uff66' && r < '\uff9f':
return false
}
return true
} }

View File

@@ -9,72 +9,178 @@ import (
func TestCamelCase(t *testing.T) { func TestCamelCase(t *testing.T) {
assert := internal.NewAssert(t, "TestCamelCase") assert := internal.NewAssert(t, "TestCamelCase")
assert.Equal("fooBar", CamelCase("foo_bar")) cases := map[string]string{
assert.Equal("fooBar", CamelCase("Foo-Bar")) "": "",
assert.Equal("fooBar", CamelCase("Foo&bar")) "foobar": "foobar",
assert.Equal("fooBar", CamelCase("foo bar")) "&FOO:BAR$BAZ": "fooBarBaz",
"fooBar": "fooBar",
"FOObar": "foObar",
"$foo%": "foo",
" $#$Foo 22 bar ": "foo22Bar",
"Foo-#1😄$_%^&*(1bar": "foo11Bar",
}
assert.NotEqual("FooBar", CamelCase("foo_bar")) for k, v := range cases {
assert.Equal(v, CamelCase(k))
}
} }
func TestCapitalize(t *testing.T) { func TestCapitalize(t *testing.T) {
assert := internal.NewAssert(t, "TestCapitalize") assert := internal.NewAssert(t, "TestCapitalize")
assert.Equal("Foo", Capitalize("foo")) cases := map[string]string{
assert.Equal("Foo", Capitalize("Foo")) "": "",
assert.Equal("Foo", Capitalize("Foo")) "Foo": "Foo",
"_foo": "_foo",
"foobar": "Foobar",
"fooBar": "Foobar",
"foo Bar": "Foo bar",
"foo-bar": "Foo-bar",
"$foo%": "$foo%",
}
assert.NotEqual("foo", Capitalize("Foo")) for k, v := range cases {
assert.Equal(v, Capitalize(k))
}
} }
func TestKebabCase(t *testing.T) { func TestKebabCase(t *testing.T) {
assert := internal.NewAssert(t, "TestKebabCase") assert := internal.NewAssert(t, "TestKebabCase")
assert.Equal("foo-bar", KebabCase("Foo Bar-")) cases := map[string]string{
assert.Equal("foo-bar", KebabCase("foo_Bar")) "": "",
assert.Equal("foo-bar", KebabCase("fooBar")) "foo-bar": "foo-bar",
assert.Equal("f-o-o-b-a-r", KebabCase("__FOO_BAR__")) "--Foo---Bar-": "foo-bar",
"Foo Bar-": "foo-bar",
"foo_Bar": "foo-bar",
"fooBar": "foo-bar",
"FOOBAR": "foobar",
"FOO_BAR": "foo-bar",
"__FOO_BAR__": "foo-bar",
"$foo@Bar": "foo-bar",
" $#$Foo 22 bar ": "foo-22-bar",
"Foo-#1😄$_%^&*(1bar": "foo-1-1-bar",
}
assert.NotEqual("foo_bar", KebabCase("fooBar")) for k, v := range cases {
assert.Equal(v, KebabCase(k))
}
}
func TestUpperKebabCase(t *testing.T) {
assert := internal.NewAssert(t, "TestUpperKebabCase")
cases := map[string]string{
"": "",
"foo-bar": "FOO-BAR",
"--Foo---Bar-": "FOO-BAR",
"Foo Bar-": "FOO-BAR",
"foo_Bar": "FOO-BAR",
"fooBar": "FOO-BAR",
"FOOBAR": "FOOBAR",
"FOO_BAR": "FOO-BAR",
"__FOO_BAR__": "FOO-BAR",
"$foo@Bar": "FOO-BAR",
" $#$Foo 22 bar ": "FOO-22-BAR",
"Foo-#1😄$_%^&*(1bar": "FOO-1-1-BAR",
}
for k, v := range cases {
assert.Equal(v, UpperKebabCase(k))
}
} }
func TestSnakeCase(t *testing.T) { func TestSnakeCase(t *testing.T) {
assert := internal.NewAssert(t, "TestSnakeCase") assert := internal.NewAssert(t, "TestSnakeCase")
assert.Equal("foo_bar", SnakeCase("Foo Bar-")) cases := map[string]string{
assert.Equal("foo_bar", SnakeCase("foo_Bar")) "": "",
assert.Equal("foo_bar", SnakeCase("fooBar")) "foo-bar": "foo_bar",
assert.Equal("f_o_o_b_a_r", SnakeCase("__FOO_BAR__")) "--Foo---Bar-": "foo_bar",
assert.Equal("a_bbc_s_a_b_b_c", SnakeCase("aBbc-s$@a&%_B.B^C")) "Foo Bar-": "foo_bar",
"foo_Bar": "foo_bar",
"fooBar": "foo_bar",
"FOOBAR": "foobar",
"FOO_BAR": "foo_bar",
"__FOO_BAR__": "foo_bar",
"$foo@Bar": "foo_bar",
" $#$Foo 22 bar ": "foo_22_bar",
"Foo-#1😄$_%^&*(1bar": "foo_1_1_bar",
}
assert.NotEqual("foo-bar", SnakeCase("foo_Bar")) for k, v := range cases {
assert.Equal(v, SnakeCase(k))
}
}
func TestUpperSnakeCase(t *testing.T) {
assert := internal.NewAssert(t, "TestUpperSnakeCase")
cases := map[string]string{
"": "",
"foo-bar": "FOO_BAR",
"--Foo---Bar-": "FOO_BAR",
"Foo Bar-": "FOO_BAR",
"foo_Bar": "FOO_BAR",
"fooBar": "FOO_BAR",
"FOOBAR": "FOOBAR",
"FOO_BAR": "FOO_BAR",
"__FOO_BAR__": "FOO_BAR",
"$foo@Bar": "FOO_BAR",
" $#$Foo 22 bar ": "FOO_22_BAR",
"Foo-#1😄$_%^&*(1bar": "FOO_1_1_BAR",
}
for k, v := range cases {
assert.Equal(v, UpperSnakeCase(k))
}
} }
func TestUpperFirst(t *testing.T) { func TestUpperFirst(t *testing.T) {
assert := internal.NewAssert(t, "TestLowerFirst") assert := internal.NewAssert(t, "TestLowerFirst")
assert.Equal("Foo", UpperFirst("foo")) cases := map[string]string{
assert.Equal("BAR", UpperFirst("bAR")) "": "",
assert.Equal("FOo", UpperFirst("FOo")) "foo": "Foo",
assert.Equal("FOo大", UpperFirst("fOo大")) "bAR": "BAR",
"FOo": "FOo",
"fOo大": "FOo大",
}
assert.NotEqual("Bar", UpperFirst("BAR")) for k, v := range cases {
assert.Equal(v, UpperFirst(k))
}
} }
func TestLowerFirst(t *testing.T) { func TestLowerFirst(t *testing.T) {
assert := internal.NewAssert(t, "TestLowerFirst") assert := internal.NewAssert(t, "TestLowerFirst")
assert.Equal("foo", LowerFirst("foo")) cases := map[string]string{
assert.Equal("bAR", LowerFirst("BAR")) "": "",
assert.Equal("fOo", LowerFirst("FOo")) "foo": "foo",
assert.Equal("fOo大", LowerFirst("FOo大")) "bAR": "bAR",
"FOo": "fOo",
"fOo大": "fOo大",
}
assert.NotEqual("Bar", LowerFirst("BAR")) for k, v := range cases {
assert.Equal(v, LowerFirst(k))
}
}
func TestPad(t *testing.T) {
assert := internal.NewAssert(t, "TestPad")
assert.Equal("a ", Pad("a", 2, ""))
assert.Equal("a", Pad("a", 1, "b"))
assert.Equal("ab", Pad("a", 2, "b"))
assert.Equal("mabcdm", Pad("abcd", 6, "m"))
} }
func TestPadEnd(t *testing.T) { func TestPadEnd(t *testing.T) {
assert := internal.NewAssert(t, "TestPadEnd") assert := internal.NewAssert(t, "TestPadEnd")
assert.Equal("a ", PadEnd("a", 2, " "))
assert.Equal("a", PadEnd("a", 1, "b")) assert.Equal("a", PadEnd("a", 1, "b"))
assert.Equal("ab", PadEnd("a", 2, "b")) assert.Equal("ab", PadEnd("a", 2, "b"))
assert.Equal("abcdmn", PadEnd("abcd", 6, "mno")) assert.Equal("abcdmn", PadEnd("abcd", 6, "mno"))
@@ -189,3 +295,37 @@ func TestSplitEx(t *testing.T) {
assert.Equal([]string{" a", "b", "c", ""}, SplitEx(" a = b = c = ", " = ", false)) assert.Equal([]string{" a", "b", "c", ""}, SplitEx(" a = b = c = ", " = ", false))
assert.Equal([]string{" a", "b", "c"}, SplitEx(" a = b = c = ", " = ", true)) assert.Equal([]string{" a", "b", "c"}, SplitEx(" a = b = c = ", " = ", true))
} }
func TestSplitWords(t *testing.T) {
assert := internal.NewAssert(t, "TestSplitWords")
cases := map[string][]string{
"a word": {"a", "word"},
"I'am a programmer": {"I'am", "a", "programmer"},
"Bonjour, je suis programmeur": {"Bonjour", "je", "suis", "programmeur"},
"a -b-c' 'd'e": {"a", "b-c'", "d'e"},
"你好,我是一名码农": nil,
"こんにちは,私はプログラマーです": nil,
}
for k, v := range cases {
assert.Equal(v, SplitWords(k))
}
}
func TestWordCount(t *testing.T) {
assert := internal.NewAssert(t, "TestSplitWords")
cases := map[string]int{
"a word": 2, // {"a", "word"},
"I'am a programmer": 3, // {"I'am", "a", "programmer"},
"Bonjour, je suis programmeur": 4, // {"Bonjour", "je", "suis", "programmeur"},
"a -b-c' 'd'e": 3, // {"a", "b-c'", "d'e"},
"你好,我是一名码农": 0, // nil,
"こんにちは,私はプログラマーです": 0, // nil,
}
for k, v := range cases {
assert.Equal(v, WordCount(k))
}
}

View File

@@ -9,6 +9,10 @@ import (
"os" "os"
"os/exec" "os/exec"
"runtime" "runtime"
"unicode/utf8"
"github.com/duke-git/lancet/validator"
"golang.org/x/text/encoding/simplifiedchinese"
) )
// IsWindows check if current os is windows // IsWindows check if current os is windows
@@ -50,27 +54,61 @@ func CompareOsEnv(key, comparedEnv string) bool {
return env == comparedEnv return env == comparedEnv
} }
// ExecCommand use shell /bin/bash -c to execute command // ExecCommand execute command, return the stdout and stderr string of command, and error if error occur
// param `command` is a complete command string, like, ls -a (linux), dir(windows), ping 127.0.0.1
// in linux, use /bin/bash -c to execute command
// in windows, use powershell.exe to execute command
func ExecCommand(command string) (stdout, stderr string, err error) { func ExecCommand(command string) (stdout, stderr string, err error) {
var out bytes.Buffer var out bytes.Buffer
var errout bytes.Buffer var errOut bytes.Buffer
cmd := exec.Command("/bin/bash", "-c", command) cmd := exec.Command("/bin/bash", "-c", command)
if IsWindows() { if IsWindows() {
cmd = exec.Command("cmd") cmd = exec.Command("powershell.exe", command)
} }
cmd.Stdout = &out cmd.Stdout = &out
cmd.Stderr = &errout cmd.Stderr = &errOut
err = cmd.Run() err = cmd.Run()
if err != nil { if err != nil {
stderr = string(errout.Bytes()) if utf8.Valid(errOut.Bytes()) {
stderr = byteToString(errOut.Bytes(), "UTF8")
} else if validator.IsGBK(errOut.Bytes()) {
stderr = byteToString(errOut.Bytes(), "GBK")
}
return
}
data := out.Bytes()
if utf8.Valid(data) {
stdout = byteToString(data, "UTF8")
} else if validator.IsGBK(data) {
stdout = byteToString(data, "GBK")
} }
stdout = string(out.Bytes())
return return
} }
func byteToString(data []byte, charset string) string {
var result string
switch charset {
case "GBK":
decodeBytes, _ := simplifiedchinese.GBK.NewDecoder().Bytes(data)
result = string(decodeBytes)
case "GB18030":
decodeBytes, _ := simplifiedchinese.GB18030.NewDecoder().Bytes(data)
result = string(decodeBytes)
case "UTF8":
fallthrough
default:
result = string(data)
}
return result
}
// GetOsBits get this system bits 32bit or 64bit // GetOsBits get this system bits 32bit or 64bit
// return bit int (32/64) // return bit int (32/64)
func GetOsBits() int { func GetOsBits() int {

View File

@@ -11,10 +11,10 @@ func TestOsDetection(t *testing.T) {
assert := internal.NewAssert(t, "TestOsJudgment") assert := internal.NewAssert(t, "TestOsJudgment")
osType, _, _ := ExecCommand("echo $OSTYPE") osType, _, _ := ExecCommand("echo $OSTYPE")
if strings.Index(osType, "linux") != -1 { if strings.Contains(osType, "linux") {
assert.Equal(true, IsLinux()) assert.Equal(true, IsLinux())
} }
if strings.Index(osType, "darwin") != -1 { if strings.Contains(osType, "darwin") {
assert.Equal(true, IsMac()) assert.Equal(true, IsMac())
} }
} }
@@ -44,21 +44,26 @@ func TestOsEnvOperation(t *testing.T) {
func TestExecCommand(t *testing.T) { func TestExecCommand(t *testing.T) {
assert := internal.NewAssert(t, "TestExecCommand") assert := internal.NewAssert(t, "TestExecCommand")
out, errout, err := ExecCommand("ls") // linux or mac
t.Log("std out: ", out) stdout, stderr, err := ExecCommand("ls")
t.Log("std err: ", errout) t.Log("std out: ", stdout)
t.Log("std err: ", stderr)
assert.Equal("", stderr)
assert.IsNil(err) assert.IsNil(err)
out, errout, err = ExecCommand("abc") // windows
t.Log("std out: ", out) stdout, stderr, err = ExecCommand("dir")
t.Log("std err: ", errout) t.Log("std out: ", stdout)
if err != nil { t.Log("std err: ", stderr)
t.Logf("error: %v\n", err) if IsWindows() {
assert.IsNil(err)
} }
if !IsWindows() { // error command
assert.IsNotNil(err) stdout, stderr, err = ExecCommand("abc")
} t.Log("std out: ", stdout)
t.Log("std err: ", stderr)
assert.IsNotNil(err)
} }
func TestGetOsBits(t *testing.T) { func TestGetOsBits(t *testing.T) {

View File

@@ -15,11 +15,24 @@ import (
"unicode" "unicode"
) )
var isAlphaRegexMatcher *regexp.Regexp = regexp.MustCompile(`^[a-zA-Z]+$`) var (
alphaMatcher *regexp.Regexp = regexp.MustCompile(`^[a-zA-Z]+$`)
letterRegexMatcher *regexp.Regexp = regexp.MustCompile(`[a-zA-Z]`)
intStrMatcher *regexp.Regexp = regexp.MustCompile(`^[\+-]?\d+$`)
urlMatcher *regexp.Regexp = regexp.MustCompile(`^((ftp|http|https?):\/\/)?(\S+(:\S*)?@)?((([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(([a-zA-Z0-9]+([-\.][a-zA-Z0-9]+)*)|((www\.)?))?(([a-z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-z\x{00a1}-\x{ffff}]{2,}))?))(:(\d{1,5}))?((\/|\?|#)[^\s]*)?$`)
dnsMatcher *regexp.Regexp = regexp.MustCompile(`^[a-zA-Z]([a-zA-Z0-9\-]+[\.]?)*[a-zA-Z0-9]$`)
emailMatcher *regexp.Regexp = regexp.MustCompile(`\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*`)
chineseMobileMatcher *regexp.Regexp = regexp.MustCompile(`^1(?:3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8\d|9\d)\d{8}$`)
chineseIdMatcher *regexp.Regexp = regexp.MustCompile(`^[1-9]\d{5}(18|19|20|21|22)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$`)
chineseMatcher *regexp.Regexp = regexp.MustCompile("[\u4e00-\u9fa5]")
chinesePhoneMatcher *regexp.Regexp = regexp.MustCompile(`\d{3}-\d{8}|\d{4}-\d{7}`)
creditCardMatcher *regexp.Regexp = regexp.MustCompile(`^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11}|6[27][0-9]{14})$`)
base64Matcher *regexp.Regexp = regexp.MustCompile(`^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$`)
)
// IsAlpha checks if the string contains only letters (a-zA-Z) // IsAlpha checks if the string contains only letters (a-zA-Z)
func IsAlpha(str string) bool { func IsAlpha(str string) bool {
return isAlphaRegexMatcher.MatchString(str) return alphaMatcher.MatchString(str)
} }
// IsAllUpper check if the string is all upper case letters A-Z // IsAllUpper check if the string is all upper case letters A-Z
@@ -62,11 +75,9 @@ func ContainLower(str string) bool {
return false return false
} }
var containLetterRegexMatcher *regexp.Regexp = regexp.MustCompile(`[a-zA-Z]`)
// ContainLetter check if the string contain at least one letter // ContainLetter check if the string contain at least one letter
func ContainLetter(str string) bool { func ContainLetter(str string) bool {
return containLetterRegexMatcher.MatchString(str) return letterRegexMatcher.MatchString(str)
} }
// IsJSON checks if the string is valid JSON // IsJSON checks if the string is valid JSON
@@ -86,11 +97,9 @@ func IsFloatStr(str string) bool {
return e == nil return e == nil
} }
var isIntStrRegexMatcher *regexp.Regexp = regexp.MustCompile(`^[\+-]?\d+$`)
// IsIntStr check if the string can convert to a integer. // IsIntStr check if the string can convert to a integer.
func IsIntStr(str string) bool { func IsIntStr(str string) bool {
return isIntStrRegexMatcher.MatchString(str) return intStrMatcher.MatchString(str)
} }
// IsIp check if the string is a ip address. // IsIp check if the string is a ip address.
@@ -125,8 +134,6 @@ func IsPort(str string) bool {
return false return false
} }
var isUrlRegexMatcher *regexp.Regexp = regexp.MustCompile(`^((ftp|http|https?):\/\/)?(\S+(:\S*)?@)?((([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(([a-zA-Z0-9]+([-\.][a-zA-Z0-9]+)*)|((www\.)?))?(([a-z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-z\x{00a1}-\x{ffff}]{2,}))?))(:(\d{1,5}))?((\/|\?|#)[^\s]*)?$`)
// IsUrl check if the string is url. // IsUrl check if the string is url.
func IsUrl(str string) bool { func IsUrl(str string) bool {
if str == "" || len(str) >= 2083 || len(str) <= 3 || strings.HasPrefix(str, ".") { if str == "" || len(str) >= 2083 || len(str) <= 3 || strings.HasPrefix(str, ".") {
@@ -143,64 +150,48 @@ func IsUrl(str string) bool {
return false return false
} }
return isUrlRegexMatcher.MatchString(str) return urlMatcher.MatchString(str)
} }
var isDnsRegexMatcher *regexp.Regexp = regexp.MustCompile(`^[a-zA-Z]([a-zA-Z0-9\-]+[\.]?)*[a-zA-Z0-9]$`)
// IsDns check if the string is dns. // IsDns check if the string is dns.
func IsDns(dns string) bool { func IsDns(dns string) bool {
return isDnsRegexMatcher.MatchString(dns) return dnsMatcher.MatchString(dns)
} }
var isEmailRegexMatcher *regexp.Regexp = regexp.MustCompile(`\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*`)
// IsEmail check if the string is a email address. // IsEmail check if the string is a email address.
func IsEmail(email string) bool { func IsEmail(email string) bool {
return isEmailRegexMatcher.MatchString(email) return emailMatcher.MatchString(email)
} }
var isChineseMobileRegexMatcher *regexp.Regexp = regexp.MustCompile("^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$")
// IsChineseMobile check if the string is chinese mobile number. // IsChineseMobile check if the string is chinese mobile number.
func IsChineseMobile(mobileNum string) bool { func IsChineseMobile(mobileNum string) bool {
return isChineseMobileRegexMatcher.MatchString(mobileNum) return chineseMobileMatcher.MatchString(mobileNum)
} }
var isChineseIdNumRegexMatcher *regexp.Regexp = regexp.MustCompile(`^[1-9]\d{5}(18|19|20|21|22)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$`)
// IsChineseIdNum check if the string is chinese id number. // IsChineseIdNum check if the string is chinese id number.
func IsChineseIdNum(id string) bool { func IsChineseIdNum(id string) bool {
return isChineseIdNumRegexMatcher.MatchString(id) return chineseIdMatcher.MatchString(id)
} }
var containChineseRegexMatcher *regexp.Regexp = regexp.MustCompile("[\u4e00-\u9fa5]")
// ContainChinese check if the string contain mandarin chinese. // ContainChinese check if the string contain mandarin chinese.
func ContainChinese(s string) bool { func ContainChinese(s string) bool {
return containChineseRegexMatcher.MatchString(s) return chineseMatcher.MatchString(s)
} }
var isChinesePhoneRegexMatcher *regexp.Regexp = regexp.MustCompile(`\d{3}-\d{8}|\d{4}-\d{7}`)
// IsChinesePhone check if the string is chinese phone number. // IsChinesePhone check if the string is chinese phone number.
// Valid chinese phone is xxx-xxxxxxxx or xxxx-xxxxxxx // Valid chinese phone is xxx-xxxxxxxx or xxxx-xxxxxxx
func IsChinesePhone(phone string) bool { func IsChinesePhone(phone string) bool {
return isChinesePhoneRegexMatcher.MatchString(phone) return chinesePhoneMatcher.MatchString(phone)
} }
var isCreditCardRegexMatcher *regexp.Regexp = regexp.MustCompile(`^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11}|6[27][0-9]{14})$`)
// IsCreditCard check if the string is credit card. // IsCreditCard check if the string is credit card.
func IsCreditCard(creditCart string) bool { func IsCreditCard(creditCart string) bool {
return isCreditCardRegexMatcher.MatchString(creditCart) return creditCardMatcher.MatchString(creditCart)
} }
var isBase64RegexMatcher *regexp.Regexp = regexp.MustCompile(`^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$`)
// IsBase64 check if the string is base64 string. // IsBase64 check if the string is base64 string.
func IsBase64(base64 string) bool { func IsBase64(base64 string) bool {
return isBase64RegexMatcher.MatchString(base64) return base64Matcher.MatchString(base64)
} }
// IsEmptyString check if the string is empty. // IsEmptyString check if the string is empty.
@@ -288,3 +279,40 @@ func IsZeroValue(value interface{}) bool {
return reflect.DeepEqual(rv.Interface(), reflect.Zero(rv.Type()).Interface()) return reflect.DeepEqual(rv.Interface(), reflect.Zero(rv.Type()).Interface())
} }
// IsGBK check if data encoding is gbk
// Note: this function is implemented by whether double bytes fall within the encoding range of gbk,
// while each byte of utf-8 encoding format falls within the encoding range of gbk.
// Therefore, utf8.valid() should be called first to check whether it is not utf-8 encoding,
// and then call IsGBK() to check gbk encoding. like below
/**
data := []byte("你好")
if utf8.Valid(data) {
fmt.Println("data encoding is utf-8")
}else if(IsGBK(data)) {
fmt.Println("data encoding is GBK")
}
fmt.Println("data encoding is unknown")
**/
func IsGBK(data []byte) bool {
i := 0
for i < len(data) {
if data[i] <= 0xff {
i++
continue
} else {
if data[i] >= 0x81 &&
data[i] <= 0xfe &&
data[i+1] >= 0x40 &&
data[i+1] <= 0xfe &&
data[i+1] != 0xf7 {
i += 2
continue
} else {
return false
}
}
}
return true
}

View File

@@ -4,8 +4,10 @@ import (
"fmt" "fmt"
"testing" "testing"
"time" "time"
"unicode/utf8"
"github.com/duke-git/lancet/internal" "github.com/duke-git/lancet/internal"
"golang.org/x/text/encoding/simplifiedchinese"
) )
func TestIsAllUpper(t *testing.T) { func TestIsAllUpper(t *testing.T) {
@@ -388,3 +390,13 @@ func TestIsZeroValue(t *testing.T) {
assert.Equal(false, IsZeroValue(value)) assert.Equal(false, IsZeroValue(value))
} }
} }
func TestIsGBK(t *testing.T) {
assert := internal.NewAssert(t, "TestIsGBK")
str := "你好"
gbkData, _ := simplifiedchinese.GBK.NewEncoder().Bytes([]byte(str))
assert.Equal(true, IsGBK(gbkData))
assert.Equal(false, utf8.Valid(gbkData))
}