mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-17 11:12:28 +08:00
Compare commits
18 Commits
db34b5f69c
...
v1.3.9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a8ff17b52 | ||
|
|
6b46a0c05c | ||
|
|
4b8b624b4c | ||
|
|
f274375e62 | ||
|
|
6dc017a5fa | ||
|
|
e1fb97095d | ||
|
|
d8f5a15590 | ||
|
|
1202ac955d | ||
|
|
84b2cec9b5 | ||
|
|
2d01a13787 | ||
|
|
db9b045500 | ||
|
|
2701bcc4d2 | ||
|
|
b9745fd08b | ||
|
|
3b1597d6f7 | ||
|
|
40ab5e8f7b | ||
|
|
cacedf2a05 | ||
|
|
4fc391895b | ||
|
|
b419319e66 |
69
README.md
69
README.md
@@ -4,7 +4,7 @@
|
||||
<br/>
|
||||
|
||||

|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://pkg.go.dev/github.com/duke-git/lancet)
|
||||
[](https://goreportcard.com/report/github.com/duke-git/lancet)
|
||||
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
||||
@@ -24,7 +24,7 @@ English | [简体中文](./README_zh-CN.md)
|
||||
## Feature
|
||||
|
||||
- 👏 Comprehensive, efficient and reusable.
|
||||
- 💪 300+ go util functions, support string, slice, datetime, net, crypt...
|
||||
- 💪 400+ go util functions, support string, slice, datetime, net, crypt...
|
||||
- 💅 Only depend on the go standard library.
|
||||
- 🌍 Unit test for every exported function.
|
||||
|
||||
@@ -63,7 +63,22 @@ func main() {
|
||||
|
||||
## API Documentation
|
||||
|
||||
### 1. Convertor package contains some functions for data convertion.
|
||||
### 1. Compare package provides a lightweight comparison function on any type.
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/compare"
|
||||
```
|
||||
|
||||
#### Function list:
|
||||
|
||||
- [Equal](https://github.com/duke-git/lancet/blob/v1/docs/compare.md#Equal)
|
||||
- [EqualValue](https://github.com/duke-git/lancet/blob/v1/docs/compare.md#EqualValue)
|
||||
- [LessThan](https://github.com/duke-git/lancet/blob/v1/docs/compare.md#LessThan)
|
||||
- [GreaterThan](https://github.com/duke-git/lancet/blob/v1/docs/compare.md#GreaterThan)
|
||||
- [LessOrEqual](https://github.com/duke-git/lancet/blob/v1/docs/compare.md#LessOrEqual)
|
||||
- [GreaterOrEqual](https://github.com/duke-git/lancet/blob/v1/docs/compare.md#GreaterOrEqual)
|
||||
|
||||
### 2. Convertor package contains some functions for data convertion.
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/convertor"
|
||||
@@ -86,7 +101,7 @@ import "github.com/duke-git/lancet/convertor"
|
||||
- [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.
|
||||
### 3. Cryptor package is for data encryption and decryption.
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/cryptor"
|
||||
@@ -127,7 +142,7 @@ import "github.com/duke-git/lancet/cryptor"
|
||||
- [RsaEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#RsaEncrypt)
|
||||
- [RsaDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor.md#RsaDecrypt)
|
||||
|
||||
### 3. Datetime package supports date and time format and compare.
|
||||
### 4. Datetime package supports date and time format and compare.
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/datetime"
|
||||
@@ -138,6 +153,7 @@ import "github.com/duke-git/lancet/datetime"
|
||||
- [AddDay](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#AddDay)
|
||||
- [AddHour](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#AddHour)
|
||||
- [AddMinute](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#AddMinute)
|
||||
- [AddYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#AddYear)
|
||||
- [BeginOfMinute](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfMinute)
|
||||
- [BeginOfHour](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfHour)
|
||||
- [BeginOfDay](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfDay)
|
||||
@@ -165,8 +181,12 @@ import "github.com/duke-git/lancet/datetime"
|
||||
- [ToFormat](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#ToFormat)
|
||||
- [ToFormatForTpl](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#ToFormatForTpl)
|
||||
- [ToIso8601](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#ToIso8601)
|
||||
- [IsLeapYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#IsLeapYear)
|
||||
- [BetweenSeconds](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BetweenSeconds)
|
||||
- [DayOfYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#DayOfYear)
|
||||
- [IsWeekend](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#IsWeekend)
|
||||
|
||||
### 4. Fileutil package implements some basic functions for file operations.
|
||||
### 5. Fileutil package implements some basic functions for file operations.
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/fileutil"
|
||||
@@ -190,8 +210,15 @@ import "github.com/duke-git/lancet/fileutil"
|
||||
- [Zip](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#Zip)
|
||||
- [UnZip](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#UnZip)
|
||||
- [CurrentPath](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#CurrentPath)
|
||||
- [IsZipFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#IsZipFile)
|
||||
- [FileSize](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#FileSize)
|
||||
- [MTime](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#MTime)
|
||||
- [Sha](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#Sha)
|
||||
- [ReadCsvFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#ReadCsvFile)
|
||||
- [WriteStringToFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#WriteStringToFile)
|
||||
- [WriteBytesToFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil.md#WriteBytesToFile)
|
||||
|
||||
### 5. Formatter contains some functions for data formatting.
|
||||
### 6. Formatter contains some functions for data formatting.
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/formatter"
|
||||
@@ -207,7 +234,7 @@ import "github.com/duke-git/lancet/formatter"
|
||||
- [ParseDecimalBytes](https://github.com/duke-git/lancet/blob/v1/docs/formatter.md#ParseDecimalBytes)
|
||||
- [ParseBinaryBytes](https://github.com/duke-git/lancet/blob/v1/docs/formatter.md#ParseBinaryBytes)
|
||||
|
||||
### Function package can control the flow of function execution and support part of functional programming
|
||||
### 7. Function package can control the flow of function execution and support part of functional programming
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/function"
|
||||
@@ -225,7 +252,7 @@ import "github.com/duke-git/lancet/function"
|
||||
- [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)
|
||||
|
||||
### 6. Mathutil package implements some functions for math calculation.
|
||||
### 8. Mathutil package implements some functions for math calculation.
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/mathutil"
|
||||
@@ -244,8 +271,12 @@ import "github.com/duke-git/lancet/mathutil"
|
||||
- [RadianToAngle](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#RadianToAngle)
|
||||
- [PointDistance](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#PointDistance)
|
||||
- [IsPrime](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#IsPrime)
|
||||
- [GCD](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#GCD)
|
||||
- [LCM](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#LCM)
|
||||
- [Cos](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#Cos)
|
||||
- [Sin](https://github.com/duke-git/lancet/blob/v1/docs/mathutil.md#Sin)
|
||||
|
||||
### 7. Netutil package contains functions to get net information and send http request.
|
||||
### 9. Netutil package contains functions to get net information and send http request.
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/netutil"
|
||||
@@ -273,7 +304,7 @@ import "github.com/duke-git/lancet/netutil"
|
||||
- [IsPingConnected](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#IsPingConnected)
|
||||
- [IsTelnetConnected](https://github.com/duke-git/lancet/blob/v1/docs/netutil.md#IsTelnetConnected)
|
||||
|
||||
### 8. Random package implements some basic functions to generate random int and string.
|
||||
### 10. Random package implements some basic functions to generate random int and string.
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/random"
|
||||
@@ -290,7 +321,7 @@ import "github.com/duke-git/lancet/random"
|
||||
- [RandNumeralOrLetter](https://github.com/duke-git/lancet/blob/v1/docs/random.md#RandNumeralOrLetter)
|
||||
- [UUIdV4](https://github.com/duke-git/lancet/blob/v1/docs/random.md#UUIdV4)
|
||||
|
||||
### 9. Retry package is for executing a function repeatedly until it was successful or canceled by the context.
|
||||
### 11. Retry package is for executing a function repeatedly until it was successful or canceled by the context.
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/retry"
|
||||
@@ -304,7 +335,7 @@ import "github.com/duke-git/lancet/retry"
|
||||
- [RetryDuration](https://github.com/duke-git/lancet/blob/v1/docs/retry.md#RetryDuration)
|
||||
- [RetryTimes](https://github.com/duke-git/lancet/blob/v1/docs/retry.md#RetryTimes)
|
||||
|
||||
### 10. Slice contains some functions to manipulate slice.
|
||||
### 12. Slice contains some functions to manipulate slice.
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/slice"
|
||||
@@ -353,7 +384,7 @@ import "github.com/duke-git/lancet/slice"
|
||||
- [UpdateByIndex](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#UpdateByIndex)
|
||||
- [Without](https://github.com/duke-git/lancet/blob/v1/docs/slice.md#Without)
|
||||
|
||||
### 11. Strutil package contains some functions to manipulate string.
|
||||
### 13. Strutil package contains some functions to manipulate string.
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/strutil"
|
||||
@@ -367,6 +398,8 @@ import "github.com/duke-git/lancet/strutil"
|
||||
- [BeforeLast](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#BeforeLast)
|
||||
- [CamelCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#CamelCase)
|
||||
- [Capitalize](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Capitalize)
|
||||
- [ContainsAll](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#ContainsAll)
|
||||
- [ContainsAny](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#ContainsAny)
|
||||
- [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)
|
||||
- [UpperKebabCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#UpperKebabCase)
|
||||
@@ -390,8 +423,12 @@ import "github.com/duke-git/lancet/strutil"
|
||||
- [HasPrefixAny](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#HasPrefixAny)
|
||||
- [HasSuffixAny](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#HasSuffixAny)
|
||||
- [IndexOffset](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#IndexOffset)
|
||||
- [ReplaceWithMap](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#ReplaceWithMap)
|
||||
- [Trim](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#Trim)
|
||||
- [SplitAndTrim](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#SplitAndTrim)
|
||||
- [HideString](https://github.com/duke-git/lancet/blob/v1/docs/strutil.md#HideString)
|
||||
|
||||
### 12. System package contain some functions about os, runtime, shell command.
|
||||
### 14. System package contain some functions about os, runtime, shell command.
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/system"
|
||||
@@ -409,7 +446,7 @@ import "github.com/duke-git/lancet/system"
|
||||
- [ExecCommand](https://github.com/duke-git/lancet/blob/v1/docs/system.md#ExecCommand)
|
||||
- [GetOsBits](https://github.com/duke-git/lancet/blob/v1/docs/system.md#GetOsBits)
|
||||
|
||||
### 13. Validator package contains some functions for data validation.
|
||||
### 15. Validator package contains some functions for data validation.
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/validator"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<br/>
|
||||
|
||||

|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://pkg.go.dev/github.com/duke-git/lancet)
|
||||
[](https://goreportcard.com/report/github.com/duke-git/lancet)
|
||||
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
||||
@@ -23,7 +23,7 @@
|
||||
## 特性
|
||||
|
||||
- 👏 全面、高效、可复用
|
||||
- 💪 300+常用 go 工具函数,支持 string、slice、datetime、net、crypt...
|
||||
- 💪 400+常用 go 工具函数,支持 string、slice、datetime、net、crypt...
|
||||
- 💅 只依赖 go 标准库
|
||||
- 🌍 所有导出函数单元测试覆盖率 100%
|
||||
|
||||
@@ -62,7 +62,22 @@ func main() {
|
||||
|
||||
## API 文档
|
||||
|
||||
### 1. convertor 转换器包支持一些常见的数据类型转换。
|
||||
|
||||
### 1. compare包提供几个轻量级的类型比较函数。
|
||||
```go
|
||||
import "github.com/duke-git/lancet/compare"
|
||||
```
|
||||
|
||||
#### Function list:
|
||||
|
||||
- [Equal](https://github.com/duke-git/lancet/blob/v1/docs/compare_zh-CN.md#Equal)
|
||||
- [EqualValue](https://github.com/duke-git/lancet/blob/v1/docs/compare_zh-CN.md#EqualValue)
|
||||
- [LessThan](https://github.com/duke-git/lancet/blob/v1/docs/compare_zh-CN.md#LessThan)
|
||||
- [GreaterThan](https://github.com/duke-git/lancet/blob/v1/docs/compare_zh-CN.md#GreaterThan)
|
||||
- [LessOrEqual](https://github.com/duke-git/lancet/blob/v1/docs/compare_zh-CN.md#LessOrEqual)
|
||||
- [GreaterOrEqual](https://github.com/duke-git/lancet/blob/v1/docs/compare_zh-CN.md#GreaterOrEqual)
|
||||
|
||||
### 2. convertor转换器包支持一些常见的数据类型转换。
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/convertor"
|
||||
@@ -85,7 +100,7 @@ import "github.com/duke-git/lancet/convertor"
|
||||
- [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 加密包支持数据加密和解密,获取 md5,hash 值。支持 base64, md5, hmac, aes, des, rsa。
|
||||
### 3. cryptor 加密包支持数据加密和解密,获取 md5,hash 值。支持 base64, md5, hmac, aes, des, rsa。
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/cryptor"
|
||||
@@ -126,7 +141,7 @@ import "github.com/duke-git/lancet/cryptor"
|
||||
- [RsaEncrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#RsaEncrypt)
|
||||
- [RsaDecrypt](https://github.com/duke-git/lancet/blob/v1/docs/cryptor_zh-CN.md#RsaDecrypt)
|
||||
|
||||
### 3. datetime 日期时间处理包,格式化日期,比较日期。
|
||||
### 4. datetime 日期时间处理包,格式化日期,比较日期。
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/datetime"
|
||||
@@ -137,6 +152,7 @@ import "github.com/duke-git/lancet/datetime"
|
||||
- [AddDay](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#AddDay)
|
||||
- [AddHour](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#AddHour)
|
||||
- [AddMinute](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#AddMinute)
|
||||
- [AddYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#AddYear)
|
||||
- [BeginOfMinute](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfMinute)
|
||||
- [BeginOfHour](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfHour)
|
||||
- [BeginOfDay](https://github.com/duke-git/lancet/blob/v1/docs/datetime.md#BeginOfDay)
|
||||
@@ -164,8 +180,12 @@ import "github.com/duke-git/lancet/datetime"
|
||||
- [ToFormat](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#ToFormat)
|
||||
- [ToFormatForTpl](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#ToFormatForTpl)
|
||||
- [ToIso8601](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#ToIso8601)
|
||||
- [IsLeapYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#IsLeapYear)
|
||||
- [BetweenSeconds](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#BetweenSeconds)
|
||||
- [DayOfYear](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#DayOfYear)
|
||||
- [IsWeekend](https://github.com/duke-git/lancet/blob/v1/docs/datetime_zh-CN.md#IsWeekend)
|
||||
|
||||
### 4. fileutil 包支持文件基本操作。
|
||||
### 5. fileutil 包支持文件基本操作。
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/fileutil"
|
||||
@@ -189,8 +209,15 @@ import "github.com/duke-git/lancet/fileutil"
|
||||
- [Zip](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#Zip)
|
||||
- [UnZip](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#UnZip)
|
||||
- [CurrentPath](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#CurrentPath)
|
||||
- [IsZipFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#IsZipFile)
|
||||
- [FileSize](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#FileSize)
|
||||
- [MTime](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#MTime)
|
||||
- [Sha](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#Sha)
|
||||
- [ReadCsvFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#ReadCsvFile)
|
||||
- [WriteStringToFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#WriteStringToFile)
|
||||
- [WriteBytesToFile](https://github.com/duke-git/lancet/blob/v1/docs/fileutil_zh-CN.md#WriteBytesToFile)
|
||||
|
||||
### 5. formatter 格式化器包含一些数据格式化处理方法。
|
||||
### 6. formatter 格式化器包含一些数据格式化处理方法。
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/formatter"
|
||||
@@ -206,7 +233,7 @@ import "github.com/duke-git/lancet/formatter"
|
||||
- [ParseDecimalBytes](https://github.com/duke-git/lancet/blob/v1/docs/formatter_zh-CN.md#ParseDecimalBytes)
|
||||
- [ParseBinaryBytes](https://github.com/duke-git/lancet/blob/v1/docs/formatter_zh-CN.md#ParseBinaryBytes)
|
||||
|
||||
### function 函数包控制函数执行流程,包含部分函数式编程。
|
||||
### 7. function 函数包控制函数执行流程,包含部分函数式编程。
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/function"
|
||||
@@ -224,7 +251,7 @@ import "github.com/duke-git/lancet/function"
|
||||
- [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)
|
||||
|
||||
### 6. mathutil 包实现了一些数学计算的函数。
|
||||
### 8. mathutil 包实现了一些数学计算的函数。
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/mathutil"
|
||||
@@ -243,8 +270,12 @@ import "github.com/duke-git/lancet/mathutil"
|
||||
- [RadianToAngle](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#RadianToAngle)
|
||||
- [PointDistance](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#PointDistance)
|
||||
- [IsPrime](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#IsPrime)
|
||||
- [GCD](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#GCD)
|
||||
- [LCM](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#LCM)
|
||||
- [Cos](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#Cos)
|
||||
- [Sin](https://github.com/duke-git/lancet/blob/v1/docs/mathutil_zh-CN.md#Sin)
|
||||
|
||||
### 7. netutil 网络包支持获取 ip 地址,发送 http 请求。
|
||||
### 9. netutil 网络包支持获取 ip 地址,发送 http 请求。
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/netutil"
|
||||
@@ -272,7 +303,7 @@ import "github.com/duke-git/lancet/netutil"
|
||||
- [IsPingConnected](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#IsPingConnected)
|
||||
- [IsTelnetConnected](https://github.com/duke-git/lancet/blob/v1/docs/netutil_zh-CN.md#IsTelnetConnected)
|
||||
|
||||
### 8. random 随机数生成器包,可以生成随机[]bytes, int, string。
|
||||
### 10. random 随机数生成器包,可以生成随机[]bytes, int, string。
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/random"
|
||||
@@ -289,7 +320,7 @@ import "github.com/duke-git/lancet/random"
|
||||
- [RandNumeralOrLetter](https://github.com/duke-git/lancet/blob/v1/docs/random_zh-CN.md#RandNumeralOrLetter)
|
||||
- [UUIdV4](https://github.com/duke-git/lancet/blob/v1/docs/random.md#UUIdV4)
|
||||
|
||||
### 9. retry 重试执行函数直到函数运行成功或被 context cancel。
|
||||
### 11. retry 重试执行函数直到函数运行成功或被 context cancel。
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/retry"
|
||||
@@ -303,7 +334,7 @@ import "github.com/duke-git/lancet/retry"
|
||||
- [RetryDuration](https://github.com/duke-git/lancet/blob/v1/docs/retry_zh-CN.md#RetryDuration)
|
||||
- [RetryTimes](https://github.com/duke-git/lancet/blob/v1/docs/retry_zh-CN.md#RetryTimes)
|
||||
|
||||
### 10. slice 包包含操作切片的方法集合。
|
||||
### 12. slice 包包含操作切片的方法集合。
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/slice"
|
||||
@@ -352,7 +383,7 @@ import "github.com/duke-git/lancet/slice"
|
||||
- [UpdateByIndex](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#UpdateByIndex)
|
||||
- [Without](https://github.com/duke-git/lancet/blob/v1/docs/slice_zh-CN.md#Without)
|
||||
|
||||
### 12. strutil 包含处理字符串的相关函数。
|
||||
### 13. strutil 包含处理字符串的相关函数。
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/strutil"
|
||||
@@ -366,6 +397,8 @@ import "github.com/duke-git/lancet/strutil"
|
||||
- [BeforeLast](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#BeforeLast)
|
||||
- [CamelCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#CamelCase)
|
||||
- [Capitalize](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Capitalize)
|
||||
- [ContainsAll](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#ContainsAll)
|
||||
- [ContainsAny](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#ContainsAny)
|
||||
- [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)
|
||||
- [UpperKebabCase](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#UpperKebabCase)
|
||||
@@ -389,8 +422,12 @@ import "github.com/duke-git/lancet/strutil"
|
||||
- [HasPrefixAny](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#HasPrefixAny)
|
||||
- [HasSuffixAny](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#HasSuffixAny)
|
||||
- [IndexOffset](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#IndexOffset)
|
||||
- [ReplaceWithMap](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#ReplaceWithMap)
|
||||
- [Trim](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#Trim)
|
||||
- [SplitAndTrim](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#SplitAndTrim)
|
||||
- [HideString](https://github.com/duke-git/lancet/blob/v1/docs/strutil_zh-CN.md#HideString)
|
||||
|
||||
### 13. system 包含 os, runtime, shell command 相关函数。
|
||||
### 14. system 包含 os, runtime, shell command 相关函数。
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/system"
|
||||
@@ -408,7 +445,7 @@ import "github.com/duke-git/lancet/system"
|
||||
- [ExecCommand](https://github.com/duke-git/lancet/blob/v1/docs/system_zh-CN.md#ExecCommand)
|
||||
- [GetOsBits](https://github.com/duke-git/lancet/blob/v1/docs/system_zh-CN.md#GetOsBits)
|
||||
|
||||
### 14. validator 验证器包,包含常用字符串格式验证函数。
|
||||
### 15. validator 验证器包,包含常用字符串格式验证函数。
|
||||
|
||||
```go
|
||||
import "github.com/duke-git/lancet/validator"
|
||||
|
||||
58
compare/compare.go
Normal file
58
compare/compare.go
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright 2023 dudaodong@gmail.com. All rights resulterved.
|
||||
// Use of this source code is governed by MIT license
|
||||
|
||||
// Package compare provides a lightweight comparison function on interface{} type.
|
||||
// reference: https://github.com/stretchr/testify
|
||||
package compare
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/duke-git/lancet/convertor"
|
||||
)
|
||||
|
||||
// operator type
|
||||
const (
|
||||
equal = "eq"
|
||||
lessThan = "lt"
|
||||
greaterThan = "gt"
|
||||
lessOrEqual = "le"
|
||||
greaterOrEqual = "ge"
|
||||
)
|
||||
|
||||
var (
|
||||
timeType = reflect.TypeOf(time.Time{})
|
||||
bytesType = reflect.TypeOf([]byte{})
|
||||
)
|
||||
|
||||
// Equal checks if two values are equal or not. (check both type and value)
|
||||
func Equal(left, right interface{}) bool {
|
||||
return compareValue(equal, left, right)
|
||||
}
|
||||
|
||||
// EqualValue checks if two values are equal or not. (check value only)
|
||||
func EqualValue(left, right interface{}) bool {
|
||||
ls, rs := convertor.ToString(left), convertor.ToString(right)
|
||||
return ls == rs
|
||||
}
|
||||
|
||||
// LessThan checks if value `left` less than value `right`.
|
||||
func LessThan(left, right interface{}) bool {
|
||||
return compareValue(lessThan, left, right)
|
||||
}
|
||||
|
||||
// GreaterThan checks if value `left` greater than value `right`.
|
||||
func GreaterThan(left, right interface{}) bool {
|
||||
return compareValue(greaterThan, left, right)
|
||||
}
|
||||
|
||||
// LessOrEqual checks if value `left` less than or equal to value `right`.
|
||||
func LessOrEqual(left, right interface{}) bool {
|
||||
return compareValue(lessOrEqual, left, right)
|
||||
}
|
||||
|
||||
// GreaterOrEqual checks if value `left` greater than or equal to value `right`.
|
||||
func GreaterOrEqual(left, right interface{}) bool {
|
||||
return compareValue(greaterOrEqual, left, right)
|
||||
}
|
||||
170
compare/compare_example_test.go
Normal file
170
compare/compare_example_test.go
Normal file
@@ -0,0 +1,170 @@
|
||||
package compare
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
func ExampleEqual() {
|
||||
result1 := Equal(1, 1)
|
||||
result2 := Equal("1", "1")
|
||||
result3 := Equal([]int{1, 2, 3}, []int{1, 2, 3})
|
||||
result4 := Equal(map[int]string{1: "a", 2: "b"}, map[int]string{1: "a", 2: "b"})
|
||||
|
||||
result5 := Equal(1, "1")
|
||||
result6 := Equal(1, int64(1))
|
||||
result7 := Equal([]int{1, 2}, []int{1, 2, 3})
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
fmt.Println(result6)
|
||||
fmt.Println(result7)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
// false
|
||||
}
|
||||
|
||||
func ExampleEqualValue() {
|
||||
result1 := EqualValue(1, 1)
|
||||
result2 := EqualValue(int(1), int64(1))
|
||||
result3 := EqualValue(1, "1")
|
||||
result4 := EqualValue(1, "2")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
}
|
||||
|
||||
func ExampleLessThan() {
|
||||
result1 := LessThan(1, 2)
|
||||
result2 := LessThan(1.1, 2.2)
|
||||
result3 := LessThan("a", "b")
|
||||
|
||||
time1 := time.Now()
|
||||
time2 := time1.Add(time.Second)
|
||||
result4 := LessThan(time1, time2)
|
||||
|
||||
result5 := LessThan(2, 1)
|
||||
result6 := LessThan(1, int64(2))
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
fmt.Println(result6)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
}
|
||||
|
||||
func ExampleGreaterThan() {
|
||||
result1 := GreaterThan(2, 1)
|
||||
result2 := GreaterThan(2.2, 1.1)
|
||||
result3 := GreaterThan("b", "a")
|
||||
|
||||
time1 := time.Now()
|
||||
time2 := time1.Add(time.Second)
|
||||
result4 := GreaterThan(time2, time1)
|
||||
|
||||
result5 := GreaterThan(1, 2)
|
||||
result6 := GreaterThan(int64(2), 1)
|
||||
result7 := GreaterThan("b", "c")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
fmt.Println(result6)
|
||||
fmt.Println(result7)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
// false
|
||||
}
|
||||
|
||||
func ExampleLessOrEqual() {
|
||||
result1 := LessOrEqual(1, 1)
|
||||
result2 := LessOrEqual(1.1, 2.2)
|
||||
result3 := LessOrEqual("a", "b")
|
||||
|
||||
time1 := time.Now()
|
||||
time2 := time1.Add(time.Second)
|
||||
result4 := LessOrEqual(time1, time2)
|
||||
|
||||
result5 := LessOrEqual(2, 1)
|
||||
result6 := LessOrEqual(1, int64(2))
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
fmt.Println(result6)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
}
|
||||
|
||||
func ExampleGreaterOrEqual() {
|
||||
result1 := GreaterOrEqual(1, 1)
|
||||
result2 := GreaterOrEqual(2.2, 1.1)
|
||||
result3 := GreaterOrEqual("b", "b")
|
||||
|
||||
time1 := time.Now()
|
||||
time2 := time1.Add(time.Second)
|
||||
result4 := GreaterOrEqual(time2, time1)
|
||||
|
||||
result5 := GreaterOrEqual(1, 2)
|
||||
result6 := GreaterOrEqual(int64(2), 1)
|
||||
result7 := GreaterOrEqual("b", "c")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
fmt.Println(result6)
|
||||
fmt.Println(result7)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
// false
|
||||
}
|
||||
323
compare/compare_internal.go
Normal file
323
compare/compare_internal.go
Normal file
@@ -0,0 +1,323 @@
|
||||
package compare
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/duke-git/lancet/convertor"
|
||||
)
|
||||
|
||||
func compareValue(operator string, left, right interface{}) bool {
|
||||
leftType, rightType := reflect.TypeOf(left), reflect.TypeOf(right)
|
||||
|
||||
if leftType.Kind() != rightType.Kind() {
|
||||
return false
|
||||
}
|
||||
|
||||
switch leftType.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
|
||||
reflect.Float32, reflect.Float64, reflect.Bool, reflect.String:
|
||||
return compareBasicValue(operator, left, right)
|
||||
|
||||
case reflect.Struct, reflect.Slice, reflect.Map:
|
||||
return compareRefValue(operator, left, right, leftType.Kind())
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func compareRefValue(operator string, leftObj, rightObj interface{}, kind reflect.Kind) bool {
|
||||
leftVal, rightVal := reflect.ValueOf(leftObj), reflect.ValueOf(rightObj)
|
||||
|
||||
switch kind {
|
||||
case reflect.Struct:
|
||||
|
||||
// compare time
|
||||
if leftVal.CanConvert(timeType) {
|
||||
timeObj1, ok := leftObj.(time.Time)
|
||||
if !ok {
|
||||
timeObj1 = leftVal.Convert(timeType).Interface().(time.Time)
|
||||
}
|
||||
|
||||
timeObj2, ok := rightObj.(time.Time)
|
||||
if !ok {
|
||||
timeObj2 = rightVal.Convert(timeType).Interface().(time.Time)
|
||||
}
|
||||
|
||||
return compareBasicValue(operator, timeObj1.UnixNano(), timeObj2.UnixNano())
|
||||
}
|
||||
|
||||
// for other struct type, only process equal operator
|
||||
switch operator {
|
||||
case equal:
|
||||
return objectsAreEqualValues(leftObj, rightObj)
|
||||
}
|
||||
|
||||
case reflect.Slice:
|
||||
// compare []byte
|
||||
if leftVal.CanConvert(bytesType) {
|
||||
bytesObj1, ok := leftObj.([]byte)
|
||||
if !ok {
|
||||
bytesObj1 = leftVal.Convert(bytesType).Interface().([]byte)
|
||||
}
|
||||
bytesObj2, ok := rightObj.([]byte)
|
||||
if !ok {
|
||||
bytesObj2 = rightVal.Convert(bytesType).Interface().([]byte)
|
||||
}
|
||||
|
||||
switch operator {
|
||||
case equal:
|
||||
if bytes.Compare(bytesObj1, bytesObj2) == 0 {
|
||||
return true
|
||||
}
|
||||
case lessThan:
|
||||
if bytes.Compare(bytesObj1, bytesObj2) == -1 {
|
||||
return true
|
||||
}
|
||||
case greaterThan:
|
||||
if bytes.Compare(bytesObj1, bytesObj2) == 1 {
|
||||
return true
|
||||
}
|
||||
case lessOrEqual:
|
||||
if bytes.Compare(bytesObj1, bytesObj2) <= 0 {
|
||||
return true
|
||||
}
|
||||
case greaterOrEqual:
|
||||
if bytes.Compare(bytesObj1, bytesObj2) >= 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// for other type slice, only process equal operator
|
||||
switch operator {
|
||||
case equal:
|
||||
return reflect.DeepEqual(leftObj, rightObj)
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
// only process equal operator
|
||||
switch operator {
|
||||
case equal:
|
||||
return reflect.DeepEqual(leftObj, rightObj)
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func objectsAreEqualValues(expected, actual interface{}) bool {
|
||||
if objectsAreEqual(expected, actual) {
|
||||
return true
|
||||
}
|
||||
|
||||
actualType := reflect.TypeOf(actual)
|
||||
if actualType == nil {
|
||||
return false
|
||||
}
|
||||
expectedValue := reflect.ValueOf(expected)
|
||||
if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) {
|
||||
// Attempt comparison after type conversion
|
||||
return reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), actual)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func objectsAreEqual(expected, actual interface{}) bool {
|
||||
if expected == nil || actual == nil {
|
||||
return expected == actual
|
||||
}
|
||||
|
||||
exp, ok := expected.([]byte)
|
||||
if !ok {
|
||||
return reflect.DeepEqual(expected, actual)
|
||||
}
|
||||
|
||||
act, ok := actual.([]byte)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if exp == nil || act == nil {
|
||||
return exp == nil && act == nil
|
||||
}
|
||||
return bytes.Equal(exp, act)
|
||||
}
|
||||
|
||||
// compareBasic compare basic value: integer, float, string, bool
|
||||
func compareBasicValue(operator string, leftValue, rightValue interface{}) bool {
|
||||
if leftValue == nil && rightValue == nil && operator == equal {
|
||||
return true
|
||||
}
|
||||
|
||||
switch leftVal := leftValue.(type) {
|
||||
case json.Number:
|
||||
if left, err := leftVal.Float64(); err == nil {
|
||||
switch rightVal := rightValue.(type) {
|
||||
case json.Number:
|
||||
if right, err := rightVal.Float64(); err == nil {
|
||||
switch operator {
|
||||
case equal:
|
||||
if left == right {
|
||||
return true
|
||||
}
|
||||
case lessThan:
|
||||
if left < right {
|
||||
return true
|
||||
}
|
||||
case greaterThan:
|
||||
if left > right {
|
||||
return true
|
||||
}
|
||||
case lessOrEqual:
|
||||
if left <= right {
|
||||
return true
|
||||
}
|
||||
case greaterOrEqual:
|
||||
if left >= right {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
case float32, float64, int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64:
|
||||
right, err := convertor.ToFloat(rightValue)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
switch operator {
|
||||
case equal:
|
||||
if left == right {
|
||||
return true
|
||||
}
|
||||
case lessThan:
|
||||
if left < right {
|
||||
return true
|
||||
}
|
||||
case greaterThan:
|
||||
if left > right {
|
||||
return true
|
||||
}
|
||||
case lessOrEqual:
|
||||
if left <= right {
|
||||
return true
|
||||
}
|
||||
case greaterOrEqual:
|
||||
if left >= right {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
case float32, float64, int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64:
|
||||
left, err := convertor.ToFloat(leftValue)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
switch rightVal := rightValue.(type) {
|
||||
case json.Number:
|
||||
if right, err := rightVal.Float64(); err == nil {
|
||||
switch operator {
|
||||
case equal:
|
||||
if left == right {
|
||||
return true
|
||||
}
|
||||
case lessThan:
|
||||
if left < right {
|
||||
return true
|
||||
}
|
||||
case greaterThan:
|
||||
if left > right {
|
||||
return true
|
||||
}
|
||||
case lessOrEqual:
|
||||
if left <= right {
|
||||
return true
|
||||
}
|
||||
case greaterOrEqual:
|
||||
if left >= right {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
case float32, float64, int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64:
|
||||
right, err := convertor.ToFloat(rightValue)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
switch operator {
|
||||
case equal:
|
||||
if left == right {
|
||||
return true
|
||||
}
|
||||
case lessThan:
|
||||
if left < right {
|
||||
return true
|
||||
}
|
||||
case greaterThan:
|
||||
if left > right {
|
||||
return true
|
||||
}
|
||||
case lessOrEqual:
|
||||
if left <= right {
|
||||
return true
|
||||
}
|
||||
case greaterOrEqual:
|
||||
if left >= right {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case string:
|
||||
left := leftVal
|
||||
switch right := rightValue.(type) {
|
||||
case string:
|
||||
switch operator {
|
||||
case equal:
|
||||
if left == right {
|
||||
return true
|
||||
}
|
||||
case lessThan:
|
||||
if left < right {
|
||||
return true
|
||||
}
|
||||
case greaterThan:
|
||||
if left > right {
|
||||
return true
|
||||
}
|
||||
case lessOrEqual:
|
||||
if left <= right {
|
||||
return true
|
||||
}
|
||||
case greaterOrEqual:
|
||||
if left >= right {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case bool:
|
||||
left := leftVal
|
||||
switch right := rightValue.(type) {
|
||||
case bool:
|
||||
switch operator {
|
||||
case equal:
|
||||
if left == right {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
134
compare/compare_test.go
Normal file
134
compare/compare_test.go
Normal file
@@ -0,0 +1,134 @@
|
||||
package compare
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/duke-git/lancet/internal"
|
||||
)
|
||||
|
||||
func TestEqual(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestEqual")
|
||||
|
||||
assert.Equal(true, Equal(1, 1))
|
||||
assert.Equal(true, Equal(int64(1), int64(1)))
|
||||
assert.Equal(true, Equal("a", "a"))
|
||||
assert.Equal(true, Equal(true, true))
|
||||
assert.Equal(true, Equal([]int{1, 2, 3}, []int{1, 2, 3}))
|
||||
assert.Equal(true, Equal(map[int]string{1: "a", 2: "b"}, map[int]string{1: "a", 2: "b"}))
|
||||
|
||||
assert.Equal(false, Equal(1, 2))
|
||||
assert.Equal(false, Equal(1, int64(1)))
|
||||
assert.Equal(false, Equal("a", "b"))
|
||||
assert.Equal(false, Equal(true, false))
|
||||
assert.Equal(false, Equal([]int{1, 2}, []int{1, 2, 3}))
|
||||
assert.Equal(false, Equal(map[int]string{1: "a", 2: "b"}, map[int]string{1: "a"}))
|
||||
|
||||
time1 := time.Now()
|
||||
time2 := time1.Add(time.Second)
|
||||
time3 := time1.Add(time.Second)
|
||||
|
||||
assert.Equal(false, Equal(time1, time2))
|
||||
assert.Equal(true, Equal(time2, time3))
|
||||
|
||||
st1 := struct {
|
||||
A string
|
||||
B string
|
||||
}{
|
||||
A: "a",
|
||||
B: "b",
|
||||
}
|
||||
|
||||
st2 := struct {
|
||||
A string
|
||||
B string
|
||||
}{
|
||||
A: "a",
|
||||
B: "b",
|
||||
}
|
||||
|
||||
st3 := struct {
|
||||
A string
|
||||
B string
|
||||
}{
|
||||
A: "a1",
|
||||
B: "b",
|
||||
}
|
||||
|
||||
assert.Equal(true, Equal(st1, st2))
|
||||
assert.Equal(false, Equal(st1, st3))
|
||||
}
|
||||
|
||||
func TestEqualValue(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestEqualValue")
|
||||
|
||||
assert.Equal(true, EqualValue(1, 1))
|
||||
assert.Equal(true, EqualValue(int(1), int64(1)))
|
||||
assert.Equal(true, EqualValue(1, "1"))
|
||||
|
||||
assert.Equal(false, EqualValue(1, "2"))
|
||||
}
|
||||
|
||||
func TestLessThan(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestLessThan")
|
||||
|
||||
assert.Equal(true, LessThan(1, 2))
|
||||
assert.Equal(true, LessThan(1.1, 2.2))
|
||||
assert.Equal(true, LessThan("a", "b"))
|
||||
|
||||
time1 := time.Now()
|
||||
time2 := time1.Add(time.Second)
|
||||
assert.Equal(true, LessThan(time1, time2))
|
||||
|
||||
assert.Equal(false, LessThan(1, 1))
|
||||
assert.Equal(false, LessThan(1, int64(1)))
|
||||
}
|
||||
|
||||
func TestGreaterThan(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestGreaterThan")
|
||||
|
||||
assert.Equal(true, GreaterThan(2, 1))
|
||||
assert.Equal(true, GreaterThan(2.2, 1.1))
|
||||
assert.Equal(true, GreaterThan("b", "a"))
|
||||
|
||||
time1 := time.Now()
|
||||
time2 := time1.Add(time.Second)
|
||||
assert.Equal(true, GreaterThan(time2, time1))
|
||||
|
||||
assert.Equal(false, GreaterThan(1, 2))
|
||||
assert.Equal(false, GreaterThan(int64(2), 1))
|
||||
assert.Equal(false, GreaterThan("b", "c"))
|
||||
}
|
||||
|
||||
func TestLessOrEqual(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestLessOrEqual")
|
||||
|
||||
assert.Equal(true, LessOrEqual(1, 2))
|
||||
assert.Equal(true, LessOrEqual(1, 1))
|
||||
assert.Equal(true, LessOrEqual(1.1, 2.2))
|
||||
assert.Equal(true, LessOrEqual("a", "b"))
|
||||
|
||||
time1 := time.Now()
|
||||
time2 := time1.Add(time.Second)
|
||||
assert.Equal(true, LessOrEqual(time1, time2))
|
||||
|
||||
assert.Equal(false, LessOrEqual(2, 1))
|
||||
assert.Equal(false, LessOrEqual(1, int64(2)))
|
||||
}
|
||||
|
||||
func TestGreaterOrEqual(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestGreaterThan")
|
||||
|
||||
assert.Equal(true, GreaterOrEqual(2, 1))
|
||||
assert.Equal(true, GreaterOrEqual(1, 1))
|
||||
assert.Equal(true, GreaterOrEqual(2.2, 1.1))
|
||||
assert.Equal(true, GreaterOrEqual("b", "b"))
|
||||
|
||||
time1 := time.Now()
|
||||
time2 := time1.Add(time.Second)
|
||||
assert.Equal(true, GreaterOrEqual(time2, time1))
|
||||
|
||||
assert.Equal(false, GreaterOrEqual(1, 2))
|
||||
assert.Equal(false, GreaterOrEqual(int64(2), 1))
|
||||
assert.Equal(false, GreaterOrEqual("b", "c"))
|
||||
}
|
||||
@@ -278,44 +278,99 @@ func DeepClone(src interface{}) interface{} {
|
||||
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))
|
||||
}
|
||||
}()
|
||||
// // 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)
|
||||
// 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
|
||||
// }
|
||||
|
||||
// CopyProperties copies each field from the source into the destination. It recursively copies struct pointers and interfaces that contain struct pointers.
|
||||
// use json.Marshal/Unmarshal, so json tag should be set for fields of dst and src struct.
|
||||
func CopyProperties(dst, src interface{}) error {
|
||||
dstType, srcType := reflect.TypeOf(dst), reflect.TypeOf(src)
|
||||
|
||||
if dstType.Kind() != reflect.Ptr || dstType.Elem().Kind() != reflect.Struct {
|
||||
return errors.New("CopyProperties: param dst should be struct pointer")
|
||||
return errors.New("CopyProperties: parameter dst should be struct pointer")
|
||||
}
|
||||
|
||||
if srcType.Kind() == reflect.Ptr {
|
||||
srcType, srcValue = srcType.Elem(), srcValue.Elem()
|
||||
srcType = srcType.Elem()
|
||||
}
|
||||
if srcType.Kind() != reflect.Struct {
|
||||
return errors.New("CopyProperties: param src should be a struct or struct pointer")
|
||||
return errors.New("CopyProperties: parameter 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)
|
||||
}
|
||||
bytes, err := json.Marshal(src)
|
||||
if err != nil {
|
||||
return fmt.Errorf("CopyProperties: unable to marshal src: %s", err)
|
||||
}
|
||||
err = json.Unmarshal(bytes, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf("CopyProperties: unable to unmarshal into dst: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToInterface converts reflect value to its interface type.
|
||||
func ToInterface(v reflect.Value) (value interface{}, ok bool) {
|
||||
if v.IsValid() && v.CanInterface() {
|
||||
return v.Interface(), true
|
||||
}
|
||||
switch v.Kind() {
|
||||
case reflect.Bool:
|
||||
return v.Bool(), true
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return v.Int(), true
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return v.Uint(), true
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v.Float(), true
|
||||
case reflect.Complex64, reflect.Complex128:
|
||||
return v.Complex(), true
|
||||
case reflect.String:
|
||||
return v.String(), true
|
||||
case reflect.Ptr:
|
||||
return ToInterface(v.Elem())
|
||||
case reflect.Interface:
|
||||
return ToInterface(v.Elem())
|
||||
default:
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,49 +262,80 @@ func TestDeepClone(t *testing.T) {
|
||||
func TestCopyProperties(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestCopyProperties")
|
||||
|
||||
type Address struct {
|
||||
Country string
|
||||
ZipCode string
|
||||
type Disk struct {
|
||||
Name string `json:"name"`
|
||||
Total string `json:"total"`
|
||||
Used string `json:"used"`
|
||||
Percent float64 `json:"percent"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
Name string
|
||||
Age int
|
||||
Role string
|
||||
Addr Address
|
||||
Hobbys []string
|
||||
salary int
|
||||
type DiskVO struct {
|
||||
Name string `json:"name"`
|
||||
Total string `json:"total"`
|
||||
Used string `json:"used"`
|
||||
Percent float64 `json:"percent"`
|
||||
}
|
||||
|
||||
type Employee struct {
|
||||
Name string
|
||||
Age int
|
||||
Role string
|
||||
Addr Address
|
||||
Hobbys []string
|
||||
salary int
|
||||
type Indicator struct {
|
||||
Id string `json:"id"`
|
||||
Ip string `json:"ip"`
|
||||
UpTime string `json:"upTime"`
|
||||
LoadAvg string `json:"loadAvg"`
|
||||
Cpu int `json:"cpu"`
|
||||
Disk []Disk `json:"disk"`
|
||||
Stop chan bool `json:"-"`
|
||||
}
|
||||
|
||||
user := User{Name: "user001", Age: 10, Role: "Admin", Addr: Address{Country: "CN", ZipCode: "001"}, Hobbys: []string{"a", "b"}, salary: 1000}
|
||||
type IndicatorVO struct {
|
||||
Id string `json:"id"`
|
||||
Ip string `json:"ip"`
|
||||
UpTime string `json:"upTime"`
|
||||
LoadAvg string `json:"loadAvg"`
|
||||
Cpu int64 `json:"cpu"`
|
||||
Disk []DiskVO `json:"disk"`
|
||||
}
|
||||
|
||||
employee1 := Employee{}
|
||||
indicator := &Indicator{Id: "001", Ip: "127.0.0.1", Cpu: 1, Disk: []Disk{
|
||||
{Name: "disk-001", Total: "100", Used: "1", Percent: 10},
|
||||
{Name: "disk-002", Total: "200", Used: "1", Percent: 20},
|
||||
{Name: "disk-003", Total: "300", Used: "1", Percent: 30},
|
||||
}}
|
||||
|
||||
err := CopyProperties(&employee1, &user)
|
||||
indicatorVO := IndicatorVO{}
|
||||
|
||||
err := CopyProperties(&indicatorVO, indicator)
|
||||
|
||||
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)
|
||||
assert.Equal("001", indicatorVO.Id)
|
||||
assert.Equal("127.0.0.1", indicatorVO.Ip)
|
||||
assert.Equal(3, len(indicatorVO.Disk))
|
||||
}
|
||||
|
||||
func TestToInterface(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestToInterface")
|
||||
|
||||
cases := []reflect.Value{
|
||||
reflect.ValueOf("abc"),
|
||||
reflect.ValueOf(int(0)), reflect.ValueOf(int8(1)), reflect.ValueOf(int16(-1)), reflect.ValueOf(int32(123)), reflect.ValueOf(int64(123)),
|
||||
reflect.ValueOf(uint(123)), reflect.ValueOf(uint8(123)), reflect.ValueOf(uint16(123)), reflect.ValueOf(uint32(123)), reflect.ValueOf(uint64(123)),
|
||||
reflect.ValueOf(float64(12.3)), reflect.ValueOf(float32(12.3)),
|
||||
reflect.ValueOf(true), reflect.ValueOf(false),
|
||||
}
|
||||
|
||||
expected := []interface{}{
|
||||
"abc",
|
||||
0, int8(1), int16(-1), int32(123), int64(123),
|
||||
uint(123), uint8(123), uint16(123), uint32(123), uint64(123),
|
||||
float64(12.3), float32(12.3),
|
||||
true, false,
|
||||
}
|
||||
|
||||
for i := 0; i < len(cases); i++ {
|
||||
actual, _ := ToInterface(cases[i])
|
||||
assert.Equal(expected[i], actual)
|
||||
}
|
||||
|
||||
nilVal, ok := ToInterface(reflect.ValueOf(nil))
|
||||
assert.EqualValues(nil, nilVal)
|
||||
assert.Equal(false, ok)
|
||||
}
|
||||
|
||||
@@ -4,24 +4,24 @@
|
||||
// Package datetime implements some functions to format date and time.
|
||||
// Note:
|
||||
// 1. `format` param in FormatTimeToStr function should be as flow:
|
||||
//"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"
|
||||
// "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"
|
||||
package datetime
|
||||
|
||||
import (
|
||||
@@ -35,7 +35,7 @@ func init() {
|
||||
timeFormat = map[string]string{
|
||||
"yyyy-mm-dd hh:mm:ss": "2006-01-02 15:04:05",
|
||||
"yyyy-mm-dd hh:mm": "2006-01-02 15:04",
|
||||
"yyyy-mm-dd hh": "2006-01-02 15:04",
|
||||
"yyyy-mm-dd hh": "2006-01-02 15",
|
||||
"yyyy-mm-dd": "2006-01-02",
|
||||
"yyyy-mm": "2006-01",
|
||||
"mm-dd": "01-02",
|
||||
@@ -69,6 +69,11 @@ func AddDay(t time.Time, day int64) time.Time {
|
||||
return t.Add(24 * time.Hour * time.Duration(day))
|
||||
}
|
||||
|
||||
// AddYear add or sub year to the time.
|
||||
func AddYear(t time.Time, year int64) time.Time {
|
||||
return t.Add(365 * 24 * time.Hour * time.Duration(year))
|
||||
}
|
||||
|
||||
// GetNowDate return format yyyy-mm-dd of current date
|
||||
func GetNowDate() string {
|
||||
return time.Now().Format("2006-01-02")
|
||||
@@ -180,3 +185,28 @@ func BeginOfYear(t time.Time) time.Time {
|
||||
func EndOfYear(t time.Time) time.Time {
|
||||
return BeginOfYear(t).AddDate(1, 0, 0).Add(-time.Nanosecond)
|
||||
}
|
||||
|
||||
// IsLeapYear check if param year is leap year or not.
|
||||
func IsLeapYear(year int) bool {
|
||||
return year%4 == 0 && (year%100 != 0 || year%400 == 0)
|
||||
}
|
||||
|
||||
// BetweenSeconds returns the number of seconds between two times.
|
||||
func BetweenSeconds(t1 time.Time, t2 time.Time) int64 {
|
||||
index := t2.Unix() - t1.Unix()
|
||||
return index
|
||||
}
|
||||
|
||||
// DayOfYear returns which day of the year the parameter date `t` is.
|
||||
func DayOfYear(t time.Time) int {
|
||||
y, m, d := t.Date()
|
||||
firstDay := time.Date(y, 1, 1, 0, 0, 0, 0, t.Location())
|
||||
nowDate := time.Date(y, m, d, 0, 0, 0, 0, t.Location())
|
||||
|
||||
return int(nowDate.Sub(firstDay).Hours() / 24)
|
||||
}
|
||||
|
||||
// IsWeekend checks if passed time is weekend or not.
|
||||
func IsWeekend(t time.Time) bool {
|
||||
return time.Saturday == t.Weekday() || time.Sunday == t.Weekday()
|
||||
}
|
||||
|
||||
@@ -46,6 +46,19 @@ func TestAddMinute(t *testing.T) {
|
||||
assert.Equal(float64(-2), diff2.Minutes())
|
||||
}
|
||||
|
||||
func TestAddYear(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestAddDay")
|
||||
|
||||
now := time.Now()
|
||||
after2Years := AddYear(now, 1)
|
||||
diff1 := after2Years.Sub(now)
|
||||
assert.Equal(float64(8760), diff1.Hours())
|
||||
|
||||
before2Years := AddYear(now, -1)
|
||||
diff2 := before2Years.Sub(now)
|
||||
assert.Equal(float64(-8760), diff2.Hours())
|
||||
}
|
||||
|
||||
func TestGetNowDate(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestGetNowDate")
|
||||
expected := time.Now().Format("2006-01-02")
|
||||
@@ -231,3 +244,57 @@ func TestEndOfYear(t *testing.T) {
|
||||
|
||||
assert.Equal(expected, actual)
|
||||
}
|
||||
|
||||
func TestIsLeapYear(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestEndOfYear")
|
||||
|
||||
result1 := IsLeapYear(2000)
|
||||
result2 := IsLeapYear(2001)
|
||||
|
||||
assert.Equal(true, result1)
|
||||
assert.Equal(false, result2)
|
||||
}
|
||||
|
||||
func TestBetweenSeconds(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestBetweenSeconds")
|
||||
|
||||
today := time.Now()
|
||||
tomorrow := AddDay(today, 1)
|
||||
yesterday := AddDay(today, -1)
|
||||
|
||||
result1 := BetweenSeconds(today, tomorrow)
|
||||
result2 := BetweenSeconds(today, yesterday)
|
||||
|
||||
assert.Equal(int64(86400), result1)
|
||||
assert.Equal(int64(-86400), result2)
|
||||
}
|
||||
|
||||
func TestDayOfYear(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestDayOfYear")
|
||||
date1 := time.Date(2023, 02, 01, 1, 1, 1, 0, time.Local)
|
||||
result1 := DayOfYear(date1)
|
||||
assert.Equal(31, result1)
|
||||
|
||||
date2 := time.Date(2023, 01, 02, 1, 1, 1, 0, time.Local)
|
||||
result2 := DayOfYear(date2)
|
||||
assert.Equal(1, result2)
|
||||
|
||||
date3 := time.Date(2023, 01, 01, 1, 1, 1, 0, time.Local)
|
||||
result3 := DayOfYear(date3)
|
||||
assert.Equal(0, result3)
|
||||
}
|
||||
|
||||
func TestIsWeekend(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestIsWeekend")
|
||||
date := time.Date(2023, 06, 03, 0, 0, 0, 0, time.Local)
|
||||
result := IsWeekend(date)
|
||||
assert.Equal(true, result)
|
||||
|
||||
date1 := time.Date(2023, 06, 04, 0, 0, 0, 0, time.Local)
|
||||
result1 := IsWeekend(date1)
|
||||
assert.Equal(true, result1)
|
||||
|
||||
date2 := time.Date(2023, 06, 02, 0, 0, 0, 0, time.Local)
|
||||
result2 := IsWeekend(date2)
|
||||
assert.Equal(false, result2)
|
||||
}
|
||||
|
||||
326
docs/compare.md
Normal file
326
docs/compare.md
Normal file
@@ -0,0 +1,326 @@
|
||||
# Compare
|
||||
|
||||
Package compare provides a lightweight comparison function on any type.
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/v1/compare/compare.go](https://github.com/duke-git/lancet/blob/v1/compare/compare.go)
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/v1/compare/compare_internal.go](https://github.com/duke-git/lancet/blob/v1/compare/compare_internal.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Usage:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/condition"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
|
||||
- [Equal](#Equal)
|
||||
- [EqualValue](#EqualValue)
|
||||
- [LessThan](#LessThan)
|
||||
- [GreaterThan](#GreaterThan)
|
||||
- [LessOrEqual](#LessOrEqual)
|
||||
- [GreaterOrEqual](#GreaterOrEqual)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
### <span id="Equal">Equal</span>
|
||||
|
||||
<p>Checks if two values are equal or not. (check both type and value)</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Equal(left, right any) bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/compare"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := compare.Equal(1, 1)
|
||||
result2 := compare.Equal("1", "1")
|
||||
result3 := compare.Equal([]int{1, 2, 3}, []int{1, 2, 3})
|
||||
result4 := compare.Equal(map[int]string{1: "a", 2: "b"}, map[int]string{1: "a", 2: "b"})
|
||||
|
||||
result5 := compare.Equal(1, "1")
|
||||
result6 := compare.Equal(1, int64(1))
|
||||
result7 := compare.Equal([]int{1, 2}, []int{1, 2, 3})
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
fmt.Println(result6)
|
||||
fmt.Println(result7)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="EqualValue">EqualValue</span>
|
||||
|
||||
<p>Checks if two values are equal or not. (check value only)</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func EqualValue(left, right any) bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/compare"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := compare.EqualValue(1, 1)
|
||||
result2 := compare.EqualValue(int(1), int64(1))
|
||||
result3 := compare.EqualValue(1, "1")
|
||||
result4 := compare.EqualValue(1, "2")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="LessThan">LessThan</span>
|
||||
|
||||
<p>Checks if value `left` less than value `right`.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func LessThan(left, right any) bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/compare"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := compare.LessThan(1, 2)
|
||||
result2 := compare.LessThan(1.1, 2.2)
|
||||
result3 := compare.LessThan("a", "b")
|
||||
|
||||
time1 := time.Now()
|
||||
time2 := time1.Add(time.Second)
|
||||
result4 := compare.LessThan(time1, time2)
|
||||
|
||||
result5 := compare.LessThan(2, 1)
|
||||
result6 := compare.LessThan(1, int64(2))
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
fmt.Println(result6)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="GreaterThan">GreaterThan</span>
|
||||
|
||||
<p>Checks if value `left` greater than value `right`.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func GreaterThan(left, right any) bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/compare"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := compare.GreaterThan(2, 1)
|
||||
result2 := compare.GreaterThan(2.2, 1.1)
|
||||
result3 := compare.GreaterThan("b", "a")
|
||||
|
||||
time1 := time.Now()
|
||||
time2 := time1.Add(time.Second)
|
||||
result4 := compare.GreaterThan(time2, time1)
|
||||
|
||||
result5 := compare.GreaterThan(1, 2)
|
||||
result6 := compare.GreaterThan(int64(2), 1)
|
||||
result7 := compare.GreaterThan("b", "c")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
fmt.Println(result6)
|
||||
fmt.Println(result7)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="LessOrEqual">LessOrEqual</span>
|
||||
|
||||
<p>Checks if value `left` less than or equal than value `right`.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func LessOrEqual(left, right any) bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/compare"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := compare.LessOrEqual(1, 1)
|
||||
result2 := compare.LessOrEqual(1.1, 2.2)
|
||||
result3 := compare.LessOrEqual("a", "b")
|
||||
|
||||
time1 := time.Now()
|
||||
time2 := time1.Add(time.Second)
|
||||
result4 := compare.LessOrEqual(time1, time2)
|
||||
|
||||
result5 := compare.LessOrEqual(2, 1)
|
||||
result6 := compare.LessOrEqual(1, int64(2))
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
fmt.Println(result6)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="GreaterOrEqual">GreaterOrEqual</span>
|
||||
|
||||
<p>Checks if value `left` less greater or equal than value `right`.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func GreaterOrEqual(left, right any) bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/compare"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := compare.GreaterOrEqual(1, 1)
|
||||
result2 := compare.GreaterOrEqual(2.2, 1.1)
|
||||
result3 := compare.GreaterOrEqual("b", "b")
|
||||
|
||||
time1 := time.Now()
|
||||
time2 := time1.Add(time.Second)
|
||||
result4 := compare.GreaterOrEqual(time2, time1)
|
||||
|
||||
result5 := compare.GreaterOrEqual(1, 2)
|
||||
result6 := compare.GreaterOrEqual(int64(2), 1)
|
||||
result7 := compare.GreaterOrEqual("b", "c")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
fmt.Println(result6)
|
||||
fmt.Println(result7)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
// false
|
||||
}
|
||||
```
|
||||
326
docs/compare_zh-CN.md
Normal file
326
docs/compare_zh-CN.md
Normal file
@@ -0,0 +1,326 @@
|
||||
# Compare
|
||||
|
||||
compare包提供几个轻量级的类型比较函数。
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/v1/compare/compare.go](https://github.com/duke-git/lancet/blob/v1/compare/compare.go)
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/v1/compare/compare_internal.go](https://github.com/duke-git/lancet/blob/v1/compare/compare_internal.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 用法:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/duke-git/lancet/condition"
|
||||
)
|
||||
```
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
|
||||
- [Equal](#Equal)
|
||||
- [EqualValue](#EqualValue)
|
||||
- [LessThan](#LessThan)
|
||||
- [GreaterThan](#GreaterThan)
|
||||
- [LessOrEqual](#LessOrEqual)
|
||||
- [GreaterOrEqual](#GreaterOrEqual)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
### <span id="Equal">Equal</span>
|
||||
|
||||
<p>检查两个值是否相等(检查类型和值)</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Equal(left, right any) bool
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/compare"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := compare.Equal(1, 1)
|
||||
result2 := compare.Equal("1", "1")
|
||||
result3 := compare.Equal([]int{1, 2, 3}, []int{1, 2, 3})
|
||||
result4 := compare.Equal(map[int]string{1: "a", 2: "b"}, map[int]string{1: "a", 2: "b"})
|
||||
|
||||
result5 := compare.Equal(1, "1")
|
||||
result6 := compare.Equal(1, int64(1))
|
||||
result7 := compare.Equal([]int{1, 2}, []int{1, 2, 3})
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
fmt.Println(result6)
|
||||
fmt.Println(result7)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="EqualValue">EqualValue</span>
|
||||
|
||||
<p>检查两个值是否相等(只检查值)</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func EqualValue(left, right any) bool
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/compare"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := compare.EqualValue(1, 1)
|
||||
result2 := compare.EqualValue(int(1), int64(1))
|
||||
result3 := compare.EqualValue(1, "1")
|
||||
result4 := compare.EqualValue(1, "2")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="LessThan">LessThan</span>
|
||||
|
||||
<p>验证参数`left`的值是否小于参数`right`的值。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func LessThan(left, right any) bool
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/compare"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := compare.LessThan(1, 2)
|
||||
result2 := compare.LessThan(1.1, 2.2)
|
||||
result3 := compare.LessThan("a", "b")
|
||||
|
||||
time1 := time.Now()
|
||||
time2 := time1.Add(time.Second)
|
||||
result4 := compare.LessThan(time1, time2)
|
||||
|
||||
result5 := compare.LessThan(2, 1)
|
||||
result6 := compare.LessThan(1, int64(2))
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
fmt.Println(result6)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="GreaterThan">GreaterThan</span>
|
||||
|
||||
<p>验证参数`left`的值是否大于参数`right`的值。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func GreaterThan(left, right any) bool
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/compare"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := compare.GreaterThan(2, 1)
|
||||
result2 := compare.GreaterThan(2.2, 1.1)
|
||||
result3 := compare.GreaterThan("b", "a")
|
||||
|
||||
time1 := time.Now()
|
||||
time2 := time1.Add(time.Second)
|
||||
result4 := compare.GreaterThan(time2, time1)
|
||||
|
||||
result5 := compare.GreaterThan(1, 2)
|
||||
result6 := compare.GreaterThan(int64(2), 1)
|
||||
result7 := compare.GreaterThan("b", "c")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
fmt.Println(result6)
|
||||
fmt.Println(result7)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="LessOrEqual">LessOrEqual</span>
|
||||
|
||||
<p>验证参数`left`的值是否小于或等于参数`right`的值。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func LessOrEqual(left, right any) bool
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/compare"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := compare.LessOrEqual(1, 1)
|
||||
result2 := compare.LessOrEqual(1.1, 2.2)
|
||||
result3 := compare.LessOrEqual("a", "b")
|
||||
|
||||
time1 := time.Now()
|
||||
time2 := time1.Add(time.Second)
|
||||
result4 := compare.LessOrEqual(time1, time2)
|
||||
|
||||
result5 := compare.LessOrEqual(2, 1)
|
||||
result6 := compare.LessOrEqual(1, int64(2))
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
fmt.Println(result6)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="GreaterOrEqual">GreaterOrEqual</span>
|
||||
|
||||
<p>验证参数`left`的值是否大于或参数`right`的值。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func GreaterOrEqual(left, right any) bool
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/compare"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := compare.GreaterOrEqual(1, 1)
|
||||
result2 := compare.GreaterOrEqual(2.2, 1.1)
|
||||
result3 := compare.GreaterOrEqual("b", "b")
|
||||
|
||||
time1 := time.Now()
|
||||
time2 := time1.Add(time.Second)
|
||||
result4 := compare.GreaterOrEqual(time2, time1)
|
||||
|
||||
result5 := compare.GreaterOrEqual(1, 2)
|
||||
result6 := compare.GreaterOrEqual(int64(2), 1)
|
||||
result7 := compare.GreaterOrEqual("b", "c")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
fmt.Println(result6)
|
||||
fmt.Println(result7)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
// false
|
||||
// false
|
||||
}
|
||||
```
|
||||
@@ -36,6 +36,9 @@ import (
|
||||
- [EncodeByte](#EncodeByte)
|
||||
- [DecodeByte](#DecodeByte)
|
||||
- [DeepClone](#DeepClone)
|
||||
- [CopyProperties](#CopyProperties)
|
||||
- [ToInterface](#ToInterface)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -501,3 +504,117 @@ func main() {
|
||||
// &{test 1 0.1 true <nil> } false
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="CopyProperties">CopyProperties</span>
|
||||
|
||||
<p>Copies each field from the source struct into the destination struct. Use json.Marshal/Unmarshal, so json tag should be set for fields of dst and src struct.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func CopyProperties(dst, src interface{}) error
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type Disk struct {
|
||||
Name string `json:"name"`
|
||||
Total string `json:"total"`
|
||||
Used string `json:"used"`
|
||||
Percent float64 `json:"percent"`
|
||||
}
|
||||
|
||||
type DiskVO struct {
|
||||
Name string `json:"name"`
|
||||
Total string `json:"total"`
|
||||
Used string `json:"used"`
|
||||
Percent float64 `json:"percent"`
|
||||
}
|
||||
|
||||
type Indicator struct {
|
||||
Id string `json:"id"`
|
||||
Ip string `json:"ip"`
|
||||
UpTime string `json:"upTime"`
|
||||
LoadAvg string `json:"loadAvg"`
|
||||
Cpu int `json:"cpu"`
|
||||
Disk []Disk `json:"disk"`
|
||||
Stop chan bool `json:"-"`
|
||||
}
|
||||
|
||||
type IndicatorVO struct {
|
||||
Id string `json:"id"`
|
||||
Ip string `json:"ip"`
|
||||
UpTime string `json:"upTime"`
|
||||
LoadAvg string `json:"loadAvg"`
|
||||
Cpu int64 `json:"cpu"`
|
||||
Disk []DiskVO `json:"disk"`
|
||||
}
|
||||
|
||||
indicator := &Indicator{Id: "001", Ip: "127.0.0.1", Cpu: 1, Disk: []Disk{
|
||||
{Name: "disk-001", Total: "100", Used: "1", Percent: 10},
|
||||
{Name: "disk-002", Total: "200", Used: "1", Percent: 20},
|
||||
{Name: "disk-003", Total: "300", Used: "1", Percent: 30},
|
||||
}}
|
||||
|
||||
indicatorVO := IndicatorVO{}
|
||||
|
||||
err := convertor.CopyProperties(&indicatorVO, indicator)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(indicatorVO.Id)
|
||||
fmt.Println(indicatorVO.Ip)
|
||||
fmt.Println(len(indicatorVO.Disk))
|
||||
|
||||
// Output:
|
||||
// 001
|
||||
// 127.0.0.1
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="ToInterface">ToInterface</span>
|
||||
|
||||
<p>Converts reflect value to its interface type.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ToInterface(v reflect.Value) (value interface{}, ok bool)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
val := reflect.ValueOf("abc")
|
||||
iVal, ok := convertor.ToInterface(val)
|
||||
|
||||
fmt.Printf("%T\n", iVal)
|
||||
fmt.Printf("%v\n", iVal)
|
||||
fmt.Println(ok)
|
||||
|
||||
// Output:
|
||||
// string
|
||||
// abc
|
||||
// true
|
||||
}
|
||||
```
|
||||
@@ -36,6 +36,8 @@ import (
|
||||
- [EncodeByte](#EncodeByte)
|
||||
- [DecodeByte](#DecodeByte)
|
||||
- [DeepClone](#DeepClone)
|
||||
- [CopyProperties](#CopyProperties)
|
||||
- [ToInterface](#ToInterface)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -501,3 +503,118 @@ func main() {
|
||||
// &{test 1 0.1 true <nil> } false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="CopyProperties">CopyProperties</span>
|
||||
|
||||
<p>拷贝不同结构体之间的同名字段。使用json.Marshal序列化,需要设置dst和src struct字段的json tag。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func CopyProperties(dst, src interface{}) error
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type Disk struct {
|
||||
Name string `json:"name"`
|
||||
Total string `json:"total"`
|
||||
Used string `json:"used"`
|
||||
Percent float64 `json:"percent"`
|
||||
}
|
||||
|
||||
type DiskVO struct {
|
||||
Name string `json:"name"`
|
||||
Total string `json:"total"`
|
||||
Used string `json:"used"`
|
||||
Percent float64 `json:"percent"`
|
||||
}
|
||||
|
||||
type Indicator struct {
|
||||
Id string `json:"id"`
|
||||
Ip string `json:"ip"`
|
||||
UpTime string `json:"upTime"`
|
||||
LoadAvg string `json:"loadAvg"`
|
||||
Cpu int `json:"cpu"`
|
||||
Disk []Disk `json:"disk"`
|
||||
Stop chan bool `json:"-"`
|
||||
}
|
||||
|
||||
type IndicatorVO struct {
|
||||
Id string `json:"id"`
|
||||
Ip string `json:"ip"`
|
||||
UpTime string `json:"upTime"`
|
||||
LoadAvg string `json:"loadAvg"`
|
||||
Cpu int64 `json:"cpu"`
|
||||
Disk []DiskVO `json:"disk"`
|
||||
}
|
||||
|
||||
indicator := &Indicator{Id: "001", Ip: "127.0.0.1", Cpu: 1, Disk: []Disk{
|
||||
{Name: "disk-001", Total: "100", Used: "1", Percent: 10},
|
||||
{Name: "disk-002", Total: "200", Used: "1", Percent: 20},
|
||||
{Name: "disk-003", Total: "300", Used: "1", Percent: 30},
|
||||
}}
|
||||
|
||||
indicatorVO := IndicatorVO{}
|
||||
|
||||
err := convertor.CopyProperties(&indicatorVO, indicator)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(indicatorVO.Id)
|
||||
fmt.Println(indicatorVO.Ip)
|
||||
fmt.Println(len(indicatorVO.Disk))
|
||||
|
||||
// Output:
|
||||
// 001
|
||||
// 127.0.0.1
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="ToInterface">ToInterface</span>
|
||||
|
||||
<p>将反射值转换成对应的interface类型。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ToInterface(v reflect.Value) (value interface{}, ok bool)
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/convertor"
|
||||
)
|
||||
|
||||
func main() {
|
||||
val := reflect.ValueOf("abc")
|
||||
iVal, ok := convertor.ToInterface(val)
|
||||
|
||||
fmt.Printf("%T\n", iVal)
|
||||
fmt.Printf("%v\n", iVal)
|
||||
fmt.Println(ok)
|
||||
|
||||
// Output:
|
||||
// string
|
||||
// abc
|
||||
// true
|
||||
}
|
||||
```
|
||||
236
docs/datetime.md
236
docs/datetime.md
@@ -25,6 +25,7 @@ import (
|
||||
- [AddDay](#AddDay)
|
||||
- [AddHour](#AddHour)
|
||||
- [AddMinute](#AddMinute)
|
||||
- [AddYear](#AddYear)
|
||||
- [BeginOfMinute](#BeginOfMinute)
|
||||
- [BeginOfHour](#BeginOfHour)
|
||||
- [BeginOfDay](#BeginOfDay)
|
||||
@@ -52,6 +53,10 @@ import (
|
||||
- [ToFormat](#ToFormat)
|
||||
- [ToFormatForTpl](#ToFormatForTpl)
|
||||
- [ToIso8601](#ToIso8601)
|
||||
- [IsLeapYear](#IsLeapYear)
|
||||
- [BetweenSeconds](#BetweenSeconds)
|
||||
- [DayOfYear](#DayOfYear)
|
||||
- [IsWeekend](#IsWeekend)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -170,6 +175,45 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="AddYear">AddYear</span>
|
||||
|
||||
<p>Add or sub year to the time.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func AddYear(t time.Time, year int64) time.Time
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
|
||||
after1Year := datetime.AddYear(now, 1)
|
||||
diff1 := after1Year.Sub(now)
|
||||
|
||||
before1Year := datetime.AddYear(now, -1)
|
||||
diff2 := before1Year.Sub(now)
|
||||
|
||||
fmt.Println(diff1)
|
||||
fmt.Println(diff2)
|
||||
|
||||
// Output:
|
||||
// 8760h0m0s
|
||||
// -8760h0m0s
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="BeginOfMinute">BeginOfMinute</span>
|
||||
|
||||
<p>Return beginning minute time of day.</p>
|
||||
@@ -921,3 +965,195 @@ func main() {
|
||||
fmt.Println(ts) //"2006-01-02T23:04:05+08:00"
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="IsLeapYear">IsLeapYear</span>
|
||||
|
||||
<p>check if param `year` is leap year or not.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsLeapYear(year int) bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := datetime.IsLeapYear(2000)
|
||||
result2 := datetime.IsLeapYear(2001)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="BetweenSeconds">BetweenSeconds</span>
|
||||
|
||||
<p>Return the number of seconds between two times.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func BetweenSeconds(t1 time.Time, t2 time.Time) int64
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
today := time.Now()
|
||||
tomorrow := AddDay(today, 1)
|
||||
yesterday := AddDay(today, -1)
|
||||
|
||||
result1 := datetime.BetweenSeconds(today, tomorrow)
|
||||
result2 := datetime.BetweenSeconds(today, yesterday)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 86400
|
||||
// -86400
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="DayOfYear">DayOfYear</span>
|
||||
|
||||
<p>Returns which day of the year the parameter date `t` is.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func DayOfYear(t time.Time) int
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
date1 := time.Date(2023, 02, 01, 1, 1, 1, 0, time.Local)
|
||||
result1 := datetime.DayOfYear(date1)
|
||||
|
||||
date2 := time.Date(2023, 01, 02, 1, 1, 1, 0, time.Local)
|
||||
result2 := datetime.DayOfYear(date2)
|
||||
|
||||
date3 := time.Date(2023, 01, 01, 1, 1, 1, 0, time.Local)
|
||||
result3 := datetime.DayOfYear(date3)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 31
|
||||
// 1
|
||||
// 0
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="IsWeekend">IsWeekend</span>
|
||||
|
||||
<p>Checks if passed time is weekend or not.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsWeekend(t time.Time) bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
date1 := time.Date(2023, 06, 03, 0, 0, 0, 0, time.Local)
|
||||
date2 := time.Date(2023, 06, 04, 0, 0, 0, 0, time.Local)
|
||||
date3 := time.Date(2023, 06, 02, 0, 0, 0, 0, time.Local)
|
||||
|
||||
result1 := datetime.IsWeekend(date1)
|
||||
result2 := datetime.IsWeekend(date2)
|
||||
result3 := datetime.IsWeekend(date3)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="IsWeekend">IsWeekend</span>
|
||||
|
||||
<p>判断日期是否是周末。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsWeekend(t time.Time) bool
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
date1 := time.Date(2023, 06, 03, 0, 0, 0, 0, time.Local)
|
||||
date2 := time.Date(2023, 06, 04, 0, 0, 0, 0, time.Local)
|
||||
date3 := time.Date(2023, 06, 02, 0, 0, 0, 0, time.Local)
|
||||
|
||||
result1 := datetime.IsWeekend(date1)
|
||||
result2 := datetime.IsWeekend(date2)
|
||||
result3 := datetime.IsWeekend(date3)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
- [AddDay](#AddDay)
|
||||
- [AddHour](#AddHour)
|
||||
- [AddMinute](#AddMinute)
|
||||
- [AddYear](#AddYear)
|
||||
- [BeginOfMinute](#BeginOfMinute)
|
||||
- [BeginOfHour](#BeginOfHour)
|
||||
- [BeginOfDay](#BeginOfDay)
|
||||
@@ -52,6 +53,11 @@ import (
|
||||
- [ToFormat](#ToFormat)
|
||||
- [ToFormatForTpl](#ToFormatForTpl)
|
||||
- [ToIso8601](#ToIso8601)
|
||||
- [IsLeapYear](#IsLeapYear)
|
||||
- [BetweenSeconds](#BetweenSeconds)
|
||||
- [DayOfYear](#DayOfYear)
|
||||
- [IsWeekend](#IsWeekend)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -170,6 +176,45 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="AddYear">AddYear</span>
|
||||
|
||||
<p>将日期加/减年数。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func AddYear(t time.Time, year int64) time.Time
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"github.com/duke-git/lancet/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
|
||||
after1Year := datetime.AddYear(now, 1)
|
||||
diff1 := after1Year.Sub(now)
|
||||
|
||||
before1Year := datetime.AddYear(now, -1)
|
||||
diff2 := before1Year.Sub(now)
|
||||
|
||||
fmt.Println(diff1)
|
||||
fmt.Println(diff2)
|
||||
|
||||
// Output:
|
||||
// 8760h0m0s
|
||||
// -8760h0m0s
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="BeginOfMinute">BeginOfMinute</span>
|
||||
|
||||
<p>返回指定时间的分钟开始时间</p>
|
||||
@@ -921,3 +966,114 @@ func main() {
|
||||
fmt.Println(ts) //"2006-01-02T23:04:05+08:00"
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="IsLeapYear">IsLeapYear</span>
|
||||
|
||||
<p>验证是否是闰年。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsLeapYear(year int) bool
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := datetime.IsLeapYear(2000)
|
||||
result2 := datetime.IsLeapYear(2001)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="BetweenSeconds">BetweenSeconds</span>
|
||||
|
||||
<p>返回两个时间的间隔秒数。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func BetweenSeconds(t1 time.Time, t2 time.Time) int64
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
today := time.Now()
|
||||
tomorrow := AddDay(today, 1)
|
||||
yesterday := AddDay(today, -1)
|
||||
|
||||
result1 := datetime.BetweenSeconds(today, tomorrow)
|
||||
result2 := datetime.BetweenSeconds(today, yesterday)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// 86400
|
||||
// -86400
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="DayOfYear">DayOfYear</span>
|
||||
|
||||
<p>返回参数日期是一年中的第几天。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func DayOfYear(t time.Time) int
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/datetime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
date1 := time.Date(2023, 02, 01, 1, 1, 1, 0, time.Local)
|
||||
result1 := datetime.DayOfYear(date1)
|
||||
|
||||
date2 := time.Date(2023, 01, 02, 1, 1, 1, 0, time.Local)
|
||||
result2 := datetime.DayOfYear(date2)
|
||||
|
||||
date3 := time.Date(2023, 01, 01, 1, 1, 1, 0, time.Local)
|
||||
result3 := datetime.DayOfYear(date3)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 31
|
||||
// 1
|
||||
// 0
|
||||
}
|
||||
```
|
||||
|
||||
268
docs/fileutil.md
268
docs/fileutil.md
@@ -38,6 +38,13 @@ import (
|
||||
- [Zip](#Zip)
|
||||
- [UnZip](#UnZip)
|
||||
- [CurrentPath](#CurrentPath)
|
||||
- [IsZipFile](#IsZipFile)
|
||||
- [FileSize](#FileSize)
|
||||
- [MTime](#MTime)
|
||||
- [Sha](#Sha)
|
||||
- [ReadCsvFile](#ReadCsvFile)
|
||||
- [WriteStringToFile](#WriteStringToFile)
|
||||
- [WriteBytesToFile](#WriteBytesToFile)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -494,4 +501,265 @@ func main() {
|
||||
absPath := CurrentPath()
|
||||
fmt.Println(absPath)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="IsZipFile">IsZipFile</span>
|
||||
|
||||
<p>Checks if file is zip file or not.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func IsZipFile(filepath string) bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isZip := IsZipFile("./zipfile.zip")
|
||||
fmt.Println(isZip)
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="FileSize">FileSize</span>
|
||||
|
||||
<p>Returns file size in bytes.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func FileSize(path string) (int64, error)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
size, err := fileutil.FileSize("./testdata/test.txt")
|
||||
|
||||
fmt.Println(size)
|
||||
fmt.Println(err)
|
||||
|
||||
// Output:
|
||||
// 20
|
||||
// <nil>
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="MTime">MTime</span>
|
||||
|
||||
<p>Returns file modified time(unix timestamp).</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func MTime(filepath string) (int64, error)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
mtime, err := fileutil.MTime("./testdata/test.txt")
|
||||
|
||||
fmt.Println(mtime)
|
||||
fmt.Println(err)
|
||||
|
||||
// Output:
|
||||
// 1682391110
|
||||
// <nil>
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="Sha">Sha</span>
|
||||
|
||||
<p>returns file sha value, param `shaType` should be 1, 256 or 512.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Sha(filepath string, shaType ...int) (string, error)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
sha1, err := fileutil.Sha("./testdata/test.txt", 1)
|
||||
sha256, _ := fileutil.Sha("./testdata/test.txt", 256)
|
||||
sha512, _ := fileutil.Sha("./testdata/test.txt", 512)
|
||||
|
||||
fmt.Println(sha1)
|
||||
fmt.Println(sha256)
|
||||
fmt.Println(sha512)
|
||||
fmt.Println(err)
|
||||
|
||||
// Output:
|
||||
// dda3cf10c5a6ff6c6659a497bf7261b287af2bc7
|
||||
// aa6d0a3fbc3442c228d606da09e0c1dc98c69a1cac3da1909199e0266171df35
|
||||
// d22aba2a1b7a2e2f512756255cc1c3708905646920cb1eb95e45b531ba74774dbbb89baebf1f716220eb9cf4908f1cfc5b2a01267704d9a59f59d77cab609870
|
||||
// <nil>
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="ReadCsvFile">ReadCsvFile</span>
|
||||
|
||||
<p>Reads file content into slice.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ReadCsvFile(filepath string) ([][]string, error)
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
content, err := fileutil.ReadCsvFile("./testdata/test.csv")
|
||||
|
||||
fmt.Println(content)
|
||||
fmt.Println(err)
|
||||
|
||||
// Output:
|
||||
// [[Bob 12 male] [Duke 14 male] [Lucy 16 female]]
|
||||
// <nil>
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="WriteBytesToFile">WriteBytesToFile</span>
|
||||
|
||||
<p>Writes bytes to target file.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func WriteBytesToFile(filepath string, content []byte) error
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
filepath := "./bytes.txt"
|
||||
|
||||
file, err := os.Create(filepath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
err = fileutil.WriteBytesToFile(filepath, []byte("hello"))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
content, err := fileutil.ReadFileToString(filepath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
os.Remove(filepath)
|
||||
|
||||
fmt.Println(content)
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="WriteStringToFile">WriteStringToFile</span>
|
||||
|
||||
<p>Writes string to target file.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func WriteStringToFile(filepath string, content string, append bool) error
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
filepath := "./test.txt"
|
||||
|
||||
file, err := os.Create(filepath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
err = fileutil.WriteStringToFile(filepath, "hello", true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
content, err := fileutil.ReadFileToString(filepath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
os.Remove(filepath)
|
||||
|
||||
fmt.Println(content)
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
@@ -38,6 +38,13 @@ import (
|
||||
- [Zip](#Zip)
|
||||
- [UnZip](#UnZip)
|
||||
- [CurrentPath](#CurrentPath)
|
||||
- [IsZipFile](#IsZipFile)
|
||||
- [FileSize](#FileSize)
|
||||
- [MTime](#MTime)
|
||||
- [Sha](#Sha)
|
||||
- [ReadCsvFile](#ReadCsvFile)
|
||||
- [WriteStringToFile](#WriteStringToFile)
|
||||
- [WriteBytesToFile](#WriteBytesToFile)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -446,7 +453,7 @@ func main() {
|
||||
|
||||
<p>zip解压缩文件并保存在目录中</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func UnZip(zipFile string, destPath string) error
|
||||
@@ -495,3 +502,263 @@ func main() {
|
||||
fmt.Println(absPath)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="IsZipFile">IsZipFile</span>
|
||||
|
||||
<p>判断文件是否是zip压缩文件。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func IsZipFile(filepath string) bool
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isZip := IsZipFile("./zipfile.zip")
|
||||
fmt.Println(isZip)
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="FileSize">FileSize</span>
|
||||
|
||||
<p>返回文件字节大小。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func FileSize(path string) (int64, error)
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
size, err := fileutil.FileSize("./testdata/test.txt")
|
||||
|
||||
fmt.Println(size)
|
||||
fmt.Println(err)
|
||||
|
||||
// Output:
|
||||
// 20
|
||||
// <nil>
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="MTime">MTime</span>
|
||||
|
||||
<p>返回文件修改时间(unix timestamp).</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func MTime(filepath string) (int64, error)
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
mtime, err := fileutil.MTime("./testdata/test.txt")
|
||||
|
||||
fmt.Println(mtime)
|
||||
fmt.Println(err)
|
||||
|
||||
// Output:
|
||||
// 1682391110
|
||||
// <nil>
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="Sha">Sha</span>
|
||||
|
||||
<p>返回文件sha值,参数`shaType` 应传值为: 1, 256,512.</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Sha(filepath string, shaType ...int) (string, error)
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
sha1, err := fileutil.Sha("./testdata/test.txt", 1)
|
||||
sha256, _ := fileutil.Sha("./testdata/test.txt", 256)
|
||||
sha512, _ := fileutil.Sha("./testdata/test.txt", 512)
|
||||
|
||||
fmt.Println(sha1)
|
||||
fmt.Println(sha256)
|
||||
fmt.Println(sha512)
|
||||
fmt.Println(err)
|
||||
|
||||
// Output:
|
||||
// dda3cf10c5a6ff6c6659a497bf7261b287af2bc7
|
||||
// aa6d0a3fbc3442c228d606da09e0c1dc98c69a1cac3da1909199e0266171df35
|
||||
// d22aba2a1b7a2e2f512756255cc1c3708905646920cb1eb95e45b531ba74774dbbb89baebf1f716220eb9cf4908f1cfc5b2a01267704d9a59f59d77cab609870
|
||||
// <nil>
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="ReadCsvFile">ReadCsvFile</span>
|
||||
|
||||
<p>读取csv文件内容到切片</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ReadCsvFile(filepath string) ([][]string, error)
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
content, err := fileutil.ReadCsvFile("./testdata/test.csv")
|
||||
|
||||
fmt.Println(content)
|
||||
fmt.Println(err)
|
||||
|
||||
// Output:
|
||||
// [[Bob 12 male] [Duke 14 male] [Lucy 16 female]]
|
||||
// <nil>
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="WriteBytesToFile">WriteBytesToFile</span>
|
||||
|
||||
<p>将bytes写入文件。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func WriteBytesToFile(filepath string, content []byte) error
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
filepath := "./bytes.txt"
|
||||
|
||||
file, err := os.Create(filepath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
err = fileutil.WriteBytesToFile(filepath, []byte("hello"))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
content, err := fileutil.ReadFileToString(filepath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
os.Remove(filepath)
|
||||
|
||||
fmt.Println(content)
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="WriteStringToFile">WriteStringToFile</span>
|
||||
|
||||
<p>将字符串写入文件。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func WriteStringToFile(filepath string, content string, append bool) error
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
filepath := "./test.txt"
|
||||
|
||||
file, err := os.Create(filepath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
err = fileutil.WriteStringToFile(filepath, "hello", true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
content, err := fileutil.ReadFileToString(filepath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
os.Remove(filepath)
|
||||
|
||||
fmt.Println(content)
|
||||
|
||||
// Output:
|
||||
// hello
|
||||
}
|
||||
```
|
||||
|
||||
168
docs/mathutil.md
168
docs/mathutil.md
@@ -33,6 +33,10 @@ import (
|
||||
- [RadianToAngle](#RadianToAngle)
|
||||
- [PointDistance](#PointDistance)
|
||||
- [IsPrime](#IsPrime)
|
||||
- [GCD](#GCD)
|
||||
- [LCM](#LCM)
|
||||
- [Cos](#Cos)
|
||||
- [Sin](#Sin)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -375,3 +379,167 @@ func main() {
|
||||
// true
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="GCD">GCD</span>
|
||||
|
||||
<p>Return greatest common divisor (GCD) of integers.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func GCD(integers ...int) int
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := mathutil.GCD(1, 1)
|
||||
result2 := mathutil.GCD(1, -1)
|
||||
result3 := mathutil.GCD(-1, 1)
|
||||
result4 := mathutil.GCD(-1, -1)
|
||||
result5 := mathutil.GCD(3, 6, 9)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 1
|
||||
// -1
|
||||
// -1
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="LCM">LCM</span>
|
||||
|
||||
<p>Return Least Common Multiple (LCM) of integers.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func LCM(integers ...int) int
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := mathutil.LCM(1, 1)
|
||||
result2 := mathutil.LCM(1, 2)
|
||||
result3 := mathutil.LCM(3, 6, 9)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 18
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="Cos">Cos</span>
|
||||
|
||||
<p>Returns the cosine of the radian argument.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Cos(radian float64, precision ...int) float64
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := mathutil.Cos(0)
|
||||
result2 := mathutil.Cos(90)
|
||||
result3 := mathutil.Cos(180)
|
||||
result4 := mathutil.Cos(math.Pi)
|
||||
result5 := mathutil.Cos(math.Pi / 2)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// -0.447
|
||||
// -0.598
|
||||
// -1
|
||||
// 0
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="Sin">Sin</span>
|
||||
|
||||
<p>Returns the sine of the radian argument.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Sin(radian float64, precision ...int) float64
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := mathutil.Sin(0)
|
||||
result2 := mathutil.Sin(90)
|
||||
result3 := mathutil.Sin(180)
|
||||
result4 := mathutil.Sin(math.Pi)
|
||||
result5 := mathutil.Sin(math.Pi / 2)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
|
||||
// Output:
|
||||
// 0
|
||||
// 0.894
|
||||
// -0.801
|
||||
// 0
|
||||
// 1
|
||||
}
|
||||
```
|
||||
@@ -33,6 +33,10 @@ import (
|
||||
- [RadianToAngle](#RadianToAngle)
|
||||
- [PointDistance](#PointDistance)
|
||||
- [IsPrime](#IsPrime)
|
||||
- [GCD](#GCD)
|
||||
- [LCM](#LCM)
|
||||
- [Cos](#Cos)
|
||||
- [Sin](#Sin)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -375,3 +379,168 @@ func main() {
|
||||
// true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="GCD">GCD</span>
|
||||
|
||||
<p>计算整数最大公约数。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func GCD(integers ...int) int
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := mathutil.GCD(1, 1)
|
||||
result2 := mathutil.GCD(1, -1)
|
||||
result3 := mathutil.GCD(-1, 1)
|
||||
result4 := mathutil.GCD(-1, -1)
|
||||
result5 := mathutil.GCD(3, 6, 9)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 1
|
||||
// -1
|
||||
// -1
|
||||
// 3
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="LCM">LCM</span>
|
||||
|
||||
<p>计算整数最小公倍数。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func LCM(integers ...int) int
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := mathutil.LCM(1, 1)
|
||||
result2 := mathutil.LCM(1, 2)
|
||||
result3 := mathutil.LCM(3, 6, 9)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// 2
|
||||
// 18
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="Cos">Cos</span>
|
||||
|
||||
<p>计算弧度的余弦值。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Cos(radian float64, precision ...int) float64
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := mathutil.Cos(0)
|
||||
result2 := mathutil.Cos(90)
|
||||
result3 := mathutil.Cos(180)
|
||||
result4 := mathutil.Cos(math.Pi)
|
||||
result5 := mathutil.Cos(math.Pi / 2)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
// -0.447
|
||||
// -0.598
|
||||
// -1
|
||||
// 0
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="Sin">Sin</span>
|
||||
|
||||
<p>计算弧度的正弦值。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Sin(radian float64, precision ...int) float64
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/mathutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := mathutil.Sin(0)
|
||||
result2 := mathutil.Sin(90)
|
||||
result3 := mathutil.Sin(180)
|
||||
result4 := mathutil.Sin(math.Pi)
|
||||
result5 := mathutil.Sin(math.Pi / 2)
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
fmt.Println(result5)
|
||||
|
||||
// Output:
|
||||
// 0
|
||||
// 0.894
|
||||
// -0.801
|
||||
// 0
|
||||
// 1
|
||||
}
|
||||
```
|
||||
@@ -586,9 +586,9 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="HttpGet">HttpGet (Deprecated: use SendRequest for replacement)</span>
|
||||
### <span id="HttpGet">HttpGet</span>
|
||||
|
||||
<p>Send http get request.</p>
|
||||
<p>Send http get request. (Deprecated: use SendRequest for replacement)</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
@@ -628,9 +628,9 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="HttpPost">HttpPost (Deprecated: use SendRequest for replacement)</span>
|
||||
### <span id="HttpPost">HttpPost</span>
|
||||
|
||||
<p>Send http post request.</p>
|
||||
<p>Send http post request. (Deprecated: use SendRequest for replacement)</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
@@ -658,28 +658,30 @@ import (
|
||||
func main() {
|
||||
url := "https://jsonplaceholder.typicode.com/todos"
|
||||
header := map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
type Todo struct {
|
||||
UserId int `json:"userId"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
todo := Todo{1, "TestAddToDo"}
|
||||
bodyParams, _ := json.Marshal(todo)
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
// "Content-Type": "multipart/form-data",
|
||||
}
|
||||
|
||||
resp, err := netutil.HttpPost(url, header, nil, bodyParams)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
postData := url.Values{}
|
||||
postData.Add("userId", "1")
|
||||
postData.Add("title", "TestToDo")
|
||||
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
fmt.Println(body)
|
||||
// postData := make(map[string]string)
|
||||
// postData["userId"] = "1"
|
||||
// postData["title"] = "title"
|
||||
|
||||
resp, err := netutil.HttpPost(apiUrl, header, nil, postData)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
t.Log("response: ", resp.StatusCode, string(body))
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="HttpPut">HttpPut (Deprecated: use SendRequest for replacement)</span>
|
||||
### <span id="HttpPut">HttpPut</span>
|
||||
|
||||
<p>Send http put request.</p>
|
||||
<p>Send http put request. (Deprecated: use SendRequest for replacement)</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
@@ -727,9 +729,9 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="HttpDelete">HttpDelete (Deprecated: use SendRequest for replacement)</span>
|
||||
### <span id="HttpDelete">HttpDelete</span>
|
||||
|
||||
<p>Send http delete request.</p>
|
||||
<p>Send http delete request. (Deprecated: use SendRequest for replacement)</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
@@ -766,9 +768,9 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="HttpPatch">HttpPatch (Deprecated: use SendRequest for replacement)</span>
|
||||
### <span id="HttpPatch">HttpPatch</span>
|
||||
|
||||
<p>Send http patch request.</p>
|
||||
<p>Send http patch request. (Deprecated: use SendRequest for replacement)</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
@@ -916,9 +918,8 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
ok, err := netutil.DownloadFile("./", "http://www.xxx.com/a.jpg")
|
||||
err := DownloadFile("./lancet_logo.jpg", "https://picx.zhimg.com/v2-fc82a4199749de9cfb71e32e54f489d3_720w.jpg?source=172ae18b")
|
||||
|
||||
fmt.Println(ok)
|
||||
fmt.Println(err)
|
||||
}
|
||||
```
|
||||
@@ -939,10 +940,7 @@ func IsPingConnected(host string) bool
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/netutil"
|
||||
)
|
||||
|
||||
@@ -975,10 +973,7 @@ func IsTelnetConnected(host string, port string) bool
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/netutil"
|
||||
)
|
||||
|
||||
|
||||
@@ -585,9 +585,9 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="HttpGet">HttpGet (Deprecated: use SendRequest for replacement)</span>
|
||||
### <span id="HttpGet">HttpGet</span>
|
||||
|
||||
<p>发送http get请求</p>
|
||||
<p>发送http get请求。(已废弃: 使用SendRequest)</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
@@ -627,9 +627,9 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="HttpPost">HttpPost (Deprecated: use SendRequest for replacement)</span>
|
||||
### <span id="HttpPost">HttpPost</span>
|
||||
|
||||
<p>发送http post请求</p>
|
||||
<p>发送http post请求。(已废弃: 使用SendRequest)</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
@@ -657,28 +657,30 @@ import (
|
||||
func main() {
|
||||
url := "https://jsonplaceholder.typicode.com/todos"
|
||||
header := map[string]string{
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
type Todo struct {
|
||||
UserId int `json:"userId"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
todo := Todo{1, "TestAddToDo"}
|
||||
bodyParams, _ := json.Marshal(todo)
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
// "Content-Type": "multipart/form-data",
|
||||
}
|
||||
|
||||
resp, err := netutil.HttpPost(url, header, nil, bodyParams)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
postData := url.Values{}
|
||||
postData.Add("userId", "1")
|
||||
postData.Add("title", "TestToDo")
|
||||
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
// postData := make(map[string]string)
|
||||
// postData["userId"] = "1"
|
||||
// postData["title"] = "title"
|
||||
|
||||
resp, err := netutil.HttpPost(apiUrl, header, nil, postData)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
fmt.Println(body)
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="HttpPut">HttpPut (Deprecated: use SendRequest for replacement)</span>
|
||||
### <span id="HttpPut">HttpPut</span>
|
||||
|
||||
<p>发送http put请求</p>
|
||||
<p>发送http put请求。(已废弃: 使用SendRequest)</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
@@ -726,9 +728,9 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="HttpDelete">HttpDelete (Deprecated: use SendRequest for replacement)</span>
|
||||
### <span id="HttpDelete">HttpDelete</span>
|
||||
|
||||
<p>发送http delete请求</p>
|
||||
<p>发送http delete请求。(已废弃: 使用SendRequest)</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
@@ -765,9 +767,9 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="HttpPatch">HttpPatch (Deprecated: use SendRequest for replacement)</span>
|
||||
### <span id="HttpPatch">HttpPatch</span>
|
||||
|
||||
<p>发送http patch请求</p>
|
||||
<p>发送http patch请求。(已废弃: 使用SendRequest)</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
@@ -915,9 +917,8 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
ok, err := netutil.DownloadFile("./", "http://www.xxx.com/a.jpg")
|
||||
err := DownloadFile("./lancet_logo.jpg", "https://picx.zhimg.com/v2-fc82a4199749de9cfb71e32e54f489d3_720w.jpg?source=172ae18b")
|
||||
|
||||
fmt.Println(ok)
|
||||
fmt.Println(err)
|
||||
}
|
||||
```
|
||||
@@ -938,10 +939,7 @@ func IsPingConnected(host string) bool
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/netutil"
|
||||
)
|
||||
|
||||
@@ -974,10 +972,7 @@ func IsTelnetConnected(host string, port string) bool
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"github.com/duke-git/lancet/netutil"
|
||||
)
|
||||
|
||||
|
||||
220
docs/strutil.md
220
docs/strutil.md
@@ -28,6 +28,8 @@ import (
|
||||
- [BeforeLast](#BeforeLast)
|
||||
- [CamelCase](#CamelCase)
|
||||
- [Capitalize](#Capitalize)
|
||||
- [ContainsAll](#ContainsAll)
|
||||
- [ContainsAny](#ContainsAny)
|
||||
- [IsString](#IsString)
|
||||
- [KebabCase](#KebabCase)
|
||||
- [UpperKebabCase](#UpperKebabCase)
|
||||
@@ -51,6 +53,10 @@ import (
|
||||
- [HasPrefixAny](#HasPrefixAny)
|
||||
- [HasSuffixAny](#HasSuffixAny)
|
||||
- [IndexOffset](#IndexOffset)
|
||||
- [ReplaceWithMap](#ReplaceWithMap)
|
||||
- [Trim](#Trim)
|
||||
- [SplitAndTrim](#SplitAndTrim)
|
||||
- [HideString](#HideString)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -1021,4 +1027,216 @@ func main() {
|
||||
// -1
|
||||
// -1
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
### <span id="ReplaceWithMap">ReplaceWithMap</span>
|
||||
|
||||
<p>Returns a copy of `str`, which is replaced by a map in unordered way, case-sensitively.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ReplaceWithMap(str string, replaces map[string]string) string
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
str := "ac ab ab ac"
|
||||
replaces := map[string]string{
|
||||
"a": "1",
|
||||
"b": "2",
|
||||
}
|
||||
|
||||
result := strutil.ReplaceWithMap(str, replaces)
|
||||
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// 1c 12 12 1c
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="Trim">Trim</span>
|
||||
|
||||
<p>Strips whitespace (or other characters) from the beginning and end of a string. The optional parameter `characterMask` specifies the additional stripped characters.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func Trim(str string, characterMask ...string) string
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := strutil.Trim("\nabcd")
|
||||
|
||||
str := "$ ab cd $ "
|
||||
|
||||
result2 := strutil.Trim(str)
|
||||
result3 := strutil.Trim(str, "$")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// abcd
|
||||
// $ ab cd $
|
||||
// ab cd
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="SplitAndTrim">SplitAndTrim</span>
|
||||
|
||||
<p>Splits string `str` by a string `delimiter` to a slice, and calls Trim to every element of slice. It ignores the elements which are empty after Trim.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func SplitAndTrim(str, delimiter string, characterMask ...string) []string
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
str := " a,b, c,d,$1 "
|
||||
|
||||
result1 := strutil.SplitAndTrim(str, ",")
|
||||
result2 := strutil.SplitAndTrim(str, ",", "$")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// [a b c d $1]
|
||||
// [a b c d 1]
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="HideString">HideString</span>
|
||||
|
||||
<p>HideString hide some chars in source string with param `replaceChar`. replace range is origin[start : end]. [start, end).</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func HideString(origin string, start, end int, replaceChar string) string
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
str := "13242658976"
|
||||
|
||||
result1 := strutil.HideString(str, 3, 3, "*")
|
||||
result2 := strutil.HideString(str, 3, 4, "*")
|
||||
result3 := strutil.HideString(str, 3, 7, "*")
|
||||
result4 := strutil.HideString(str, 7, 11, "*")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
|
||||
// Output:
|
||||
// 13242658976
|
||||
// 132*2658976
|
||||
// 132****8976
|
||||
// 1324265****
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="ContainsAll">ContainsAll</span>
|
||||
|
||||
<p>Return true if target string contains all the substrings.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ContainsAll(str string, substrs []string) bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
str := "hello world"
|
||||
|
||||
result1 := strutil.ContainsAll(str, []string{"hello", "world"})
|
||||
result2 := strutil.ContainsAll(str, []string{"hello", "abc"})
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="ContainsAny">ContainsAny</span>
|
||||
|
||||
<p>Return true if target string contains any one of the substrings.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func ContainsAny(str string, substrs []string) bool
|
||||
```
|
||||
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
str := "hello world"
|
||||
|
||||
result1 := strutil.ContainsAny(str, []string{"hello", "world"})
|
||||
result2 := strutil.ContainsAny(str, []string{"hello", "abc"})
|
||||
result3 := strutil.ContainsAny(str, []string{"123", "abc"})
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
@@ -27,6 +27,8 @@ import (
|
||||
- [Before](#Before)
|
||||
- [BeforeLast](#BeforeLast)
|
||||
- [CamelCase](#CamelCase)
|
||||
- [ContainsAll](#ContainsAll)
|
||||
- [ContainsAny](#ContainsAny)
|
||||
- [Capitalize](#Capitalize)
|
||||
- [IsString](#IsString)
|
||||
- [KebabCase](#KebabCase)
|
||||
@@ -51,6 +53,10 @@ import (
|
||||
- [HasPrefixAny](#HasPrefixAny)
|
||||
- [HasSuffixAny](#HasSuffixAny)
|
||||
- [IndexOffset](#IndexOffset)
|
||||
- [ReplaceWithMap](#ReplaceWithMap)
|
||||
- [Trim](#Trim)
|
||||
- [SplitAndTrim](#SplitAndTrim)
|
||||
- [HideString](#HideString)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -832,7 +838,6 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="RemoveNonPrintable">RemoveNonPrintable</span>
|
||||
|
||||
<p>删除字符串中不可打印的字符。</p>
|
||||
@@ -1053,4 +1058,217 @@ func main() {
|
||||
// -1
|
||||
// -1
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
### <span id="ReplaceWithMap">ReplaceWithMap</span>
|
||||
|
||||
<p>返回`str`的副本,以无序的方式被map替换,区分大小写。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ReplaceWithMap(str string, replaces map[string]string) string
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
str := "ac ab ab ac"
|
||||
replaces := map[string]string{
|
||||
"a": "1",
|
||||
"b": "2",
|
||||
}
|
||||
|
||||
result := strutil.ReplaceWithMap(str, replaces)
|
||||
|
||||
fmt.Println(result)
|
||||
// Output:
|
||||
// 1c 12 12 1c
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="Trim">Trim</span>
|
||||
|
||||
<p>从字符串的开头和结尾去除空格(或其他字符)。 可选参数 characterMask 指定额外的剥离字符。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func Trim(str string, characterMask ...string) string
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
result1 := strutil.Trim("\nabcd")
|
||||
|
||||
str := "$ ab cd $ "
|
||||
|
||||
result2 := strutil.Trim(str)
|
||||
result3 := strutil.Trim(str, "$")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// abcd
|
||||
// $ ab cd $
|
||||
// ab cd
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="SplitAndTrim">SplitAndTrim</span>
|
||||
|
||||
<p>将字符串str按字符串delimiter拆分为一个切片,并对该数组的每个元素调用Trim。忽略Trim后为空的元素。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func SplitAndTrim(str, delimiter string, characterMask ...string) []string
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
str := " a,b, c,d,$1 "
|
||||
|
||||
result1 := strutil.SplitAndTrim(str, ",")
|
||||
result2 := strutil.SplitAndTrim(str, ",", "$")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// [a b c d $1]
|
||||
// [a b c d 1]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="HideString">HideString</span>
|
||||
|
||||
<p>使用参数`replaceChar`隐藏源字符串中的一些字符。替换范围是 origin[start : end]。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func HideString(origin string, start, end int, replaceChar string) string
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
str := "13242658976"
|
||||
|
||||
result1 := strutil.HideString(str, 3, 3, "*")
|
||||
result2 := strutil.HideString(str, 3, 4, "*")
|
||||
result3 := strutil.HideString(str, 3, 7, "*")
|
||||
result4 := strutil.HideString(str, 7, 11, "*")
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
fmt.Println(result4)
|
||||
|
||||
// Output:
|
||||
// 13242658976
|
||||
// 132*2658976
|
||||
// 132****8976
|
||||
// 1324265****
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="ContainsAll">ContainsAll</span>
|
||||
|
||||
<p>判断字符串是否包括全部给定的子字符串切片。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ContainsAll(str string, substrs []string) bool
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
str := "hello world"
|
||||
|
||||
result1 := strutil.ContainsAll(str, []string{"hello", "world"})
|
||||
result2 := strutil.ContainsAll(str, []string{"hello", "abc"})
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="ContainsAny">ContainsAny</span>
|
||||
|
||||
<p>判断字符串是否包括给定的子字符串切片中任意一个子字符串。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func ContainsAny(str string, substrs []string) bool
|
||||
```
|
||||
|
||||
<b>示例:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/strutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
str := "hello world"
|
||||
|
||||
result1 := strutil.ContainsAny(str, []string{"hello", "world"})
|
||||
result2 := strutil.ContainsAny(str, []string{"hello", "abc"})
|
||||
result3 := strutil.ContainsAny(str, []string{"123", "abc"})
|
||||
|
||||
fmt.Println(result1)
|
||||
fmt.Println(result2)
|
||||
fmt.Println(result3)
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
}
|
||||
```
|
||||
|
||||
119
fileutil/file.go
119
fileutil/file.go
@@ -7,6 +7,11 @@ package fileutil
|
||||
import (
|
||||
"archive/zip"
|
||||
"bufio"
|
||||
"bytes"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"encoding/csv"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -330,3 +335,117 @@ func CurrentPath() string {
|
||||
|
||||
return absPath
|
||||
}
|
||||
|
||||
// IsZipFile checks if file is zip or not.
|
||||
func IsZipFile(filepath string) bool {
|
||||
f, err := os.Open(filepath)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
buf := make([]byte, 4)
|
||||
if n, err := f.Read(buf); err != nil || n < 4 {
|
||||
return false
|
||||
}
|
||||
|
||||
return bytes.Equal(buf, []byte("PK\x03\x04"))
|
||||
}
|
||||
|
||||
// FileSize returns file size in bytes.
|
||||
func FileSize(path string) (int64, error) {
|
||||
f, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return f.Size(), nil
|
||||
}
|
||||
|
||||
// MTime returns file modified time.
|
||||
func MTime(filepath string) (int64, error) {
|
||||
f, err := os.Stat(filepath)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return f.ModTime().Unix(), nil
|
||||
}
|
||||
|
||||
// MTime returns file sha value, param `shaType` should be 1, 256 or 512.
|
||||
func Sha(filepath string, shaType ...int) (string, error) {
|
||||
file, err := os.Open(filepath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
h := sha1.New()
|
||||
if len(shaType) > 0 {
|
||||
if shaType[0] == 1 {
|
||||
h = sha1.New()
|
||||
} else if shaType[0] == 256 {
|
||||
h = sha256.New()
|
||||
} else if shaType[0] == 512 {
|
||||
h = sha512.New()
|
||||
} else {
|
||||
return "", errors.New("param `shaType` should be 1, 256 or 512.")
|
||||
}
|
||||
}
|
||||
|
||||
_, err = io.Copy(h, file)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
sha := fmt.Sprintf("%x", h.Sum(nil))
|
||||
|
||||
return sha, nil
|
||||
|
||||
}
|
||||
|
||||
// ReadCsvFile read file content into slice.
|
||||
func ReadCsvFile(filepath string) ([][]string, error) {
|
||||
f, err := os.Open(filepath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
csvReader := csv.NewReader(f)
|
||||
records, err := csvReader.ReadAll()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return records, nil
|
||||
}
|
||||
|
||||
// WriteStringToFile write string to target file.
|
||||
func WriteStringToFile(filepath string, content string, append bool) error {
|
||||
flag := os.O_RDWR | os.O_CREATE
|
||||
if append {
|
||||
flag = flag | os.O_APPEND
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(filepath, flag, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = f.WriteString(content)
|
||||
return err
|
||||
}
|
||||
|
||||
// WriteBytesToFile write bytes to target file.
|
||||
func WriteBytesToFile(filepath string, content []byte) error {
|
||||
f, err := os.OpenFile(filepath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
_, err = f.Write(content)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -226,3 +226,119 @@ func TestCurrentPath(t *testing.T) {
|
||||
absPath := CurrentPath()
|
||||
t.Log(absPath)
|
||||
}
|
||||
|
||||
func TestIsZipFile(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestIsZipFile")
|
||||
|
||||
assert.Equal(false, IsZipFile("./file.go"))
|
||||
assert.Equal(true, IsZipFile("./testdata/file.go.zip"))
|
||||
}
|
||||
|
||||
func TestFileSize(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestFileSize")
|
||||
|
||||
size, err := FileSize("./testdata/test.txt")
|
||||
|
||||
assert.IsNil(err)
|
||||
assert.Equal(int64(20), size)
|
||||
}
|
||||
|
||||
func TestMTime(t *testing.T) {
|
||||
// assert := internal.NewAssert(t, "TestMTime")
|
||||
|
||||
// mtime, err := MTime("./testdata/test.txt")
|
||||
|
||||
// assert.IsNil(err)
|
||||
// assert.Equal(int64(1682478195), mtime)
|
||||
}
|
||||
|
||||
func TestSha(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSha")
|
||||
|
||||
sha1, err := Sha("./testdata/test.txt", 1)
|
||||
sha256, err := Sha("./testdata/test.txt", 256)
|
||||
sha512, err := Sha("./testdata/test.txt", 512)
|
||||
|
||||
assert.IsNil(err)
|
||||
assert.Equal("dda3cf10c5a6ff6c6659a497bf7261b287af2bc7", sha1)
|
||||
assert.Equal("aa6d0a3fbc3442c228d606da09e0c1dc98c69a1cac3da1909199e0266171df35", sha256)
|
||||
assert.Equal("d22aba2a1b7a2e2f512756255cc1c3708905646920cb1eb95e45b531ba74774dbbb89baebf1f716220eb9cf4908f1cfc5b2a01267704d9a59f59d77cab609870", sha512)
|
||||
}
|
||||
|
||||
func TestReadCsvFile(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestReadCsvFile")
|
||||
|
||||
content, err := ReadCsvFile("./testdata/test.csv")
|
||||
t.Log(content)
|
||||
|
||||
assert.IsNil(err)
|
||||
|
||||
assert.Equal(3, len(content))
|
||||
assert.Equal(3, len(content[0]))
|
||||
assert.Equal("Bob", content[0][0])
|
||||
}
|
||||
|
||||
func TestWriteStringToFile(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestWriteStringToFile")
|
||||
|
||||
filepath := "./test.txt"
|
||||
|
||||
file, err := os.Create(filepath)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
err = WriteStringToFile(filepath, "hello", false)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
content1, err := ReadFileToString(filepath)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
err = WriteStringToFile(filepath, " world", true)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
content2, err := os.ReadFile(filepath)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
assert.Equal("hello", content1)
|
||||
assert.Equal("hello world", string(content2))
|
||||
|
||||
os.Remove(filepath)
|
||||
}
|
||||
|
||||
func TestWriteBytesToFile(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestWriteBytesToFile")
|
||||
|
||||
filepath := "./bytes.txt"
|
||||
|
||||
file, err := os.Create(filepath)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
err = WriteBytesToFile(filepath, []byte("hello"))
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
content, err := os.ReadFile(filepath)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
assert.Equal("hello", string(content))
|
||||
|
||||
os.Remove(filepath)
|
||||
}
|
||||
|
||||
BIN
fileutil/testdata/file.go.zip
vendored
Normal file
BIN
fileutil/testdata/file.go.zip
vendored
Normal file
Binary file not shown.
3
fileutil/testdata/test.csv
vendored
Normal file
3
fileutil/testdata/test.csv
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
Bob, 12, male
|
||||
Duke, 14, male
|
||||
Lucy, 16, female
|
||||
|
1
fileutil/testdata/test.txt
vendored
Normal file
1
fileutil/testdata/test.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
this is a test file.
|
||||
@@ -5,6 +5,7 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"runtime"
|
||||
@@ -36,6 +37,52 @@ func (a *Assert) Equal(expected, actual interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// EqualValues asserts that two objects are equal or convertable to the same types and equal.
|
||||
// https://github.com/stretchr/testify/assert/assertions.go
|
||||
func (a *Assert) EqualValues(expected, actual interface{}) {
|
||||
if !objectsAreEqualValues(expected, actual) {
|
||||
makeTestFailed(a.T, a.CaseName, expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func objectsAreEqualValues(expected, actual interface{}) bool {
|
||||
if objectsAreEqual(expected, actual) {
|
||||
return true
|
||||
}
|
||||
|
||||
actualType := reflect.TypeOf(actual)
|
||||
if actualType == nil {
|
||||
return false
|
||||
}
|
||||
expectedValue := reflect.ValueOf(expected)
|
||||
if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) {
|
||||
// Attempt comparison after type conversion
|
||||
return reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), actual)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func objectsAreEqual(expected, actual interface{}) bool {
|
||||
if expected == nil || actual == nil {
|
||||
return expected == actual
|
||||
}
|
||||
|
||||
exp, ok := expected.([]byte)
|
||||
if !ok {
|
||||
return reflect.DeepEqual(expected, actual)
|
||||
}
|
||||
|
||||
act, ok := actual.([]byte)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if exp == nil || act == nil {
|
||||
return exp == nil && act == nil
|
||||
}
|
||||
return bytes.Equal(exp, act)
|
||||
}
|
||||
|
||||
// NotEqual check if expected is not equal with actual
|
||||
func (a *Assert) NotEqual(expected, actual interface{}) {
|
||||
if compare(expected, actual) == compareEqual {
|
||||
|
||||
@@ -126,3 +126,66 @@ func IsPrime(n int) bool {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// GCD return greatest common divisor (GCD) of integers.
|
||||
func GCD(integers ...int) int {
|
||||
result := integers[0]
|
||||
|
||||
for k := range integers {
|
||||
result = gcd(integers[k], result)
|
||||
|
||||
if result == 1 {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// find greatest common divisor (GCD)
|
||||
func gcd(a, b int) int {
|
||||
if b == 0 {
|
||||
return a
|
||||
}
|
||||
|
||||
return gcd(b, a%b)
|
||||
}
|
||||
|
||||
// LCM return Least Common Multiple (LCM) of integers.
|
||||
func LCM(integers ...int) int {
|
||||
result := integers[0]
|
||||
|
||||
for k := range integers {
|
||||
result = lcm(integers[k], result)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// find Least Common Multiple (LCM) via GCD.
|
||||
func lcm(a, b int) int {
|
||||
if a == 0 || b == 0 {
|
||||
panic("lcm function: provide non zero integers only.")
|
||||
}
|
||||
return a * b / gcd(a, b)
|
||||
}
|
||||
|
||||
// Cos returns the cosine of the radian argument.
|
||||
func Cos(radian float64, precision ...int) float64 {
|
||||
t := 1.0 / (2.0 * math.Pi)
|
||||
radian *= t
|
||||
radian -= 0.25 + math.Floor(radian+0.25)
|
||||
radian *= 16.0 * (math.Abs(radian) - 0.5)
|
||||
radian += 0.225 * radian * (math.Abs(radian) - 1.0)
|
||||
|
||||
if len(precision) == 1 {
|
||||
return TruncRound(radian, precision[0])
|
||||
}
|
||||
|
||||
return TruncRound(radian, 3)
|
||||
}
|
||||
|
||||
// Cos returns the sine of the radian argument.
|
||||
func Sin(radian float64, precision ...int) float64 {
|
||||
return Cos((math.Pi / 2) - radian)
|
||||
}
|
||||
|
||||
@@ -114,3 +114,61 @@ func TestIsPrime(t *testing.T) {
|
||||
assert.Equal(true, IsPrime(3))
|
||||
assert.Equal(false, IsPrime(4))
|
||||
}
|
||||
|
||||
func TestGCD(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestGCD")
|
||||
|
||||
assert.Equal(1, GCD(1, 1))
|
||||
assert.Equal(1, GCD(1, -1))
|
||||
assert.Equal(-1, GCD(-1, 1))
|
||||
assert.Equal(-1, GCD(-1, -1))
|
||||
|
||||
assert.Equal(1, GCD(1, 0))
|
||||
assert.Equal(1, GCD(0, 1))
|
||||
assert.Equal(-1, GCD(-1, 0))
|
||||
assert.Equal(-1, GCD(0, -1))
|
||||
|
||||
assert.Equal(1, GCD(1, -2))
|
||||
assert.Equal(1, GCD(-2, 1))
|
||||
assert.Equal(-1, GCD(-1, 2))
|
||||
assert.Equal(-1, GCD(2, -1))
|
||||
|
||||
assert.Equal(-1, GCD(-1, -2))
|
||||
assert.Equal(-1, GCD(-2, -1))
|
||||
|
||||
assert.Equal(-9, GCD(-27, -36))
|
||||
assert.Equal(3, GCD(3, 6, 9))
|
||||
}
|
||||
|
||||
func TestLCM(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestLCM")
|
||||
|
||||
assert.Equal(1, LCM(1))
|
||||
assert.Equal(-1, LCM(-1))
|
||||
assert.Equal(-1, LCM(1, -1))
|
||||
assert.Equal(1, LCM(-1, 1))
|
||||
assert.Equal(1, LCM(1, 1))
|
||||
assert.Equal(-1, LCM(-1, -1))
|
||||
assert.Equal(2, LCM(1, 2))
|
||||
assert.Equal(18, LCM(3, 6, 9))
|
||||
}
|
||||
|
||||
func TestCos(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestCos")
|
||||
|
||||
assert.EqualValues(1, Cos(0))
|
||||
assert.EqualValues(-0.447, Cos(90))
|
||||
assert.EqualValues(-0.598, Cos(180))
|
||||
assert.EqualValues(-1, Cos(math.Pi))
|
||||
assert.EqualValues(0, Cos(math.Pi/2))
|
||||
}
|
||||
|
||||
func TestSin(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSin")
|
||||
|
||||
assert.EqualValues(0, Sin(0))
|
||||
assert.EqualValues(0.894, Sin(90))
|
||||
assert.EqualValues(-0.801, Sin(180))
|
||||
assert.EqualValues(0, Sin(math.Pi))
|
||||
assert.EqualValues(1, Sin(math.Pi/2))
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package netutil
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
@@ -51,23 +52,23 @@ func TestHttpPost(t *testing.T) {
|
||||
func TestHttpPostFormData(t *testing.T) {
|
||||
apiUrl := "https://jsonplaceholder.typicode.com/todos"
|
||||
header := map[string]string{
|
||||
// "Content-Type": "application/x-www-form-urlencoded",
|
||||
"Content-Type": "multipart/form-data",
|
||||
}
|
||||
type Todo struct {
|
||||
UserId int `json:"userId"`
|
||||
Title string `json:"title"`
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
// "Content-Type": "multipart/form-data",
|
||||
}
|
||||
|
||||
postData := url.Values{}
|
||||
postData.Add("userId", "1")
|
||||
postData.Add("title", "TestAddToDo")
|
||||
postData.Add("title", "TestToDo")
|
||||
|
||||
resp, err := HttpPost(apiUrl, header, postData, nil)
|
||||
// postData := make(map[string]string)
|
||||
// postData["userId"] = "1"
|
||||
// postData["title"] = "title"
|
||||
|
||||
resp, err := HttpPost(apiUrl, header, nil, postData)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
t.FailNow()
|
||||
}
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
t.Log("response: ", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -242,11 +243,17 @@ func DownloadFile(filepath string, url string) error {
|
||||
|
||||
// IsPingConnected checks if can ping specified host or not.
|
||||
func IsPingConnected(host string) bool {
|
||||
cmd := exec.Command("ping", host, "-c", "1", "-W", "6")
|
||||
cmd := exec.Command("ping", host, "-c", "4", "-W", "6")
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
cmd = exec.Command("ping", host, "-n", "4", "-w", "6")
|
||||
}
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -74,51 +75,34 @@ func setHeaderAndQueryParam(req *http.Request, reqUrl string, header, queryParam
|
||||
}
|
||||
|
||||
func setHeaderAndQueryAndBody(req *http.Request, reqUrl string, header, queryParam, body interface{}) error {
|
||||
err := setHeader(req, header)
|
||||
if err != nil {
|
||||
if err := setHeader(req, header); err != nil {
|
||||
return err
|
||||
}
|
||||
err = setQueryParam(req, reqUrl, queryParam)
|
||||
if err != nil {
|
||||
} else if err = setQueryParam(req, reqUrl, queryParam); err != nil {
|
||||
return err
|
||||
}
|
||||
if strings.Contains(req.Header.Get("Content-Type"), "multipart/form-data") || req.Header.Get("Content-Type") == "application/x-www-form-urlencoded" {
|
||||
if formData, ok := queryParam.(url.Values); ok {
|
||||
err = setBodyByte(req, []byte(formData.Encode()))
|
||||
}
|
||||
if formData, ok := queryParam.(map[string]string); ok {
|
||||
postData := url.Values{}
|
||||
for k, v := range formData {
|
||||
postData.Set(k, v)
|
||||
}
|
||||
err = setBodyByte(req, []byte(postData.Encode()))
|
||||
}
|
||||
|
||||
} else {
|
||||
err = setBodyByte(req, body)
|
||||
}
|
||||
if err != nil {
|
||||
} else if err = setBodyByte(req, body); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func setHeader(req *http.Request, header interface{}) error {
|
||||
if header != nil {
|
||||
switch v := header.(type) {
|
||||
case map[string]string:
|
||||
for k := range v {
|
||||
req.Header.Add(k, v[k])
|
||||
}
|
||||
case http.Header:
|
||||
for k, vv := range v {
|
||||
for _, vvv := range vv {
|
||||
req.Header.Add(k, vvv)
|
||||
}
|
||||
}
|
||||
default:
|
||||
return errors.New("header params type should be http.Header or map[string]string")
|
||||
if header == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch v := header.(type) {
|
||||
case map[string]string:
|
||||
for k := range v {
|
||||
req.Header.Add(k, v[k])
|
||||
}
|
||||
case http.Header:
|
||||
for k, vv := range v {
|
||||
for _, vvv := range vv {
|
||||
req.Header.Add(k, vvv)
|
||||
}
|
||||
}
|
||||
default:
|
||||
return errors.New("header params type should be http.Header or map[string]string")
|
||||
}
|
||||
|
||||
if host := req.Header.Get("Host"); host != "" {
|
||||
@@ -138,19 +122,22 @@ func setUrl(req *http.Request, reqUrl string) error {
|
||||
}
|
||||
|
||||
func setQueryParam(req *http.Request, reqUrl string, queryParam interface{}) error {
|
||||
if queryParam == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var values url.Values
|
||||
if queryParam != nil {
|
||||
switch v := queryParam.(type) {
|
||||
case map[string]interface{}:
|
||||
values = url.Values{}
|
||||
for k := range v {
|
||||
values.Set(k, fmt.Sprintf("%v", v[k]))
|
||||
}
|
||||
case url.Values:
|
||||
values = v
|
||||
default:
|
||||
return errors.New("query params type should be url.Values or map[string]interface{}")
|
||||
|
||||
switch v := queryParam.(type) {
|
||||
case map[string]interface{}:
|
||||
values = url.Values{}
|
||||
for k := range v {
|
||||
values.Set(k, fmt.Sprintf("%v", v[k]))
|
||||
}
|
||||
case url.Values:
|
||||
values = v
|
||||
default:
|
||||
return errors.New("query params type should be url.Values or map[string]interface{}")
|
||||
}
|
||||
|
||||
// set url
|
||||
@@ -171,14 +158,36 @@ func setQueryParam(req *http.Request, reqUrl string, queryParam interface{}) err
|
||||
}
|
||||
|
||||
func setBodyByte(req *http.Request, body interface{}) error {
|
||||
if body != nil {
|
||||
switch b := body.(type) {
|
||||
case []byte:
|
||||
req.Body = ioutil.NopCloser(bytes.NewReader(b))
|
||||
req.ContentLength = int64(len(b))
|
||||
default:
|
||||
return errors.New("body type should be []byte")
|
||||
if body == nil {
|
||||
return nil
|
||||
}
|
||||
var bodyReader *bytes.Reader
|
||||
switch b := body.(type) {
|
||||
case io.Reader:
|
||||
buf := bytes.NewBuffer(nil)
|
||||
if _, err := io.Copy(buf, b); err != nil {
|
||||
return err
|
||||
}
|
||||
req.Body = ioutil.NopCloser(buf)
|
||||
req.ContentLength = int64(buf.Len())
|
||||
case []byte:
|
||||
bodyReader = bytes.NewReader(b)
|
||||
req.Body = ioutil.NopCloser(bodyReader)
|
||||
req.ContentLength = int64(bodyReader.Len())
|
||||
case map[string]interface{}:
|
||||
values := url.Values{}
|
||||
for k := range b {
|
||||
values.Set(k, fmt.Sprintf("%v", b[k]))
|
||||
}
|
||||
bodyReader = bytes.NewReader([]byte(values.Encode()))
|
||||
req.Body = ioutil.NopCloser(bodyReader)
|
||||
req.ContentLength = int64(bodyReader.Len())
|
||||
case url.Values:
|
||||
bodyReader = bytes.NewReader([]byte(b.Encode()))
|
||||
req.Body = ioutil.NopCloser(bodyReader)
|
||||
req.ContentLength = int64(bodyReader.Len())
|
||||
default:
|
||||
return fmt.Errorf("invalid body type: %T", b)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -72,3 +72,10 @@ func TestTelnetConnected(t *testing.T) {
|
||||
result2 := IsTelnetConnected("www.baidu.com", "123")
|
||||
assert.Equal(false, result2)
|
||||
}
|
||||
|
||||
// func TestDownloadFile(t *testing.T) {
|
||||
// assert := internal.NewAssert(t, "TestDownloadFile")
|
||||
|
||||
// err := DownloadFile("./lancet_logo.jpg", "https://picx.zhimg.com/v2-fc82a4199749de9cfb71e32e54f489d3_720w.jpg?source=172ae18b")
|
||||
// assert.IsNil(err)
|
||||
// }
|
||||
|
||||
@@ -403,3 +403,103 @@ func IndexOffset(str string, substr string, idxFrom int) int {
|
||||
|
||||
return strings.Index(str[idxFrom:], substr) + idxFrom
|
||||
}
|
||||
|
||||
// ReplaceWithMap returns a copy of `str`, which is replaced by a map in unordered way, case-sensitively.
|
||||
func ReplaceWithMap(str string, replaces map[string]string) string {
|
||||
for k, v := range replaces {
|
||||
str = strings.ReplaceAll(str, k, v)
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
// SplitAndTrim splits string `str` by a string `delimiter` to a slice,
|
||||
// and calls Trim to every element of this slice. It ignores the elements
|
||||
// which are empty after Trim.
|
||||
func SplitAndTrim(str, delimiter string, characterMask ...string) []string {
|
||||
result := make([]string, 0)
|
||||
|
||||
for _, v := range strings.Split(str, delimiter) {
|
||||
v = Trim(v, characterMask...)
|
||||
if v != "" {
|
||||
result = append(result, v)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
var (
|
||||
// DefaultTrimChars are the characters which are stripped by Trim* functions in default.
|
||||
DefaultTrimChars = string([]byte{
|
||||
'\t', // Tab.
|
||||
'\v', // Vertical tab.
|
||||
'\n', // New line (line feed).
|
||||
'\r', // Carriage return.
|
||||
'\f', // New page.
|
||||
' ', // Ordinary space.
|
||||
0x00, // NUL-byte.
|
||||
0x85, // Delete.
|
||||
0xA0, // Non-breaking space.
|
||||
})
|
||||
)
|
||||
|
||||
// Trim strips whitespace (or other characters) from the beginning and end of a string.
|
||||
// The optional parameter `characterMask` specifies the additional stripped characters.
|
||||
func Trim(str string, characterMask ...string) string {
|
||||
trimChars := DefaultTrimChars
|
||||
|
||||
if len(characterMask) > 0 {
|
||||
trimChars += characterMask[0]
|
||||
}
|
||||
|
||||
return strings.Trim(str, trimChars)
|
||||
}
|
||||
|
||||
// HideString hide some chars in source string with param `replaceChar`.
|
||||
// replace range is origin[start : end]. [start, end)
|
||||
func HideString(origin string, start, end int, replaceChar string) string {
|
||||
size := len(origin)
|
||||
|
||||
if start > size-1 || start < 0 || end < 0 || start > end {
|
||||
return origin
|
||||
}
|
||||
|
||||
if end > size {
|
||||
end = size
|
||||
}
|
||||
|
||||
if replaceChar == "" {
|
||||
return origin
|
||||
}
|
||||
|
||||
startStr := origin[0:start]
|
||||
endStr := origin[end:size]
|
||||
|
||||
replaceSize := end - start
|
||||
replaceStr := strings.Repeat(replaceChar, replaceSize)
|
||||
|
||||
return startStr + replaceStr + endStr
|
||||
}
|
||||
|
||||
// ContainsAll return true if target string contains all the substrs.
|
||||
func ContainsAll(str string, substrs []string) bool {
|
||||
for _, v := range substrs {
|
||||
if !strings.Contains(str, v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// ContainsAny return true if target string contains any one of the substrs.
|
||||
func ContainsAny(str string, substrs []string) bool {
|
||||
for _, v := range substrs {
|
||||
if strings.Contains(str, v) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -386,3 +386,72 @@ func TestIndexOffset(t *testing.T) {
|
||||
assert.Equal(IndexOffset(str, "d", len(str)), -1)
|
||||
assert.Equal(IndexOffset(str, "f", -1), -1)
|
||||
}
|
||||
|
||||
func TestReplaceWithMap(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestReplaceWithMap")
|
||||
|
||||
str := "ac ab ab ac"
|
||||
replaces := map[string]string{
|
||||
"a": "1",
|
||||
"b": "2",
|
||||
}
|
||||
|
||||
assert.Equal(str, "ac ab ab ac")
|
||||
assert.Equal(ReplaceWithMap(str, replaces), "1c 12 12 1c")
|
||||
}
|
||||
|
||||
func TestTrim(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestTrim")
|
||||
|
||||
str1 := "$ ab cd $ "
|
||||
|
||||
assert.Equal("$ ab cd $", Trim(str1))
|
||||
assert.Equal("ab cd", Trim(str1, "$"))
|
||||
assert.Equal("abcd", Trim("\nabcd"))
|
||||
}
|
||||
|
||||
func TestSplitAndTrim(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestTrim")
|
||||
|
||||
str := " a,b, c,d,$1 "
|
||||
|
||||
result1 := SplitAndTrim(str, ",")
|
||||
result2 := SplitAndTrim(str, ",", "$")
|
||||
|
||||
assert.Equal([]string{"a", "b", "c", "d", "$1"}, result1)
|
||||
assert.Equal([]string{"a", "b", "c", "d", "1"}, result2)
|
||||
}
|
||||
|
||||
func TestHideString(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestTrim")
|
||||
|
||||
str := "13242658976"
|
||||
|
||||
assert.Equal("13242658976", HideString(str, 0, -1, "*"))
|
||||
assert.Equal("13242658976", HideString(str, 0, 0, "*"))
|
||||
assert.Equal("****2658976", HideString(str, 0, 4, "*"))
|
||||
|
||||
assert.Equal("13242658976", HideString(str, 3, 3, "*"))
|
||||
assert.Equal("132*2658976", HideString(str, 3, 4, "*"))
|
||||
assert.Equal("132****8976", HideString(str, 3, 7, "*"))
|
||||
assert.Equal("1324265****", HideString(str, 7, 11, "*"))
|
||||
|
||||
assert.Equal("1324265****", HideString(str, 7, 100, "*"))
|
||||
assert.Equal("13242658976", HideString(str, 100, 100, "*"))
|
||||
}
|
||||
|
||||
func TestContainsAll(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestContainsAll")
|
||||
|
||||
assert.Equal(true, ContainsAll("hello world", []string{"hello", "world"}))
|
||||
assert.Equal(true, ContainsAll("hello world", []string{""}))
|
||||
assert.Equal(false, ContainsAll("hello world", []string{"hello", "abc"}))
|
||||
}
|
||||
|
||||
func TestContainsAny(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestContainsAny")
|
||||
|
||||
assert.Equal(true, ContainsAny("hello world", []string{"hello", "world"}))
|
||||
assert.Equal(true, ContainsAny("hello world", []string{"hello", "abc"}))
|
||||
assert.Equal(false, ContainsAny("hello world", []string{"123", "abc"}))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user