From ee44526d9ebb4e2f316d81df595d213cf35ab3c1 Mon Sep 17 00:00:00 2001
From: dudaodong return current absolute path. 返回当前位置的绝对路径。
Pretty data to JSON string.
+ +Signature: + +```go +func Pretty(v interface{}) (string, error) +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/formatter" +) + +func main() { + result1, _ := formatter.Pretty([]string{"a", "b", "c"}) + result2, _ := formatter.Pretty(map[string]int{"a": 1}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // [ + // "a", + // "b", + // "c" + // ] + // { + // "a": 1 + // } +} +``` + +### PrettyToWriter + +Pretty encode data to writer.
+ +Signature: + +```go +func PrettyToWriter(v interface{}, out io.Writer) error +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/formatter" +) + +func main() { + type User struct { + Name string `json:"name"` + Aage uint `json:"age"` + } + user := User{Name: "King", Aage: 10000} + + buf := &bytes.Buffer{} + err := formatter.PrettyToWriter(user, buf) + + fmt.Println(buf) + fmt.Println(err) + + // Output: + // { + // "name": "King", + // "age": 10000 + // } + // + //Returns a human readable byte size under decimal standard (base 1000). The precision parameter specifies the number of digits after the decimal point, which is 4 for default.
+ +Signature: + +```go +func DecimalBytes(size float64, precision ...int) string +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/formatter" +) + +func main() { + result1 := formatter.DecimalBytes(1000) + result2 := formatter.DecimalBytes(1024) + result3 := formatter.DecimalBytes(1234567) + result4 := formatter.DecimalBytes(1234567, 3) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 1KB + // 1.024KB + // 1.2346MB + // 1.235MB +} +``` + +### BinaryBytes + +Returns a human readable byte size under binary standard (base 1024). The precision parameter specifies the number of digits after the decimal point, which is 4 for default.
+ +Signature: + +```go +func BinaryBytes(size float64, precision ...int) string +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/formatter" +) + +func main() { + result1 := formatter.BinaryBytes(1024) + result2 := formatter.BinaryBytes(1024 * 1024) + result3 := formatter.BinaryBytes(1234567) + result4 := formatter.BinaryBytes(1234567, 2) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 1KiB + // 1MiB + // 1.1774MiB + // 1.18MiB +} +``` + +### ParseDecimalBytes + +Returns the human readable bytes size string into the amount it represents(base 1000).
+ +Signature: + +```go +func ParseDecimalBytes(size string) (uint64, error) +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/formatter" +) + +func main() { + result1, _ := formatter.ParseDecimalBytes("12") + result2, _ := formatter.ParseDecimalBytes("12k") + result3, _ := formatter.ParseDecimalBytes("12 Kb") + result4, _ := formatter.ParseDecimalBytes("12.2 kb") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 12 + // 12000 + // 12000 + // 12200 +} +``` + +### ParseBinaryBytes + +Returns the human readable bytes size string into the amount it represents(base 1024).
+ +Signature: + +```go +func ParseBinaryBytes(size string) (uint64, error) +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/formatter" +) + +func main() { + result1, _ := formatter.ParseBinaryBytes("12") + result2, _ := formatter.ParseBinaryBytes("12ki") + result3, _ := formatter.ParseBinaryBytes("12 KiB") + result4, _ := formatter.ParseBinaryBytes("12.2 kib") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 12 + // 12288 + // 12288 + // 12492 +} +``` diff --git a/docs/formatter_zh-CN.md b/docs/formatter_zh-CN.md index 564993e..4e97367 100644 --- a/docs/formatter_zh-CN.md +++ b/docs/formatter_zh-CN.md @@ -23,6 +23,12 @@ import ( ## 目录 - [Comma](#Comma) +- [Pretty](#Pretty) +- [PrettyToWriter](#PrettyToWriter) +- [DecimalBytes](#DecimalBytes) +- [BinaryBytes](#BinaryBytes) +- [ParseDecimalBytes](#ParseDecimalBytes) +- [ParseBinaryBytes](#ParseBinaryBytes) @@ -53,3 +59,241 @@ func main() { fmt.Println(formatter.Comma(12345.67, "¥")) // "¥12,345.67" } ``` + +### Pretty + +返回pretty JSON字符串.
+ +函数签名: + +```go +func Pretty(v interface{}) (string, error) +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/formatter" +) + +func main() { + result1, _ := formatter.Pretty([]string{"a", "b", "c"}) + result2, _ := formatter.Pretty(map[string]int{"a": 1}) + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // [ + // "a", + // "b", + // "c" + // ] + // { + // "a": 1 + // } +} +``` + +### PrettyToWriter + +Pretty encode数据到writer。
+ +函数签名: + +```go +func PrettyToWriter(v interface{}, out io.Writer) error +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/formatter" +) + +func main() { + type User struct { + Name string `json:"name"` + Aage uint `json:"age"` + } + user := User{Name: "King", Aage: 10000} + + buf := &bytes.Buffer{} + err := formatter.PrettyToWriter(user, buf) + + fmt.Println(buf) + fmt.Println(err) + + // Output: + // { + // "name": "King", + // "age": 10000 + // } + // + //返回十进制标准(以1000为基数)下的可读字节单位字符串。precision参数指定小数点后的位数,默认为4。
+ +函数签名: + +```go +func DecimalBytes(size float64, precision ...int) string +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/formatter" +) + +func main() { + result1 := formatter.DecimalBytes(1000) + result2 := formatter.DecimalBytes(1024) + result3 := formatter.DecimalBytes(1234567) + result4 := formatter.DecimalBytes(1234567, 3) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 1KB + // 1.024KB + // 1.2346MB + // 1.235MB +} +``` + +### BinaryBytes + +返回binary标准(以1024为基数)下的可读字节单位字符串。precision参数指定小数点后的位数,默认为4。
+ +函数签名: + +```go +func BinaryBytes(size float64, precision ...int) string +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/formatter" +) + +func main() { + result1 := formatter.BinaryBytes(1024) + result2 := formatter.BinaryBytes(1024 * 1024) + result3 := formatter.BinaryBytes(1234567) + result4 := formatter.BinaryBytes(1234567, 2) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 1KiB + // 1MiB + // 1.1774MiB + // 1.18MiB +} +``` + +### ParseDecimalBytes + +将字节单位字符串转换成其所表示的字节数(以1000为基数)。
+ +函数签名: + +```go +func ParseDecimalBytes(size string) (uint64, error) +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/formatter" +) + +func main() { + result1, _ := formatter.ParseDecimalBytes("12") + result2, _ := formatter.ParseDecimalBytes("12k") + result3, _ := formatter.ParseDecimalBytes("12 Kb") + result4, _ := formatter.ParseDecimalBytes("12.2 kb") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 12 + // 12000 + // 12000 + // 12200 +} +``` + +### ParseBinaryBytes + +将字节单位字符串转换成其所表示的字节数(以1024为基数)。
+ +函数签名: + +```go +func ParseBinaryBytes(size string) (uint64, error) +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/formatter" +) + +func main() { + result1, _ := formatter.ParseBinaryBytes("12") + result2, _ := formatter.ParseBinaryBytes("12ki") + result3, _ := formatter.ParseBinaryBytes("12 KiB") + result4, _ := formatter.ParseBinaryBytes("12.2 kib") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // 12 + // 12288 + // 12288 + // 12492 +} +``` diff --git a/docs/mathutil.md b/docs/mathutil.md index f536259..5d44837 100644 --- a/docs/mathutil.md +++ b/docs/mathutil.md @@ -29,6 +29,10 @@ import ( - [RoundToFloat](#RoundToFloat) - [RoundToString](#RoundToString) - [TruncRound](#TruncRound) +- [AngleToRadian](#AngleToRadian) +- [RadianToAngle](#RadianToAngle) +- [PointDistance](#PointDistance) +- [IsPrime](#IsPrime) @@ -230,3 +234,144 @@ func main() { fmt.Println(mathutil.TruncRound(0.125, 3)) //0.125 } ``` + +### AngleToRadian + +Converts angle value to radian value.
+ +Signature: + +```go +func AngleToRadian(angle float64) float64 +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/mathutil" +) + +func main() { + result1 := mathutil.AngleToRadian(45) + result2 := mathutil.AngleToRadian(90) + result3 := mathutil.AngleToRadian(180) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 0.7853981633974483 + // 1.5707963267948966 + // 3.141592653589793 +} +``` + +### RadianToAngle + +Converts radian value to angle value.
+ +Signature: + +```go +func RadianToAngle(radian float64) float64 +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/mathutil" +) + +func main() { + result1 := mathutil.RadianToAngle(math.Pi) + result2 := mathutil.RadianToAngle(math.Pi / 2) + result3 := mathutil.RadianToAngle(math.Pi / 4) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 180 + // 90 + // 45 +} +``` + +### PointDistance + +Caculates two points distance.
+ +Signature: + +```go +func PointDistance(x1, y1, x2, y2 float64) float64 +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/mathutil" +) + +func main() { + result1 := mathutil.PointDistance(1, 1, 4, 5) + + fmt.Println(result1) + + // Output: + // 5 +} +``` + +### IsPrime + +Checks if number is prime number.
+ +Signature: + +```go +func IsPrime(n int) bool +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/mathutil" +) + +func main() { + result1 := mathutil.IsPrime(-1) + result2 := mathutil.IsPrime(0) + result3 := mathutil.IsPrime(1) + result4 := mathutil.IsPrime(2) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // false + // false + // false + // true +} +``` diff --git a/docs/mathutil_zh-CN.md b/docs/mathutil_zh-CN.md index bb7cdfb..7414a30 100644 --- a/docs/mathutil_zh-CN.md +++ b/docs/mathutil_zh-CN.md @@ -25,11 +25,14 @@ import ( - [Exponent](#Exponent) - [Fibonacci](#Fibonacci) - [Factorial](#Factorial) - - [Percent](#Percent) - [RoundToFloat](#RoundToFloat) - [RoundToString](#RoundToString) - [TruncRound](#TruncRound) +- [AngleToRadian](#AngleToRadian) +- [RadianToAngle](#RadianToAngle) +- [PointDistance](#PointDistance) +- [IsPrime](#IsPrime) @@ -231,3 +234,144 @@ func main() { fmt.Println(mathutil.TruncRound(0.125, 3)) //0.125 } ``` + +### AngleToRadian + +将角度值转为弧度值
+ +函数签名: + +```go +func AngleToRadian(angle float64) float64 +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/mathutil" +) + +func main() { + result1 := mathutil.AngleToRadian(45) + result2 := mathutil.AngleToRadian(90) + result3 := mathutil.AngleToRadian(180) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 0.7853981633974483 + // 1.5707963267948966 + // 3.141592653589793 +} +``` + +### RadianToAngle + +将弧度值转为角度值
+ +函数签名: + +```go +func RadianToAngle(radian float64) float64 +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/mathutil" +) + +func main() { + result1 := mathutil.RadianToAngle(math.Pi) + result2 := mathutil.RadianToAngle(math.Pi / 2) + result3 := mathutil.RadianToAngle(math.Pi / 4) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + + // Output: + // 180 + // 90 + // 45 +} +``` + +### PointDistance + +计算两个坐标点的距离
+ +函数签名: + +```go +func PointDistance(x1, y1, x2, y2 float64) float64 +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/mathutil" +) + +func main() { + result1 := mathutil.PointDistance(1, 1, 4, 5) + + fmt.Println(result1) + + // Output: + // 5 +} +``` + +### IsPrime + +判断质数。
+ +函数签名: + +```go +func IsPrime(n int) bool +``` + +示例: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/mathutil" +) + +func main() { + result1 := mathutil.IsPrime(-1) + result2 := mathutil.IsPrime(0) + result3 := mathutil.IsPrime(1) + result4 := mathutil.IsPrime(2) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // false + // false + // false + // true +} +``` diff --git a/docs/netutil.md b/docs/netutil.md index 927ae49..e8892e8 100644 --- a/docs/netutil.md +++ b/docs/netutil.md @@ -46,6 +46,8 @@ import ( - [HttpPutDeprecated](#HttpPut) - [HttpPatchDeprecated](#HttpPatch) - [ParseHttpResponse](#ParseHttpResponse) +- [UploadFile](#UploadFile) +- [DownloadFile](#DownloadFile) - [IsPingConnected](#IsPingConnected) - [IsTelnetConnected](#IsTelnetConnected) @@ -553,7 +555,7 @@ package main import ( "fmt" - "github.com/duke-git/lancet/v2/netutil" + "github.com/duke-git/lancet/netutil" ) func main() { @@ -865,6 +867,62 @@ func main() { } ``` +### UploadFile + +upload the file to a server.
+ +Signature: + +```go +func UploadFile(filepath string, server string) (bool, error) +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/netutil" +) + +func main() { + ok, err := netutil.UploadFile("./a.jpg", "http://www.xxx.com/bucket/test") + + fmt.Println(ok) + fmt.Println(err) +} +``` + +### DownloadFile + +download the file exist in url to a local file.
+ +Signature: + +```go +func DownloadFile(filepath string, url string) error +``` + +Example: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/netutil" +) + +func main() { + ok, err := netutil.DownloadFile("./", "http://www.xxx.com/a.jpg") + + fmt.Println(ok) + fmt.Println(err) +} +``` + ### IsPingConnectedchecks if can ping the specified host or not.
diff --git a/docs/netutil_zh-CN.md b/docs/netutil_zh-CN.md index 07c35af..bb1d350 100644 --- a/docs/netutil_zh-CN.md +++ b/docs/netutil_zh-CN.md @@ -45,6 +45,8 @@ import ( - [HttpPutDeprecated](#HttpPut) - [HttpPatchDeprecated](#HttpPatch) - [ParseHttpResponse](#ParseHttpResponse) +- [UploadFile](#UploadFile) +- [DownloadFile](#DownloadFile) - [IsPingConnected](#IsPingConnected) - [IsTelnetConnected](#IsTelnetConnected) @@ -552,7 +554,7 @@ package main import ( "fmt" - "github.com/duke-git/lancet/v2/netutil" + "github.com/duke-git/lancet/netutil" ) func main() { @@ -864,6 +866,62 @@ func main() { } ``` +### UploadFile + +将文件上传指定的server地址。
+ +函数签名: + +```go +func UploadFile(filepath string, server string) (bool, error) +``` + +例子: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/netutil" +) + +func main() { + ok, err := netutil.UploadFile("./a.jpg", "http://www.xxx.com/bucket/test") + + fmt.Println(ok) + fmt.Println(err) +} +``` + +### DownloadFile + +从指定的server地址下载文件。
+ +函数签名: + +```go +func DownloadFile(filepath string, url string) error +``` + +例子: + +```go +package main + +import ( + "fmt" + "github.com/duke-git/lancet/netutil" +) + +func main() { + ok, err := netutil.DownloadFile("./", "http://www.xxx.com/a.jpg") + + fmt.Println(ok) + fmt.Println(err) +} +``` + ### IsPingConnected检查能否ping通主机。
diff --git a/docs/slice_zh-CN.md b/docs/slice_zh-CN.md index 8e6e24e..01849c2 100644 --- a/docs/slice_zh-CN.md +++ b/docs/slice_zh-CN.md @@ -1007,7 +1007,7 @@ func ToSlice(value ...interface{}) interface{} ```go import ( "fmt" - "github.com/duke-git/lancet/v2/slice" + "github.com/duke-git/lancet/slice" ) func main() { @@ -1031,7 +1031,7 @@ func ToSlicePointer(value ...interface{}) []*interface{} ```go import ( "fmt" - "github.com/duke-git/lancet/v2/slice" + "github.com/duke-git/lancet/slice" ) func main() { diff --git a/docs/validator.md b/docs/validator.md index 7a88002..ad4a218 100644 --- a/docs/validator.md +++ b/docs/validator.md @@ -37,11 +37,14 @@ import ( - [IsDns](#IsDns) - [IsEmail](#IsEmail) - [IsEmptyString](#IsEmptyString) +- [IsInt](#IsInt) +- [IsFloat](#IsFloat) +- [IsNumber](#IsNumber) +- [IsIntStr](#IsIntStr) - [IsFloatStr](#IsFloatStr) - [IsNumberStr](#IsNumberStr) - [IsJSON](#IsJSON) - [IsRegexMatch](#IsRegexMatch) -- [IsIntStr](#IsIntStr) - [IsIp](#IsIp) - [IsIpV4](#IsIpV4) - [IsIpV6](#IsIpV6) @@ -50,6 +53,8 @@ import ( - [IsWeakPassword](#IsWeakPassword) - [IsZeroValue](#IsZeroValue) - [IsGBK](#IsGBK) +- [IsASCII](#IsASCII) +- [IsAIsPrintableSCII](#IsPrintable) @@ -478,6 +483,143 @@ func main() { } ``` +### IsInt + +Check if the value is integer(int, unit) or not.
+ +Signature: + +```go +func IsInt(v interface{}) bool +``` + +Example: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/validator" +) + +func main() { + result1 := validator.IsInt("") + result2 := validator.IsInt("3") + result3 := validator.IsInt(0.1) + result4 := validator.IsInt(0) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // false + // false + // false + // true +} +``` + +### IsFloat + +Check if the value is float(float32, float34) or not.
+ +Signature: + +```go +func IsFloat(v interface{}) bool +``` + +Example: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/validator" +) + +func main() { + result1 := validator.IsFloat("") + result2 := validator.IsFloat("3") + result3 := validator.IsFloat(0) + result4 := validator.IsFloat(0.1) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // false + // false + // false + // true +} +``` + +### IsNumber + +Check if the value is number(integer, float) or not.
+ +Signature: + +```go +func IsNumber(v interface{}) bool +``` + +Example: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/validator" +) + +func main() { + result1 := validator.IsNumber("") + result2 := validator.IsNumber("3") + result3 := validator.IsNumber(0.1) + result4 := validator.IsNumber(0) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // false + // false + // true + // true +} +``` + +### IsIntStr + +Check if the string can convert to a integer.
+ +Signature: + +```go +func IsIntStr(s string) bool +``` + +Example: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/validator" +) + +func main() { + fmt.Println(validator.IsIntStr("+3")) //true + fmt.Println(validator.IsIntStr("-3")) //true + fmt.Println(validator.IsIntStr("3.")) //false + fmt.Println(validator.IsIntStr("abc")) //false +} +``` + ### IsFloatStrCheck if the string can convert to a float.
@@ -587,32 +729,6 @@ func main() { } ``` -### IsIntStr - -Check if the string can convert to a integer.
- -Signature: - -```go -func IsIntStr(s string) bool -``` - -Example: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsIntStr("+3")) //true - fmt.Println(validator.IsIntStr("-3")) //true - fmt.Println(validator.IsIntStr("3.")) //false - fmt.Println(validator.IsIntStr("abc")) //false -} -``` - ### IsIpCheck if the string is a ip address.
@@ -778,7 +894,7 @@ func main() { Signature: ```go -func IsZeroValue(value any) bool +func IsZeroValue(value interface{}) bool ``` Example: @@ -831,3 +947,83 @@ func main() { fmt.Println("data encoding is unknown") } ``` + +### IsASCII + +Checks if string is all ASCII char.
+ +Signature: + +```go +func IsASCII(str string) bool +``` + +Example: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/validator" +) + +func main() { + result1 := validator.IsASCII("ABC") + result2 := validator.IsASCII("123") + result3 := validator.IsASCII("") + result4 := validator.IsASCII("😄") + result5 := validator.IsASCII("你好") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // true + // true + // true + // false + // false +} +``` + +### IsPrintable + +Checks if string is all printable chars.
+ +Signature: + +```go +func IsPrintable(str string) bool +``` + +Example: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/validator" +) + +func main() { + result1 := validator.IsPrintable("ABC") + result2 := validator.IsPrintable("{id: 123}") + result3 := validator.IsPrintable("") + result4 := validator.IsPrintable("😄") + result5 := validator.IsPrintable("\u0000") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // true + // true + // true + // true + // false +} +``` \ No newline at end of file diff --git a/docs/validator_zh-CN.md b/docs/validator_zh-CN.md index 9882e1f..a1f34db 100644 --- a/docs/validator_zh-CN.md +++ b/docs/validator_zh-CN.md @@ -37,11 +37,14 @@ import ( - [IsDns](#IsDns) - [IsEmail](#IsEmail) - [IsEmptyString](#IsEmptyString) +- [IsInt](#IsInt) +- [IsFloat](#IsFloat) +- [IsNumber](#IsNumber) +- [IsIntStr](#IsIntStr) - [IsFloatStr](#IsFloatStr) - [IsNumberStr](#IsNumberStr) - [IsJSON](#IsJSON) - [IsRegexMatch](#IsRegexMatch) -- [IsIntStr](#IsIntStr) - [IsIp](#IsIp) - [IsIpV4](#IsIpV4) - [IsIpV6](#IsIpV6) @@ -50,6 +53,8 @@ import ( - [IsWeakPassword](#IsWeakPassword) - [IsZeroValue](#IsZeroValue) - [IsGBK](#IsGBK) +- [IsASCII](#IsASCII) +- [IsPrintable](#IsPrintable) @@ -478,6 +483,154 @@ func main() { } ``` +### IsInt + +验证参数是否是整数(int, unit)。
+ +函数签名: + +```go +func IsInt(v interface{}) bool +``` + +示例: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/validator" +) + +func main() { + result1 := validator.IsInt("") + result2 := validator.IsInt("3") + result3 := validator.IsInt(0.1) + result4 := validator.IsInt(0) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // false + // false + // false + // true +} +``` + +### IsFloat + +验证参数是否是浮点数((float32, float34)。
+ +函数签名: + +```go +func IsFloat(v interface{}) bool +``` + +示例: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/validator" +) + +func main() { + result1 := validator.IsFloat("") + result2 := validator.IsFloat("3") + result3 := validator.IsFloat(0) + result4 := validator.IsFloat(0.1) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // false + // false + // false + // true +} +``` + +### IsNumber + +验证参数是否是数字(integer or float)
+ +函数签名: + +```go +func IsNumber(v interface{}) bool +``` + +示例: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/validator" +) + +func main() { + result1 := validator.IsNumber("") + result2 := validator.IsNumber("3") + result3 := validator.IsNumber(0.1) + result4 := validator.IsNumber(0) + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // false + // false + // true + // true +} +``` + +### IsIntStr + +验证字符串是否是可以转换为整数
+ +函数签名: + +```go +func IsIntStr(s string) bool +``` + +示例: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/validator" +) + +func main() { + result1 := validator.IsIntStr("+3") + result2 := validator.IsIntStr("-3") + result3 := validator.IsIntStr("3.") + result4 := validator.IsIntStr("abc") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + + // Output: + // true + // true + // false + // false +} +``` + ### IsFloatStr验证字符串是否是可以转换为浮点数
@@ -587,32 +740,6 @@ func main() { } ``` -### IsIntStr - -验证字符串是否是可以转换为整数
- -函数签名: - -```go -func IsIntStr(s string) bool -``` - -例子: - -```go -import ( - "fmt" - "github.com/duke-git/lancet/validator" -) - -func main() { - fmt.Println(validator.IsIntStr("+3")) //true - fmt.Println(validator.IsIntStr("-3")) //true - fmt.Println(validator.IsIntStr("3.")) //false - fmt.Println(validator.IsIntStr("abc")) //false -} -``` - ### IsIp验证字符串是否是ip地址
@@ -778,7 +905,7 @@ func main() { 函数签名: ```go -func IsZeroValue(value any) bool +func IsZeroValue(value interface{}) bool ``` 例子: @@ -831,3 +958,82 @@ func main() { fmt.Println("data encoding is unknown") } ``` +### IsASCII + +验证字符串全部为ASCII字符。
+ +函数签名: + +```go +func IsASCII(str string) bool +``` + +示例: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/validator" +) + +func main() { + result1 := validator.IsASCII("ABC") + result2 := validator.IsASCII("123") + result3 := validator.IsASCII("") + result4 := validator.IsASCII("😄") + result5 := validator.IsASCII("你好") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // true + // true + // true + // false + // false +} +``` + +### IsPrintable + +检查字符串是否全部为可打印字符。
+ +函数签名: + +```go +func IsPrintable(str string) bool +``` + +示例: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/validator" +) + +func main() { + result1 := validator.IsPrintable("ABC") + result2 := validator.IsPrintable("{id: 123}") + result3 := validator.IsPrintable("") + result4 := validator.IsPrintable("😄") + result5 := validator.IsPrintable("\u0000") + + fmt.Println(result1) + fmt.Println(result2) + fmt.Println(result3) + fmt.Println(result4) + fmt.Println(result5) + + // Output: + // true + // true + // true + // true + // false +} +``` \ No newline at end of file diff --git a/fileutil/file.go b/fileutil/file.go index f2fe11c..8c1a6b3 100644 --- a/fileutil/file.go +++ b/fileutil/file.go @@ -16,6 +16,7 @@ import ( "os" "path" "path/filepath" + "runtime" "strings" ) @@ -88,7 +89,7 @@ func CopyFile(srcFilePath string, dstFilePath string) error { } } -//ClearFile write empty string to path file +// ClearFile write empty string to path file func ClearFile(path string) error { f, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777) if err != nil { @@ -100,7 +101,7 @@ func ClearFile(path string) error { return err } -//ReadFileToString return string of file content +// ReadFileToString return string of file content func ReadFileToString(path string) (string, error) { bytes, err := ioutil.ReadFile(path) if err != nil { @@ -318,3 +319,14 @@ func MiMeType(file interface{}) string { } return mediatype } + +// CurrentPath return current absolute path. +func CurrentPath() string { + var absPath string + _, filename, _, ok := runtime.Caller(1) + if ok { + absPath = path.Dir(filename) + } + + return absPath +} diff --git a/fileutil/file_test.go b/fileutil/file_test.go index 73b2eb5..945bcf5 100644 --- a/fileutil/file_test.go +++ b/fileutil/file_test.go @@ -221,3 +221,8 @@ func TestMiMeType(t *testing.T) { assert.Equal("text/plain; charset=utf-8", MiMeType(f)) assert.Equal("text/plain; charset=utf-8", MiMeType("./file.go")) } + +func TestCurrentPath(t *testing.T) { + absPath := CurrentPath() + t.Log(absPath) +} diff --git a/formatter/formatter.go b/formatter/formatter.go index 9d5687b..8219430 100644 --- a/formatter/formatter.go +++ b/formatter/formatter.go @@ -4,14 +4,176 @@ // Package formatter implements some functions to format string, struct. package formatter -import "strings" +import ( + "encoding/json" + "fmt" + "io" -// Comma add comma to number by every 3 numbers from right. ahead by symbol char -func Comma(v interface{}, symbol string) string { - s := numString(v) - dotIndex := strings.Index(s, ".") - if dotIndex != -1 { - return symbol + commaString(s[:dotIndex]) + s[dotIndex:] + "github.com/duke-git/lancet/convertor" + "github.com/duke-git/lancet/strutil" + "github.com/duke-git/lancet/validator" +) + +// Comma add comma to a number value by every 3 numbers from right. ahead by symbol char. +// if value is invalid number string eg "aa", return empty string +// Comma("12345", "$") => "$12,345", Comma(12345, "$") => "$12,345" +func Comma(value interface{}, symbol string) string { + if validator.IsInt(value) { + v, err := convertor.ToInt(value) + if err != nil { + return "" + } + return symbol + commaInt(v) } - return symbol + commaString(s) + + if validator.IsFloat(value) { + v, err := convertor.ToFloat(value) + if err != nil { + return "" + } + return symbol + commaFloat(v) + } + + if strutil.IsString(value) { + v := fmt.Sprintf("%v", value) + if validator.IsNumberStr(v) { + return symbol + commaStr(v) + } + return "" + } + + return "" +} + +// Pretty data to JSON string. +func Pretty(v interface{}) (string, error) { + out, err := json.MarshalIndent(v, "", " ") + return string(out), err +} + +// PrettyToWriter pretty encode data to writer. +func PrettyToWriter(v interface{}, out io.Writer) error { + enc := json.NewEncoder(out) + enc.SetIndent("", " ") + + if err := enc.Encode(v); err != nil { + return err + } + + return nil +} + +// http://en.wikipedia.org/wiki/Binary_prefix +const ( + // Decimal + UnitB = 1 + UnitKB = 1000 + UnitMB = 1000 * UnitKB + UnitGB = 1000 * UnitMB + UnitTB = 1000 * UnitGB + UnitPB = 1000 * UnitTB + UnitEB = 1000 * UnitPB + + // Binary + UnitBiB = 1 + UnitKiB = 1024 + UnitMiB = 1024 * UnitKiB + UnitGiB = 1024 * UnitMiB + UnitTiB = 1024 * UnitGiB + UnitPiB = 1024 * UnitTiB + UnitEiB = 1024 * UnitPiB +) + +// type byteUnitMap map[byte]int64 + +var ( + decimalByteMap = map[string]uint64{ + "b": UnitB, + "kb": UnitKB, + "mb": UnitMB, + "gb": UnitGB, + "tb": UnitTB, + "pb": UnitPB, + "eb": UnitEB, + + // Without suffix + "": UnitB, + "k": UnitKB, + "m": UnitMB, + "g": UnitGB, + "t": UnitTB, + "p": UnitPB, + "e": UnitEB, + } + + binaryByteMap = map[string]uint64{ + "bi": UnitBiB, + "kib": UnitKiB, + "mib": UnitMiB, + "gib": UnitGiB, + "tib": UnitTiB, + "pib": UnitPiB, + "eib": UnitEiB, + + // Without suffix + "": UnitBiB, + "ki": UnitKiB, + "mi": UnitMiB, + "gi": UnitGiB, + "ti": UnitTiB, + "pi": UnitPiB, + "ei": UnitEiB, + } +) + +var ( + decimalByteUnits = []string{"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"} + binaryByteUnits = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"} +) + +// DecimalBytes returns a human readable byte size under decimal standard (base 1000) +// The precision parameter specifies the number of digits after the decimal point, which defaults to 4. +// Play: https://go.dev/play/p/FPXs1suwRcs +func DecimalBytes(size float64, precision ...int) string { + p := 5 + if len(precision) > 0 { + p = precision[0] + 1 + } + size, unit := calculateByteSize(size, 1000.0, decimalByteUnits) + + return fmt.Sprintf("%.*g%s", p, size, unit) +} + +// BinaryBytes returns a human-readable byte size under binary standard (base 1024) +// The precision parameter specifies the number of digits after the decimal point, which defaults to 4. +func BinaryBytes(size float64, precision ...int) string { + p := 5 + if len(precision) > 0 { + p = precision[0] + 1 + } + size, unit := calculateByteSize(size, 1024.0, binaryByteUnits) + + return fmt.Sprintf("%.*g%s", p, size, unit) +} + +func calculateByteSize(size float64, base float64, byteUnits []string) (float64, string) { + i := 0 + unitsLimit := len(byteUnits) - 1 + for size >= base && i < unitsLimit { + size = size / base + i++ + } + return size, byteUnits[i] +} + +// ParseDecimalBytes return the human readable bytes size string into the amount it represents(base 1000). +// ParseDecimalBytes("42 MB") -> 42000000, nil +func ParseDecimalBytes(size string) (uint64, error) { + return parseBytes(size, "decimal") +} + +// ParseBinaryBytes return the human readable bytes size string into the amount it represents(base 1024). +// ParseBinaryBytes("42 mib") -> 44040192, nil +func ParseBinaryBytes(size string) (uint64, error) { + return parseBytes(size, "binary") } diff --git a/formatter/formatter_internal.go b/formatter/formatter_internal.go index 4928147..43427cc 100644 --- a/formatter/formatter_internal.go +++ b/formatter/formatter_internal.go @@ -1,40 +1,134 @@ package formatter import ( + "bytes" "fmt" - "reflect" + "math" "strconv" "strings" + "unicode" ) -func commaString(s string) string { +// see https://github.com/dustin/go-humanize/blob/master/comma.go +func commaInt(v int64) string { + sign := "" + + // Min int64 can't be negated to a usable value, so it has to be special cased. + if v == math.MinInt64 { + return "-9,223,372,036,854,775,808" + } + + if v < 0 { + sign = "-" + v = 0 - v + } + + parts := []string{"", "", "", "", "", "", ""} + j := len(parts) - 1 + + for v > 999 { + parts[j] = strconv.FormatInt(v%1000, 10) + switch len(parts[j]) { + case 2: + parts[j] = "0" + parts[j] + case 1: + parts[j] = "00" + parts[j] + } + v = v / 1000 + j-- + } + parts[j] = strconv.Itoa(int(v)) + return sign + strings.Join(parts[j:], ",") +} + +func commaFloat(v float64) string { + buf := &bytes.Buffer{} + if v < 0 { + buf.Write([]byte{'-'}) + v = 0 - v + } + + comma := []byte{','} + + parts := strings.Split(strconv.FormatFloat(v, 'f', -1, 64), ".") + pos := 0 + if len(parts[0])%3 != 0 { + pos += len(parts[0]) % 3 + buf.WriteString(parts[0][:pos]) + buf.Write(comma) + } + for ; pos < len(parts[0]); pos += 3 { + buf.WriteString(parts[0][pos : pos+3]) + buf.Write(comma) + } + buf.Truncate(buf.Len() - 1) + + if len(parts) > 1 { + buf.Write([]byte{'.'}) + buf.WriteString(parts[1]) + } + return buf.String() +} + +func commaStr(s string) string { + dotIndex := strings.Index(s, ".") + if dotIndex != -1 { + return commaStrRecursive(s[:dotIndex]) + s[dotIndex:] + } + + return commaStrRecursive(s) +} + +func commaStrRecursive(s string) string { if len(s) <= 3 { return s } - return commaString(s[:len(s)-3]) + "," + commaString(s[len(s)-3:]) + return commaStrRecursive(s[:len(s)-3]) + "," + commaStrRecursive(s[len(s)-3:]) } -func numString(value interface{}) string { - switch reflect.TypeOf(value).Kind() { - case reflect.Int, reflect.Int64, reflect.Float32, reflect.Float64: - return fmt.Sprintf("%v", value) - case reflect.String: - { - sv := fmt.Sprintf("%v", value) - if strings.Contains(sv, ".") { - _, err := strconv.ParseFloat(sv, 64) - if err == nil { - return sv - } - } else { - _, err := strconv.ParseInt(sv, 10, 64) - if err == nil { - return sv - } - } +// see https://github.com/dustin/go-humanize/blob/master/bytes.go +func parseBytes(s string, kind string) (uint64, error) { + lastDigit := 0 + hasComma := false + for _, r := range s { + if !(unicode.IsDigit(r) || r == '.' || r == ',') { + break } - default: - return "" + if r == ',' { + hasComma = true + } + lastDigit++ } - return "" + + num := s[:lastDigit] + if hasComma { + num = strings.Replace(num, ",", "", -1) + } + + f, err := strconv.ParseFloat(num, 64) + if err != nil { + return 0, err + } + + extra := strings.ToLower(strings.TrimSpace(s[lastDigit:])) + + if kind == "decimal" { + if m, ok := decimalByteMap[extra]; ok { + f *= float64(m) + if f >= math.MaxUint64 { + return 0, fmt.Errorf("too large: %v", s) + } + return uint64(f), nil + } + } else { + if m, ok := binaryByteMap[extra]; ok { + f *= float64(m) + if f >= math.MaxUint64 { + return 0, fmt.Errorf("too large: %v", s) + } + return uint64(f), nil + } + } + + return 0, fmt.Errorf("unhandled size name: %v", extra) } diff --git a/formatter/formatter_test.go b/formatter/formatter_test.go index d2d4f87..5023da7 100644 --- a/formatter/formatter_test.go +++ b/formatter/formatter_test.go @@ -1,6 +1,7 @@ package formatter import ( + "bytes" "testing" "github.com/duke-git/lancet/internal" @@ -12,12 +13,148 @@ func TestComma(t *testing.T) { assert.Equal("", Comma("", "")) assert.Equal("", Comma("aa", "")) assert.Equal("", Comma("aa.a", "")) - assert.Equal("", Comma([]int{1}, "")) assert.Equal("123", Comma("123", "")) assert.Equal("12,345", Comma("12345", "")) + assert.Equal("12,345.6789", Comma("12345.6789", "")) + assert.Equal("123,456,789,000", Comma("123456789000", "")) + assert.Equal("12,345,678.9", Comma("12345678.9", "")) assert.Equal("12,345", Comma(12345, "")) assert.Equal("$12,345", Comma(12345, "$")) assert.Equal("¥12,345", Comma(12345, "¥")) assert.Equal("12,345.6789", Comma(12345.6789, "")) + assert.Equal("12,345.6789", Comma(+12345.6789, "")) + assert.Equal("12,345,678.9", Comma(12345678.9, "")) + assert.Equal("123,456,789,000", Comma(123456789000, "")) +} + +func TestPretty(t *testing.T) { + assert := internal.NewAssert(t, "TestPretty") + + cases := []interface{}{ + "", + "abc", + 123, + []string{"a", "b", "c"}, + map[string]int{"a": 1}, + struct { + Abc int `json:"abc"` + }{Abc: 123}, + } + + expects := []string{ + "\"\"", + `"abc"`, + "123", + "[\n \"a\",\n \"b\",\n \"c\"\n]", + "{\n \"a\": 1\n}", + "{\n \"abc\": 123\n}", + } + + for i, v := range cases { + result, err := Pretty(v) + + assert.IsNil(err) + + t.Log("result -> ", result) + assert.Equal(expects[i], result) + } +} + +func TestPrettyToWriter(t *testing.T) { + assert := internal.NewAssert(t, "TestPrettyToWriter") + + type User struct { + Name string `json:"name"` + Aage uint `json:"age"` + } + user := User{Name: "King", Aage: 10000} + + expects := "{\n \"name\": \"King\",\n \"age\": 10000\n}\n" + + buf := &bytes.Buffer{} + err := PrettyToWriter(user, buf) + + assert.IsNil(err) + assert.Equal(expects, buf.String()) +} + +func TestDecimalBytes(t *testing.T) { + assert := internal.NewAssert(t, "TestDecimalBytes") + + assert.Equal("1KB", DecimalBytes(1000)) + assert.Equal("1.024KB", DecimalBytes(1024)) + assert.Equal("1.2346MB", DecimalBytes(1234567)) + assert.Equal("1.235MB", DecimalBytes(1234567, 3)) + assert.Equal("1.123GB", DecimalBytes(float64(1.123*UnitGB))) + assert.Equal("2.123TB", DecimalBytes(float64(2.123*UnitTB))) + assert.Equal("3.123PB", DecimalBytes(float64(3.123*UnitPB))) + assert.Equal("4.123EB", DecimalBytes(float64(4.123*UnitEB))) + assert.Equal("1EB", DecimalBytes(float64(1000*UnitPB))) +} + +func TestBinaryBytes(t *testing.T) { + assert := internal.NewAssert(t, "TestBinaryBytes") + + assert.Equal("1KiB", BinaryBytes(1024)) + assert.Equal("1MiB", BinaryBytes(1024*1024)) + assert.Equal("1.1774MiB", BinaryBytes(1234567)) + assert.Equal("1.18MiB", BinaryBytes(1234567, 2)) +} + +func TestParseDecimalBytes(t *testing.T) { + assert := internal.NewAssert(t, "TestParseDecimalBytes") + + cases := map[string]uint64{ + "12": uint64(12), + "12 k": uint64(12000), + "12 kb": uint64(12000), + "12kb": uint64(12000), + "12k": uint64(12000), + "12K": uint64(12000), + "12KB": uint64(12000), + "12 K": uint64(12000), + "12 KB": uint64(12000), + "12 Kb": uint64(12000), + "12 kB": uint64(12000), + "12.2 KB": uint64(12200), + } + + for k, v := range cases { + result, err := ParseDecimalBytes(k) + assert.Equal(v, result) + assert.IsNil(err) + } + + _, err := ParseDecimalBytes("12 AB") + assert.IsNotNil(err) +} + +func TestParseBinaryBytes(t *testing.T) { + assert := internal.NewAssert(t, "TestParseBinaryBytes") + + cases := map[string]uint64{ + "12": uint64(12), + "12 ki": uint64(12288), + "12 kib": uint64(12288), + "12kib": uint64(12288), + "12ki": uint64(12288), + "12KI": uint64(12288), + "12KIB": uint64(12288), + "12KiB": uint64(12288), + "12 Ki": uint64(12288), + "12 KiB": uint64(12288), + "12 Kib": uint64(12288), + "12 kiB": uint64(12288), + "12.2 KiB": uint64(12492), + } + + for k, v := range cases { + result, err := ParseBinaryBytes(k) + assert.Equal(v, result) + assert.IsNil(err) + } + + _, err := ParseDecimalBytes("12 AB") + assert.IsNotNil(err) } diff --git a/mathutil/mathutil.go b/mathutil/mathutil.go index aada9d2..1cde95b 100644 --- a/mathutil/mathutil.go +++ b/mathutil/mathutil.go @@ -90,3 +90,39 @@ func TruncRound(x float64, n int) float64 { res, _ := strconv.ParseFloat(newFloat, 64) return res } + +// AngleToRadian converts angle value to radian value. +func AngleToRadian(angle float64) float64 { + radian := angle * (math.Pi / 180) + return radian +} + +// RadianToAngle converts radian value to angle value. +func RadianToAngle(radian float64) float64 { + angle := radian * (180 / math.Pi) + return angle +} + +// PointDistance get two points distance. +func PointDistance(x1, y1, x2, y2 float64) float64 { + a := x1 - x2 + b := y1 - y2 + c := math.Pow(a, 2) + math.Pow(b, 2) + + return math.Sqrt(c) +} + +// IsPrimes checks if number is prime number. +func IsPrime(n int) bool { + if n < 2 { + return false + } + + for i := 2; i <= int(math.Sqrt(float64(n))); i++ { + if n%i == 0 { + return false + } + } + + return true +} diff --git a/mathutil/mathutil_test.go b/mathutil/mathutil_test.go index e2fd1e1..fa15e3b 100644 --- a/mathutil/mathutil_test.go +++ b/mathutil/mathutil_test.go @@ -1,6 +1,7 @@ package mathutil import ( + "math" "testing" "github.com/duke-git/lancet/internal" @@ -70,3 +71,46 @@ func TestTruncRound(t *testing.T) { assert.Equal(TruncRound(0.125, 3), float64(0.125)) assert.Equal(TruncRound(33.33333, 2), float64(33.33)) } + +func TestAngleToRadian(t *testing.T) { + assert := internal.NewAssert(t, "TestAngleToRadian") + + result1 := AngleToRadian(45) + result2 := AngleToRadian(90) + result3 := AngleToRadian(180) + + assert.Equal(0.7853981633974483, result1) + assert.Equal(1.5707963267948966, result2) + assert.Equal(3.141592653589793, result3) +} + +func TestRadianToAngle(t *testing.T) { + assert := internal.NewAssert(t, "TestAngleToRadian") + + result1 := RadianToAngle(math.Pi) + result2 := RadianToAngle(math.Pi / 2) + result3 := RadianToAngle(math.Pi / 4) + + assert.Equal(float64(180), result1) + assert.Equal(float64(90), result2) + assert.Equal(float64(45), result3) +} + +func TestPointDistance(t *testing.T) { + assert := internal.NewAssert(t, "TestPointDistance") + + result1 := PointDistance(1, 1, 4, 5) + + assert.Equal(float64(5), result1) +} + +func TestIsPrime(t *testing.T) { + assert := internal.NewAssert(t, "TestIsPrime") + + assert.Equal(false, IsPrime(-1)) + assert.Equal(false, IsPrime(0)) + assert.Equal(false, IsPrime(1)) + assert.Equal(true, IsPrime(2)) + assert.Equal(true, IsPrime(3)) + assert.Equal(false, IsPrime(4)) +} diff --git a/netutil/net.go b/netutil/net.go index f2da28f..de4772e 100644 --- a/netutil/net.go +++ b/netutil/net.go @@ -222,7 +222,6 @@ func UploadFile(filepath string, server string) (bool, error) { } // DownloadFile will download the file exist in url to a local file. -// Play: todo func DownloadFile(filepath string, url string) error { resp, err := http.Get(url) if err != nil { diff --git a/validator/validator.go b/validator/validator.go index 56837d0..930cc12 100644 --- a/validator/validator.go +++ b/validator/validator.go @@ -316,3 +316,49 @@ func IsGBK(data []byte) bool { return true } + +// IsNumberStr check if the value is number(integer, float) or not. +func IsNumber(v interface{}) bool { + return IsInt(v) || IsFloat(v) +} + +// IsFloat check if the value is float(float32, float34) or not. +func IsFloat(v interface{}) bool { + switch v.(type) { + case float32, float64: + return true + } + return false +} + +// IsInt check if the value is integer(int, unit) or not. +func IsInt(v interface{}) bool { + switch v.(type) { + case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr: + return true + } + return false +} + +// IsASCII checks if string is all ASCII char. +func IsASCII(str string) bool { + for i := 0; i < len(str); i++ { + if str[i] > unicode.MaxASCII { + return false + } + } + return true +} + +// IsPrintable checks if string is all printable chars. +func IsPrintable(str string) bool { + for _, r := range str { + if !unicode.IsPrint(r) { + if r == '\n' || r == '\r' || r == '\t' || r == '`' { + continue + } + return false + } + } + return true +} diff --git a/validator/validator_test.go b/validator/validator_test.go index bb25103..ce7fc36 100644 --- a/validator/validator_test.go +++ b/validator/validator_test.go @@ -400,3 +400,51 @@ func TestIsGBK(t *testing.T) { assert.Equal(true, IsGBK(gbkData)) assert.Equal(false, utf8.Valid(gbkData)) } + +func TestIsNumber(t *testing.T) { + assert := internal.NewAssert(t, "TestIsNumber") + + assert.Equal(false, IsNumber("")) + assert.Equal(false, IsNumber("3")) + assert.Equal(true, IsNumber(0)) + assert.Equal(true, IsNumber(0.1)) +} + +func TestIsFloat(t *testing.T) { + assert := internal.NewAssert(t, "TestIsFloat") + + assert.Equal(false, IsFloat("")) + assert.Equal(false, IsFloat("3")) + assert.Equal(false, IsFloat(0)) + assert.Equal(true, IsFloat(0.1)) +} + +func TestIsInt(t *testing.T) { + assert := internal.NewAssert(t, "TestIsInt") + + assert.Equal(false, IsInt("")) + assert.Equal(false, IsInt("3")) + assert.Equal(false, IsInt(0.1)) + assert.Equal(true, IsInt(0)) + assert.Equal(true, IsInt(-1)) +} + +func TestIsASCII(t *testing.T) { + assert := internal.NewAssert(t, "TestIsASCII") + + assert.Equal(true, IsASCII("ABC")) + assert.Equal(true, IsASCII("123")) + assert.Equal(true, IsASCII("")) + assert.Equal(false, IsASCII("😄")) + assert.Equal(false, IsASCII("你好")) +} + +func TestIsPrintable(t *testing.T) { + assert := internal.NewAssert(t, "TestIsPrintable") + + assert.Equal(true, IsPrintable("ABC")) + assert.Equal(true, IsPrintable("{id: 123}")) + assert.Equal(true, IsPrintable("")) + assert.Equal(true, IsPrintable("😄")) + assert.Equal(false, IsPrintable("\u0000")) +}