mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-17 03:02:28 +08:00
Compare commits
5 Commits
v2.1.18
...
247cf89947
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
247cf89947 | ||
|
|
d7976e31a4 | ||
|
|
5b11a8b457 | ||
|
|
d4a16534f2 | ||
|
|
8bdd46bda4 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,3 +8,4 @@ fileutil/*.link
|
|||||||
fileutil/unzip/*
|
fileutil/unzip/*
|
||||||
slice/testdata/*
|
slice/testdata/*
|
||||||
cryptor/*.pem
|
cryptor/*.pem
|
||||||
|
test
|
||||||
15
README.md
15
README.md
@@ -598,6 +598,8 @@ import "github.com/duke-git/lancet/v2/maputil"
|
|||||||
|
|
||||||
#### Function list:
|
#### Function list:
|
||||||
|
|
||||||
|
- **<big>MapTo</big>** : quick map any value to struct or any base type.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#MapTo)]
|
||||||
- **<big>ForEach</big>** : executes iteratee funcation for every key and value pair in map.
|
- **<big>ForEach</big>** : executes iteratee funcation for every key and value pair in map.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#ForEach)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#ForEach)]
|
||||||
[[play](https://go.dev/play/p/OaThj6iNVXK)]
|
[[play](https://go.dev/play/p/OaThj6iNVXK)]
|
||||||
@@ -711,12 +713,16 @@ import "github.com/duke-git/lancet/v2/mathutil"
|
|||||||
[[play](https://go.dev/play/p/akLWz0EqOSM)]
|
[[play](https://go.dev/play/p/akLWz0EqOSM)]
|
||||||
- **<big>AngleToRadian</big>** : converts angle value to radian value.
|
- **<big>AngleToRadian</big>** : converts angle value to radian value.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#AngleToRadian)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#AngleToRadian)]
|
||||||
|
[[play](https://go.dev/play/p/CIvlICqrHql)]
|
||||||
- **<big>RadianToAngle</big>** : converts radian value to angle value.
|
- **<big>RadianToAngle</big>** : converts radian value to angle value.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#RadianToAngle)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#RadianToAngle)]
|
||||||
|
[[play](https://go.dev/play/p/dQtmOTUOMgi)]
|
||||||
- **<big>PointDistance</big>** : get two points distance.
|
- **<big>PointDistance</big>** : get two points distance.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#PointDistance)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#PointDistance)]
|
||||||
|
[[play](https://go.dev/play/p/RrG4JIaziM8)]
|
||||||
- **<big>IsPrime</big>** : checks if number is prime number.
|
- **<big>IsPrime</big>** : checks if number is prime number.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#IsPrime)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil.md#IsPrime)]
|
||||||
|
[[play](https://go.dev/play/p/Rdd8UTHZJ7u)]
|
||||||
|
|
||||||
### 13. Netutil package contains functions to get net information and send http request.
|
### 13. Netutil package contains functions to get net information and send http request.
|
||||||
|
|
||||||
@@ -1150,6 +1156,8 @@ import "github.com/duke-git/lancet/v2/strutil"
|
|||||||
[[play](https://go.dev/play/p/bj7_odx3vRf)]
|
[[play](https://go.dev/play/p/bj7_odx3vRf)]
|
||||||
- **<big>RemoveNonPrintable</big>** : remove non-printable characters from a string.
|
- **<big>RemoveNonPrintable</big>** : remove non-printable characters from a string.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#RemoveNonPrintable)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/strutil.md#RemoveNonPrintable)]
|
||||||
|
[[play](https://go.dev/play/p/og47F5x_jTZ)]
|
||||||
|
|
||||||
|
|
||||||
### 19. System package contain some functions about os, runtime, shell command.
|
### 19. System package contain some functions about os, runtime, shell command.
|
||||||
|
|
||||||
@@ -1281,8 +1289,10 @@ import "github.com/duke-git/lancet/v2/validator"
|
|||||||
[[play](https://go.dev/play/p/E2nt3unlmzP)]
|
[[play](https://go.dev/play/p/E2nt3unlmzP)]
|
||||||
- **<big>IsASCII</big>** : checks if string is all ASCII char.
|
- **<big>IsASCII</big>** : checks if string is all ASCII char.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsASCII)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsASCII)]
|
||||||
|
[[play](https://go.dev/play/p/hfQNPLX0jNa)]
|
||||||
- **<big>IsPrintable</big>** : checks if string is all printable chars.
|
- **<big>IsPrintable</big>** : checks if string is all printable chars.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsPrintable)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsPrintable)]
|
||||||
|
[[play](https://go.dev/play/p/Pe1FE2gdtTP)]
|
||||||
|
|
||||||
### 21. xerror package implements helpers for errors.
|
### 21. xerror package implements helpers for errors.
|
||||||
|
|
||||||
@@ -1332,8 +1342,13 @@ import "github.com/duke-git/lancet/v2/xerror"
|
|||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#TryUnwrap)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/xerror.md#TryUnwrap)]
|
||||||
[[play](https://go.dev/play/p/acyZVkNZEeW)]
|
[[play](https://go.dev/play/p/acyZVkNZEeW)]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## How to Contribute
|
## How to Contribute
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
I really appreciate any code commits which make lancet lib powerful. Please follow the rules below to create your pull request.
|
I really appreciate any code commits which make lancet lib powerful. Please follow the rules below to create your pull request.
|
||||||
|
|
||||||
1. Fork the repository.
|
1. Fork the repository.
|
||||||
|
|||||||
@@ -597,6 +597,8 @@ import "github.com/duke-git/lancet/v2/maputil"
|
|||||||
|
|
||||||
#### 函数列表:
|
#### 函数列表:
|
||||||
|
|
||||||
|
- **<big>MapTo</big>** : 快速将map或者其他类型映射到结构体或者指定类型。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#MapTo)]
|
||||||
- **<big>ForEach</big>** : 对 map 中的每对 key 和 value 执行 iteratee 函数。
|
- **<big>ForEach</big>** : 对 map 中的每对 key 和 value 执行 iteratee 函数。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#ForEach)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#ForEach)]
|
||||||
[[play](https://go.dev/play/p/OaThj6iNVXK)]
|
[[play](https://go.dev/play/p/OaThj6iNVXK)]
|
||||||
@@ -710,12 +712,16 @@ import "github.com/duke-git/lancet/v2/mathutil"
|
|||||||
[[play](https://go.dev/play/p/akLWz0EqOSM)]
|
[[play](https://go.dev/play/p/akLWz0EqOSM)]
|
||||||
- **<big>AngleToRadian</big>** : 将角度值转为弧度值。
|
- **<big>AngleToRadian</big>** : 将角度值转为弧度值。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#AngleToRadian)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#AngleToRadian)]
|
||||||
|
[[play](https://go.dev/play/p/CIvlICqrHql)]
|
||||||
- **<big>RadianToAngle</big>** : 将弧度值转为角度值。
|
- **<big>RadianToAngle</big>** : 将弧度值转为角度值。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#RadianToAngle)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#RadianToAngle)]
|
||||||
|
[[play](https://go.dev/play/p/dQtmOTUOMgi)]
|
||||||
- **<big>PointDistance</big>** : 计算两个坐标点的距离。
|
- **<big>PointDistance</big>** : 计算两个坐标点的距离。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#PointDistance)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#PointDistance)]
|
||||||
|
[[play](https://go.dev/play/p/RrG4JIaziM8)]
|
||||||
- **<big>IsPrime</big>** : 判断质数。
|
- **<big>IsPrime</big>** : 判断质数。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#IsPrime)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/mathutil_zh-CN.md#IsPrime)]
|
||||||
|
[[play](https://go.dev/play/p/Rdd8UTHZJ7u)]
|
||||||
|
|
||||||
### 13. netutil 网络包支持获取 ip 地址,发送 http 请求。
|
### 13. netutil 网络包支持获取 ip 地址,发送 http 请求。
|
||||||
|
|
||||||
@@ -1152,6 +1158,7 @@ import "github.com/duke-git/lancet/v2/strutil"
|
|||||||
[[play](https://go.dev/play/p/bj7_odx3vRf)]
|
[[play](https://go.dev/play/p/bj7_odx3vRf)]
|
||||||
- **<big>RemoveNonPrintable</big>** : 删除字符串中不可打印的字符。
|
- **<big>RemoveNonPrintable</big>** : 删除字符串中不可打印的字符。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#RemoveNonPrintable)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/strutil_zh-CN.md#RemoveNonPrintable)]
|
||||||
|
[[play](https://go.dev/play/p/og47F5x_jTZ)]
|
||||||
|
|
||||||
### 19. system 包含 os, runtime, shell command 的相关函数。
|
### 19. system 包含 os, runtime, shell command 的相关函数。
|
||||||
|
|
||||||
@@ -1283,8 +1290,10 @@ import "github.com/duke-git/lancet/v2/validator"
|
|||||||
[[play](https://go.dev/play/p/E2nt3unlmzP)]
|
[[play](https://go.dev/play/p/E2nt3unlmzP)]
|
||||||
- **<big>IsASCII</big>** : 验证字符串全部为 ASCII 字符。
|
- **<big>IsASCII</big>** : 验证字符串全部为 ASCII 字符。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsASCII)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsASCII)]
|
||||||
|
[[play](https://go.dev/play/p/hfQNPLX0jNa)]
|
||||||
- **<big>IsPrintable</big>** : 检查字符串是否全部为可打印字符。
|
- **<big>IsPrintable</big>** : 检查字符串是否全部为可打印字符。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsPrintable)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsPrintable)]
|
||||||
|
[[play](https://go.dev/play/p/Pe1FE2gdtTP)]
|
||||||
|
|
||||||
### 21. xerror 包实现一些错误处理函数
|
### 21. xerror 包实现一些错误处理函数
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import (
|
|||||||
|
|
||||||
## Index
|
## Index
|
||||||
|
|
||||||
|
- [MapTo](#MapTo)
|
||||||
- [ForEach](#ForEach)
|
- [ForEach](#ForEach)
|
||||||
- [Filter](#Filter)
|
- [Filter](#Filter)
|
||||||
- [FilterByKeys](#FilterByKeys)
|
- [FilterByKeys](#FilterByKeys)
|
||||||
@@ -47,6 +48,64 @@ import (
|
|||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
|
||||||
|
### <span id="MapTo">MapTo</span>
|
||||||
|
|
||||||
|
<p>Rry to map any interface to struct or base type.</p>
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func MapTo(src any, dst any) error
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>Example:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/maputil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
type (
|
||||||
|
Person struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Age int `json:"age"`
|
||||||
|
Phone string `json:"phone"`
|
||||||
|
Addr Address `json:"address"`
|
||||||
|
}
|
||||||
|
|
||||||
|
Address struct {
|
||||||
|
Street string `json:"street"`
|
||||||
|
Number int `json:"number"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
personInfo := map[string]interface{}{
|
||||||
|
"name": "Nothin",
|
||||||
|
"age": 28,
|
||||||
|
"phone": "123456789",
|
||||||
|
"address": map[string]interface{}{
|
||||||
|
"street": "test",
|
||||||
|
"number": 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var p Person
|
||||||
|
err := MapTo(personInfo, &p)
|
||||||
|
|
||||||
|
fmt.Println(err)
|
||||||
|
fmt.Println(p)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// <nil>
|
||||||
|
// {Nothin 28 123456789 {test 1}}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="ForEach">ForEach</span>
|
### <span id="ForEach">ForEach</span>
|
||||||
|
|
||||||
<p>Executes iteratee funcation for every key and value pair in map.</p>
|
<p>Executes iteratee funcation for every key and value pair in map.</p>
|
||||||
@@ -133,7 +192,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="FilterByKeys">FilterByKeys</span>
|
### <span id="FilterByKeys">FilterByKeys</span>
|
||||||
|
|
||||||
<p>Iterates over map, return a new map whose keys are all given keys.</p>
|
<p>Iterates over map, return a new map whose keys are all given keys.</p>
|
||||||
@@ -172,7 +230,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="FilterByValues">FilterByValues</span>
|
### <span id="FilterByValues">FilterByValues</span>
|
||||||
|
|
||||||
<p>Iterates over map, return a new map whose values are all given values.</p>
|
<p>Iterates over map, return a new map whose values are all given values.</p>
|
||||||
@@ -211,7 +268,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="OmitBy">OmitBy</span>
|
### <span id="OmitBy">OmitBy</span>
|
||||||
|
|
||||||
<p>OmitBy is the opposite of Filter, removes all the map elements for which the predicate function returns true.</p>
|
<p>OmitBy is the opposite of Filter, removes all the map elements for which the predicate function returns true.</p>
|
||||||
@@ -253,7 +309,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="OmitByKeys">OmitByKeys</span>
|
### <span id="OmitByKeys">OmitByKeys</span>
|
||||||
|
|
||||||
<p>The opposite of FilterByKeys, extracts all the map elements which keys are not omitted.</p>
|
<p>The opposite of FilterByKeys, extracts all the map elements which keys are not omitted.</p>
|
||||||
@@ -292,7 +347,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="OmitByValues">OmitByValues</span>
|
### <span id="OmitByValues">OmitByValues</span>
|
||||||
|
|
||||||
<p>The opposite of FilterByValues. remov all elements whose value are in the give slice.</p>
|
<p>The opposite of FilterByValues. remov all elements whose value are in the give slice.</p>
|
||||||
@@ -331,7 +385,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="Intersect">Intersect</span>
|
### <span id="Intersect">Intersect</span>
|
||||||
|
|
||||||
<p>Iterates over maps, return a new map of key and value pairs in all given maps.</p>
|
<p>Iterates over maps, return a new map of key and value pairs in all given maps.</p>
|
||||||
@@ -638,7 +691,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="MapKeys">MapKeys</span>
|
### <span id="MapKeys">MapKeys</span>
|
||||||
|
|
||||||
<p>Transforms a map to other type map by manipulating it's keys.</p>
|
<p>Transforms a map to other type map by manipulating it's keys.</p>
|
||||||
@@ -717,7 +769,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="Entry">Entry</span>
|
### <span id="Entry">Entry</span>
|
||||||
|
|
||||||
<p>Transforms a map into array of key/value pairs.</p>
|
<p>Transforms a map into array of key/value pairs.</p>
|
||||||
@@ -763,7 +814,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="FromEntries">FromEntries</span>
|
### <span id="FromEntries">FromEntries</span>
|
||||||
|
|
||||||
<p>Creates a map based on a slice of key/value pairs.</p>
|
<p>Creates a map based on a slice of key/value pairs.</p>
|
||||||
@@ -841,7 +891,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="IsDisjoint">IsDisjoint</span>
|
### <span id="IsDisjoint">IsDisjoint</span>
|
||||||
|
|
||||||
<p>Checks two maps are disjoint if they have no keys in common</p>
|
<p>Checks two maps are disjoint if they have no keys in common</p>
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import (
|
|||||||
|
|
||||||
## 目录:
|
## 目录:
|
||||||
|
|
||||||
|
- [MapTo](#MapTo)
|
||||||
- [ForEach](#ForEach)
|
- [ForEach](#ForEach)
|
||||||
- [Filter](#Filter)
|
- [Filter](#Filter)
|
||||||
- [FilterByKeys](#FilterByKeys)
|
- [FilterByKeys](#FilterByKeys)
|
||||||
@@ -47,6 +48,63 @@ import (
|
|||||||
|
|
||||||
## API 文档:
|
## API 文档:
|
||||||
|
|
||||||
|
### <span id="MapTo">MapTo</span>
|
||||||
|
|
||||||
|
<p>快速将map或者其他类型映射到结构体或者指定类型。</p>
|
||||||
|
|
||||||
|
<b>函数签名:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
func MapTo(src any, dst any) error
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>示例:</b>
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/duke-git/lancet/v2/maputil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
type (
|
||||||
|
Person struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Age int `json:"age"`
|
||||||
|
Phone string `json:"phone"`
|
||||||
|
Addr Address `json:"address"`
|
||||||
|
}
|
||||||
|
|
||||||
|
Address struct {
|
||||||
|
Street string `json:"street"`
|
||||||
|
Number int `json:"number"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
personInfo := map[string]interface{}{
|
||||||
|
"name": "Nothin",
|
||||||
|
"age": 28,
|
||||||
|
"phone": "123456789",
|
||||||
|
"address": map[string]interface{}{
|
||||||
|
"street": "test",
|
||||||
|
"number": 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var p Person
|
||||||
|
err := MapTo(personInfo, &p)
|
||||||
|
|
||||||
|
fmt.Println(err)
|
||||||
|
fmt.Println(p)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// <nil>
|
||||||
|
// {Nothin 28 123456789 {test 1}}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### <span id="ForEach">ForEach</span>
|
### <span id="ForEach">ForEach</span>
|
||||||
|
|
||||||
<p>对map中的每对key和value执行iteratee函数</p>
|
<p>对map中的每对key和value执行iteratee函数</p>
|
||||||
@@ -171,7 +229,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="FilterByValues">FilterByValues</span>
|
### <span id="FilterByValues">FilterByValues</span>
|
||||||
|
|
||||||
<p>迭代map, 返回一个新map,其value都是给定的value值。</p>
|
<p>迭代map, 返回一个新map,其value都是给定的value值。</p>
|
||||||
@@ -210,7 +267,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="OmitBy">OmitBy</span>
|
### <span id="OmitBy">OmitBy</span>
|
||||||
|
|
||||||
<p>Filter的反向操作, 迭代map中的每对key和value, 删除符合predicate函数的key, value, 返回新map。</p>
|
<p>Filter的反向操作, 迭代map中的每对key和value, 删除符合predicate函数的key, value, 返回新map。</p>
|
||||||
@@ -252,7 +308,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="OmitByKeys">OmitByKeys</span>
|
### <span id="OmitByKeys">OmitByKeys</span>
|
||||||
|
|
||||||
<p>FilterByKeys的反向操作, 迭代map, 返回一个新map,其key不包括给定的key值。</p>
|
<p>FilterByKeys的反向操作, 迭代map, 返回一个新map,其key不包括给定的key值。</p>
|
||||||
@@ -291,7 +346,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="OmitByValues">OmitByValues</span>
|
### <span id="OmitByValues">OmitByValues</span>
|
||||||
|
|
||||||
<p>FilterByValues的反向操作, 迭代map, 返回一个新map,其value不包括给定的value值。</p>
|
<p>FilterByValues的反向操作, 迭代map, 返回一个新map,其value不包括给定的value值。</p>
|
||||||
@@ -632,7 +686,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="MapKeys">MapKeys</span>
|
### <span id="MapKeys">MapKeys</span>
|
||||||
|
|
||||||
<p>操作map的每个key,然后转为新的map。</p>
|
<p>操作map的每个key,然后转为新的map。</p>
|
||||||
@@ -711,7 +764,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="Entry">Entry</span>
|
### <span id="Entry">Entry</span>
|
||||||
|
|
||||||
<p>将map转换为键/值对切片。</p>
|
<p>将map转换为键/值对切片。</p>
|
||||||
@@ -757,7 +809,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### <span id="FromEntries">FromEntries</span>
|
### <span id="FromEntries">FromEntries</span>
|
||||||
|
|
||||||
<p>基于键/值对的切片创建map。</p>
|
<p>基于键/值对的切片创建map。</p>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
package internal
|
package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
@@ -44,6 +45,52 @@ func (a *Assert) NotEqual(expected, actual any) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 any) {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
// Greater check if expected is greate than actual
|
// Greater check if expected is greate than actual
|
||||||
func (a *Assert) Greater(expected, actual any) {
|
func (a *Assert) Greater(expected, actual any) {
|
||||||
if compare(expected, actual) != compareGreater {
|
if compare(expected, actual) != compareGreater {
|
||||||
|
|||||||
@@ -397,3 +397,39 @@ func ExampleOmitByValues() {
|
|||||||
// Output:
|
// Output:
|
||||||
// map[a:1 b:2 c:3]
|
// map[a:1 b:2 c:3]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExampleMapTo() {
|
||||||
|
type (
|
||||||
|
Person struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Age int `json:"age"`
|
||||||
|
Phone string `json:"phone"`
|
||||||
|
Addr Address `json:"address"`
|
||||||
|
}
|
||||||
|
|
||||||
|
Address struct {
|
||||||
|
Street string `json:"street"`
|
||||||
|
Number int `json:"number"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
personInfo := map[string]interface{}{
|
||||||
|
"name": "Nothin",
|
||||||
|
"age": 28,
|
||||||
|
"phone": "123456789",
|
||||||
|
"address": map[string]interface{}{
|
||||||
|
"street": "test",
|
||||||
|
"number": 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var p Person
|
||||||
|
err := MapTo(personInfo, &p)
|
||||||
|
|
||||||
|
fmt.Println(err)
|
||||||
|
fmt.Println(p)
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// <nil>
|
||||||
|
// {Nothin 28 123456789 {test 1}}
|
||||||
|
}
|
||||||
|
|||||||
180
maputil/typemap.go
Normal file
180
maputil/typemap.go
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
package maputil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var mapHandlers = map[reflect.Kind]func(reflect.Value, reflect.Value) error{
|
||||||
|
reflect.String: convertNormal,
|
||||||
|
reflect.Int: convertNormal,
|
||||||
|
reflect.Int16: convertNormal,
|
||||||
|
reflect.Int32: convertNormal,
|
||||||
|
reflect.Int64: convertNormal,
|
||||||
|
reflect.Uint: convertNormal,
|
||||||
|
reflect.Uint16: convertNormal,
|
||||||
|
reflect.Uint32: convertNormal,
|
||||||
|
reflect.Uint64: convertNormal,
|
||||||
|
reflect.Float32: convertNormal,
|
||||||
|
reflect.Float64: convertNormal,
|
||||||
|
reflect.Uint8: convertNormal,
|
||||||
|
reflect.Int8: convertNormal,
|
||||||
|
reflect.Struct: convertNormal,
|
||||||
|
reflect.Complex64: convertNormal,
|
||||||
|
reflect.Complex128: convertNormal,
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = func() struct{} {
|
||||||
|
mapHandlers[reflect.Map] = convertMap
|
||||||
|
mapHandlers[reflect.Array] = convertSlice
|
||||||
|
mapHandlers[reflect.Slice] = convertSlice
|
||||||
|
return struct{}{}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// MapTo try to map any interface to struct or base type
|
||||||
|
/*
|
||||||
|
Eg:
|
||||||
|
v := map[string]interface{}{
|
||||||
|
"service":map[string]interface{}{
|
||||||
|
"ip":"127.0.0.1",
|
||||||
|
"port":1234,
|
||||||
|
},
|
||||||
|
version:"v1.0.01"
|
||||||
|
}
|
||||||
|
|
||||||
|
type Target struct {
|
||||||
|
Service struct {
|
||||||
|
Ip string `json:"ip"`
|
||||||
|
Port int `json:"port"`
|
||||||
|
} `json:"service"`
|
||||||
|
Ver string `json:"version"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var dist Target
|
||||||
|
if err := typemap.MapTo(v,&dist); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println(dist)
|
||||||
|
|
||||||
|
*/
|
||||||
|
func MapTo(src any, dst any) error {
|
||||||
|
|
||||||
|
dstRef := reflect.ValueOf(dst)
|
||||||
|
if dstRef.Kind() != reflect.Ptr {
|
||||||
|
return fmt.Errorf("dst is not ptr")
|
||||||
|
}
|
||||||
|
|
||||||
|
dstRef = reflect.Indirect(dstRef)
|
||||||
|
|
||||||
|
srcRef := reflect.ValueOf(src)
|
||||||
|
if srcRef.Kind() == reflect.Ptr || srcRef.Kind() == reflect.Interface {
|
||||||
|
srcRef = srcRef.Elem()
|
||||||
|
}
|
||||||
|
if f, ok := mapHandlers[srcRef.Kind()]; ok {
|
||||||
|
return f(srcRef, dstRef)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("no implemented:%s", srcRef.Type())
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertNormal(src reflect.Value, dst reflect.Value) error {
|
||||||
|
if dst.CanSet() {
|
||||||
|
if src.Type() == dst.Type() {
|
||||||
|
dst.Set(src)
|
||||||
|
} else if src.CanConvert(dst.Type()) {
|
||||||
|
dst.Set(src.Convert(dst.Type()))
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("can not convert:%s:%s", src.Type().String(), dst.Type().String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertSlice(src reflect.Value, dst reflect.Value) error {
|
||||||
|
if dst.Kind() != reflect.Array && dst.Kind() != reflect.Slice {
|
||||||
|
return fmt.Errorf("error type:%s", dst.Type().String())
|
||||||
|
}
|
||||||
|
l := src.Len()
|
||||||
|
target := reflect.MakeSlice(dst.Type(), l, l)
|
||||||
|
if dst.CanSet() {
|
||||||
|
dst.Set(target)
|
||||||
|
}
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
srcValue := src.Index(i)
|
||||||
|
if srcValue.Kind() == reflect.Ptr || srcValue.Kind() == reflect.Interface {
|
||||||
|
srcValue = srcValue.Elem()
|
||||||
|
}
|
||||||
|
if f, ok := mapHandlers[srcValue.Kind()]; ok {
|
||||||
|
err := f(srcValue, dst.Index(i))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertMap(src reflect.Value, dst reflect.Value) error {
|
||||||
|
if src.Kind() != reflect.Map || dst.Kind() != reflect.Struct {
|
||||||
|
if src.Kind() == reflect.Interface {
|
||||||
|
return convertMap(src.Elem(), dst)
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("src or dst type error,%s,%s", src.Type().String(), dst.Type().String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dstType := dst.Type()
|
||||||
|
num := dstType.NumField()
|
||||||
|
exist := map[string]int{}
|
||||||
|
for i := 0; i < num; i++ {
|
||||||
|
k := dstType.Field(i).Tag.Get("json")
|
||||||
|
if k == "" {
|
||||||
|
k = dstType.Field(i).Name
|
||||||
|
}
|
||||||
|
if strings.Contains(k, ",") {
|
||||||
|
taglist := strings.Split(k, ",")
|
||||||
|
if taglist[0] == "" {
|
||||||
|
|
||||||
|
k = dstType.Field(i).Name
|
||||||
|
} else {
|
||||||
|
k = taglist[0]
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
exist[k] = i
|
||||||
|
}
|
||||||
|
|
||||||
|
keys := src.MapKeys()
|
||||||
|
for _, key := range keys {
|
||||||
|
if index, ok := exist[key.String()]; ok {
|
||||||
|
v := dst.Field(index)
|
||||||
|
if v.Kind() == reflect.Struct {
|
||||||
|
err := convertMap(src.MapIndex(key), v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if v.CanSet() {
|
||||||
|
if v.Type() == src.MapIndex(key).Elem().Type() {
|
||||||
|
v.Set(src.MapIndex(key).Elem())
|
||||||
|
} else if src.MapIndex(key).Elem().CanConvert(v.Type()) {
|
||||||
|
v.Set(src.MapIndex(key).Elem().Convert(v.Type()))
|
||||||
|
} else if f, ok := mapHandlers[src.MapIndex(key).Elem().Kind()]; ok && f != nil {
|
||||||
|
err := f(src.MapIndex(key).Elem(), v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("error type:d(%s)s(%s)", v.Type(), src.Type())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
111
maputil/typemap_test.go
Normal file
111
maputil/typemap_test.go
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
package maputil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/v2/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
Person struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Age int `json:"age"`
|
||||||
|
Phone string `json:"phone"`
|
||||||
|
Addr Address `json:"address"`
|
||||||
|
}
|
||||||
|
|
||||||
|
Address struct {
|
||||||
|
Street string `json:"street"`
|
||||||
|
Number int `json:"number"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestStructType(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestStructType")
|
||||||
|
|
||||||
|
src := map[string]interface{}{
|
||||||
|
"name": "Nothin",
|
||||||
|
"age": 28,
|
||||||
|
"phone": "123456789",
|
||||||
|
"address": map[string]interface{}{
|
||||||
|
"street": "test",
|
||||||
|
"number": 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var p Person
|
||||||
|
err := MapTo(src, &p)
|
||||||
|
assert.IsNil(err)
|
||||||
|
assert.Equal(src["name"], p.Name)
|
||||||
|
assert.Equal(src["age"], p.Age)
|
||||||
|
assert.Equal(src["phone"], p.Phone)
|
||||||
|
assert.Equal("test", p.Addr.Street)
|
||||||
|
assert.Equal(1, p.Addr.Number)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBaseType(t *testing.T) {
|
||||||
|
assert := internal.NewAssert(t, "TestBaseType")
|
||||||
|
|
||||||
|
tc := map[string]interface{}{
|
||||||
|
"i32": -32,
|
||||||
|
"i8": -8,
|
||||||
|
"i16": -16,
|
||||||
|
"i64": -64,
|
||||||
|
"i": -1,
|
||||||
|
"u32": 32,
|
||||||
|
"u8": 8,
|
||||||
|
"u16": 16,
|
||||||
|
"u64": 64,
|
||||||
|
"u": 1,
|
||||||
|
"tf": true,
|
||||||
|
"f32": 1.32,
|
||||||
|
"f64": 1.64,
|
||||||
|
"str": "hello mapto",
|
||||||
|
"complex": 1 + 3i,
|
||||||
|
}
|
||||||
|
|
||||||
|
type BaseType struct {
|
||||||
|
I int `json:"i"`
|
||||||
|
I8 int8 `json:"i8"`
|
||||||
|
I16 int16 `json:"i16"`
|
||||||
|
I32 int32 `json:"i32"`
|
||||||
|
I64 int64 `json:"i64"`
|
||||||
|
U uint `json:"u"`
|
||||||
|
U8 uint8 `json:"u8"`
|
||||||
|
U16 uint16 `json:"u16"`
|
||||||
|
U32 uint32 `json:"u32"`
|
||||||
|
U64 uint64 `json:"u64"`
|
||||||
|
F32 float32 `json:"f32"`
|
||||||
|
F64 float64 `json:"f64"`
|
||||||
|
Tf bool `json:"tf"`
|
||||||
|
Str string `json:"str"`
|
||||||
|
Comp complex128 `json:"complex"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var dist BaseType
|
||||||
|
err := MapTo(tc, &dist)
|
||||||
|
assert.IsNil(err)
|
||||||
|
|
||||||
|
var number float64
|
||||||
|
|
||||||
|
MapTo(tc["i"], &number)
|
||||||
|
assert.EqualValues(-1, number)
|
||||||
|
MapTo(tc["i8"], &number)
|
||||||
|
assert.EqualValues(-8, number)
|
||||||
|
MapTo(tc["i16"], &number)
|
||||||
|
assert.EqualValues(-16, number)
|
||||||
|
MapTo(tc["i32"], &number)
|
||||||
|
assert.EqualValues(-32, number)
|
||||||
|
MapTo(tc["i64"], &number)
|
||||||
|
assert.EqualValues(-64, number)
|
||||||
|
MapTo(tc["u"], &number)
|
||||||
|
assert.EqualValues(1, number)
|
||||||
|
MapTo(tc["u8"], &number)
|
||||||
|
assert.EqualValues(8, number)
|
||||||
|
MapTo(tc["u16"], &number)
|
||||||
|
assert.EqualValues(16, number)
|
||||||
|
MapTo(tc["u32"], &number)
|
||||||
|
assert.EqualValues(32, number)
|
||||||
|
MapTo(tc["u64"], &number)
|
||||||
|
assert.EqualValues(64, number)
|
||||||
|
}
|
||||||
@@ -218,21 +218,21 @@ func RangeWithStep[T constraints.Integer | constraints.Float](start, end, step T
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AngleToRadian converts angle value to radian value.
|
// AngleToRadian converts angle value to radian value.
|
||||||
// Play: todo
|
// Play: https://go.dev/play/p/CIvlICqrHql
|
||||||
func AngleToRadian(angle float64) float64 {
|
func AngleToRadian(angle float64) float64 {
|
||||||
radian := angle * (math.Pi / 180)
|
radian := angle * (math.Pi / 180)
|
||||||
return radian
|
return radian
|
||||||
}
|
}
|
||||||
|
|
||||||
// RadianToAngle converts radian value to angle value.
|
// RadianToAngle converts radian value to angle value.
|
||||||
// Play: todo
|
// Play: https://go.dev/play/p/dQtmOTUOMgi
|
||||||
func RadianToAngle(radian float64) float64 {
|
func RadianToAngle(radian float64) float64 {
|
||||||
angle := radian * (180 / math.Pi)
|
angle := radian * (180 / math.Pi)
|
||||||
return angle
|
return angle
|
||||||
}
|
}
|
||||||
|
|
||||||
// PointDistance get two points distance.
|
// PointDistance get two points distance.
|
||||||
// Play: todo
|
// Play: https://go.dev/play/p/RrG4JIaziM8
|
||||||
func PointDistance(x1, y1, x2, y2 float64) float64 {
|
func PointDistance(x1, y1, x2, y2 float64) float64 {
|
||||||
a := x1 - x2
|
a := x1 - x2
|
||||||
b := y1 - y2
|
b := y1 - y2
|
||||||
@@ -242,7 +242,7 @@ func PointDistance(x1, y1, x2, y2 float64) float64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IsPrimes checks if number is prime number.
|
// IsPrimes checks if number is prime number.
|
||||||
// Play: todo
|
// Play: https://go.dev/play/p/Rdd8UTHZJ7u
|
||||||
func IsPrime(n int) bool {
|
func IsPrime(n int) bool {
|
||||||
if n < 2 {
|
if n < 2 {
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -362,7 +362,7 @@ func WordCount(s string) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RemoveNonPrintable remove non-printable characters from a string.
|
// RemoveNonPrintable remove non-printable characters from a string.
|
||||||
// Play: todo
|
// Play: https://go.dev/play/p/og47F5x_jTZ
|
||||||
func RemoveNonPrintable(str string) string {
|
func RemoveNonPrintable(str string) string {
|
||||||
result := strings.Map(func(r rune) rune {
|
result := strings.Map(func(r rune) rune {
|
||||||
if unicode.IsPrint(r) {
|
if unicode.IsPrint(r) {
|
||||||
|
|||||||
12
system/os.go
12
system/os.go
@@ -15,6 +15,10 @@ import (
|
|||||||
"golang.org/x/text/encoding/simplifiedchinese"
|
"golang.org/x/text/encoding/simplifiedchinese"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
Option func(*exec.Cmd)
|
||||||
|
)
|
||||||
|
|
||||||
// IsWindows check if current os is windows.
|
// IsWindows check if current os is windows.
|
||||||
// Play: https://go.dev/play/p/XzJULbzmf9m
|
// Play: https://go.dev/play/p/XzJULbzmf9m
|
||||||
func IsWindows() bool {
|
func IsWindows() bool {
|
||||||
@@ -66,7 +70,7 @@ func CompareOsEnv(key, comparedEnv string) bool {
|
|||||||
// in linux, use /bin/bash -c to execute command
|
// in linux, use /bin/bash -c to execute command
|
||||||
// in windows, use powershell.exe to execute command
|
// in windows, use powershell.exe to execute command
|
||||||
// Play: https://go.dev/play/p/n-2fLyZef-4
|
// Play: https://go.dev/play/p/n-2fLyZef-4
|
||||||
func ExecCommand(command string) (stdout, stderr string, err error) {
|
func ExecCommand(command string, opts ...Option) (stdout, stderr string, err error) {
|
||||||
var out bytes.Buffer
|
var out bytes.Buffer
|
||||||
var errOut bytes.Buffer
|
var errOut bytes.Buffer
|
||||||
|
|
||||||
@@ -74,6 +78,12 @@ func ExecCommand(command string) (stdout, stderr string, err error) {
|
|||||||
if IsWindows() {
|
if IsWindows() {
|
||||||
cmd = exec.Command("powershell.exe", command)
|
cmd = exec.Command("powershell.exe", command)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, opt := range opts {
|
||||||
|
if opt != nil {
|
||||||
|
opt(cmd)
|
||||||
|
}
|
||||||
|
}
|
||||||
cmd.Stdout = &out
|
cmd.Stdout = &out
|
||||||
cmd.Stderr = &errOut
|
cmd.Stderr = &errOut
|
||||||
|
|
||||||
|
|||||||
18
system/os_linux.go
Normal file
18
system/os_linux.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os/exec"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func WithForeground() Option {
|
||||||
|
return func(c *exec.Cmd) {
|
||||||
|
if c.SysProcAttr == nil {
|
||||||
|
c.SysProcAttr = &syscall.SysProcAttr{
|
||||||
|
Foreground: true,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c.SysProcAttr.Foreground = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
system/os_windows.go
Normal file
18
system/os_windows.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os/exec"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func WithWinHide() Option {
|
||||||
|
return func(c *exec.Cmd) {
|
||||||
|
if c.SysProcAttr == nil {
|
||||||
|
c.SysProcAttr = &syscall.SysProcAttr{
|
||||||
|
HideWindow: true,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c.SysProcAttr.HideWindow = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -59,7 +59,7 @@ func IsAllLower(str string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IsASCII checks if string is all ASCII char.
|
// IsASCII checks if string is all ASCII char.
|
||||||
// Play: todo
|
// Play: https://go.dev/play/p/hfQNPLX0jNa
|
||||||
func IsASCII(str string) bool {
|
func IsASCII(str string) bool {
|
||||||
for i := 0; i < len(str); i++ {
|
for i := 0; i < len(str); i++ {
|
||||||
if str[i] > unicode.MaxASCII {
|
if str[i] > unicode.MaxASCII {
|
||||||
@@ -70,7 +70,7 @@ func IsASCII(str string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IsPrintable checks if string is all printable chars.
|
// IsPrintable checks if string is all printable chars.
|
||||||
// Play: todo
|
// Play: https://go.dev/play/p/Pe1FE2gdtTP
|
||||||
func IsPrintable(str string) bool {
|
func IsPrintable(str string) bool {
|
||||||
for _, r := range str {
|
for _, r := range str {
|
||||||
if !unicode.IsPrint(r) {
|
if !unicode.IsPrint(r) {
|
||||||
|
|||||||
Reference in New Issue
Block a user