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

Compare commits

...

7 Commits

Author SHA1 Message Date
dudaodong
c3fad62d8c doc: update stream package document 2023-04-17 13:53:47 +08:00
dudaodong
a8a96be21b doc: update doc for new added functions 2023-04-17 11:34:17 +08:00
dudaodong
8e297769b2 fix: fix example comment of MapTo function 2023-04-17 11:06:03 +08:00
dudaodong
98cdf1c040 Merge branch 'main' into v2 2023-04-17 10:38:28 +08:00
dudaodong
d7976e31a4 refactor: move typemap.go to maputil package and add document for it 2023-04-17 10:37:56 +08:00
dudaodong
5b11a8b457 refactor: move typemap.go to maputil package and add document for it 2023-04-17 10:36:59 +08:00
Nothin
d4a16534f2 add typemap (#85)
* [FEATURE] typemap, quick map any type to specified type

* [DOC] add more test case

---------

Co-authored-by: zhijian.chen <zhijian.chen@longsys.com>
2023-04-17 10:04:31 +08:00
15 changed files with 744 additions and 50 deletions

3
.gitignore vendored
View File

@@ -7,4 +7,5 @@ fileutil/*.zip
fileutil/*.link
fileutil/unzip/*
slice/testdata/*
cryptor/*.pem
cryptor/*.pem
test

125
README.md
View File

@@ -541,6 +541,8 @@ import "github.com/duke-git/lancet/v2/fileutil"
- **<big>UnZip</big>** : unzip the zip file and save it to dest path.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#UnZip)]
[[play](https://go.dev/play/p/g0w34kS7B8m)]
- **<big>CurrentPath</big>** : return current absolute path.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/fileutil.md#CurrentPath)]
### 9. Formatter contains some functions for data formatting.
@@ -553,6 +555,18 @@ import "github.com/duke-git/lancet/v2/formatter"
- **<big>Comma</big>** : add comma to a number value by every 3 numbers from right, ahead by symbol char.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/formatter.md#Comma)]
[[play](https://go.dev/play/p/eRD5k2vzUVX)]
- **<big>Pretty</big>** : pretty print data to JSON string.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/formatter.md#Pretty)]
- **<big>PrettyToWriter</big>** : pretty encode data to writer.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/formatter.md#PrettyToWriter)]
- **<big>DecimalBytes</big>** : returns a human readable byte size under decimal standard (base 1000).
[[doc](https://github.com/duke-git/lancet/blob/main/docs/formatter.md#DecimalBytes)]
- **<big>BinaryBytes</big>** : returns a human-readable byte size under binary standard (base 1024).
[[doc](https://github.com/duke-git/lancet/blob/main/docs/formatter.md#BinaryBytes)]
- **<big>ParseDecimalBytes</big>** : return the human readable bytes size string into the amount it represents(base 1000).
[[doc](https://github.com/duke-git/lancet/blob/main/docs/formatter.md#ParseDecimalBytes)]
- **<big>ParseBinaryBytes</big>** : return the human readable bytes size string into the amount it represents(base 1024).
[[doc](https://github.com/duke-git/lancet/blob/main/docs/formatter.md#ParseBinaryBytes)]
### 10. Function package can control the flow of function execution and support part of functional programming
@@ -598,6 +612,8 @@ import "github.com/duke-git/lancet/v2/maputil"
#### 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.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/maputil.md#ForEach)]
[[play](https://go.dev/play/p/OaThj6iNVXK)]
@@ -970,8 +986,12 @@ import "github.com/duke-git/lancet/v2/slice"
- **<big>Reverse</big>** : return slice of element order is reversed to the given slice.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Reverse)]
[[play](https://go.dev/play/p/8uI8f1lwNrQ)]
- **<big>Reduce</big>** : creates an slice of values by running each element of slice thru iteratee function.
- **<big>Reduce<sup>deprecated</sup></big>** : creates an slice of values by running each element of slice thru iteratee function.(Deprecated: use ReduceBy)
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Reduce)]
- **<big>ReduceBy</big>** : produces a value from slice by accumulating the result of each element as passed through the reducer function.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ReduceBy)]
- **<big>ReduceRight</big>** : ReduceRight is like ReduceBy, but it iterates over elements of slice from right to left.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ReduceRight)]
[[play](https://go.dev/play/p/_RfXJJWIsIm)]
- **<big>Replace</big>** : returns a copy of the slice with the first n non-overlapping instances of old replaced by new.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Replace)]
@@ -1043,7 +1063,91 @@ import "github.com/duke-git/lancet/v2/slice"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice.md#KeyBy)]
[[play](https://go.dev/play/p/uXod2LWD1Kg)]
### 17. Structs package provides several high level functions to manipulate struct, tag, and field.
### 17. Stream package implements a sequence of elements supporting sequential and operations. this package is an experiment to explore if stream in go can work as the way java does. its function is very limited.
```go
import "github.com/duke-git/lancet/v2/stream"
```
#### Function list:
- **<big>Of</big>** : creates a stream whose elements are the specified values.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#Of)]
[[play](https://go.dev/play/p/jI6_iZZuVFE)]
- **<big>FromSlice</big>** : creates a stream from slice.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#FromSlice)]
[[play](https://go.dev/play/p/wywTO0XZtI4)]
- **<big>FromChannel</big>** : creates a stream from channel.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#FromChannel)]
[[play](https://go.dev/play/p/9TZYugGMhXZ)]
- **<big>FromRange</big>** : creates a number stream from start to end. both start and end are included. [start, end]
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#FromRange)]
[[play](https://go.dev/play/p/9Ex1-zcg-B-)]
- **<big>Generate</big>** : creates a stream where each element is generated by the provided generater function.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#Generate)]
[[play](https://go.dev/play/p/rkOWL1yA3j9)]
- **<big>Concat</big>** : creates a lazily concatenated stream whose elements are all the elements of the first stream followed by all the elements of the second stream.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#Concat)]
[[play](https://go.dev/play/p/HM4OlYk_OUC)]
- **<big>Distinct</big>** : creates returns a stream that removes the duplicated items.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#Distinct)]
[[play](https://go.dev/play/p/eGkOSrm64cB)]
- **<big>Filter</big>** : returns a stream consisting of the elements of this stream that match the given predicate.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#Filter)]
[[play](https://go.dev/play/p/MFlSANo-buc)]
- **<big>Map</big>** : returns a stream consisting of the elements of this stream that apply the given function to elements of stream.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#Map)]
[[play](https://go.dev/play/p/OtNQUImdYko)]
- **<big>Peek</big>** : returns a stream consisting of the elements of this stream, additionally performing the provided action on each element as elements are consumed from the resulting stream.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#Peek)]
[[play](https://go.dev/play/p/u1VNzHs6cb2)]
- **<big>Skip</big>** : returns a stream consisting of the remaining elements of this stream after discarding the first n elements of the stream.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#Skip)]
[[play](https://go.dev/play/p/fNdHbqjahum)]
- **<big>Limit</big>** : returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#Limit)]
[[play](https://go.dev/play/p/qsO4aniDcGf)]
- **<big>Reverse</big>** : returns a stream whose elements are reverse order of given stream.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#Reverse)]
[[play](https://go.dev/play/p/A8_zkJnLHm4)]
- **<big>Range</big>** : returns a stream whose elements are in the range from start(included) to end(excluded) original stream.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#Range)]
[[play](https://go.dev/play/p/indZY5V2f4j)]
- **<big>Sorted</big>** : returns a stream consisting of the elements of this stream, sorted according to the provided less function.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#Sorted)]
[[play](https://go.dev/play/p/XXtng5uonFj)]
- **<big>ForEach</big>** : performs an action for each element of this stream.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#ForEach)]
[[play](https://go.dev/play/p/Dsm0fPqcidk)]
- **<big>Reduce</big>** : performs a reduction on the elements of this stream, using an associative accumulation function, and returns an Optional describing the reduced value, if any.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#Reduce)]
[[play](https://go.dev/play/p/6uzZjq_DJLU)]
- **<big>FindFirst</big>** : returns the first element of this stream and true, or zero value and false if the stream is empty.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#FindFirst)]
[[play](https://go.dev/play/p/9xEf0-6C1e3)]
- **<big>Max</big>** : returns the maximum element of this stream according to the provided less function. less fuction: a > b
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#Max)]
[[play](https://go.dev/play/p/fm-1KOPtGzn)]
- **<big>Min</big>** : returns the minimum element of this stream according to the provided less function. less fuction: a < b
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#Min)]
[[play](https://go.dev/play/p/vZfIDgGNRe_0)]
- **<big>AllMatch</big>** : returns whether all elements of this stream match the provided predicate.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#AllMatch)]
[[play](https://go.dev/play/p/V5TBpVRs-Cx)]
- **<big>AnyMatch</big>** : returns whether any elements of this stream match the provided predicate.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#AnyMatch)]
[[play](https://go.dev/play/p/PTCnWn4OxSn)]
- **<big>NoneMatch</big>** : returns whether no elements of this stream match the provided predicate.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#NoneMatch)]
[[play](https://go.dev/play/p/iWS64pL1oo3)]
- **<big>Count</big>** : returns the count of elements in the stream.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#Count)]
[[play](https://go.dev/play/p/r3koY6y_Xo-)]
- **<big>ToSlice</big>** : returns the elements in the stream.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream.md#ToSlice)]
[[play](https://go.dev/play/p/jI6_iZZuVFE)]
### 18. Structs package provides several high level functions to manipulate struct, tag, and field.
```go
import "github.com/duke-git/lancet/v2/structs"
@@ -1076,7 +1180,7 @@ import "github.com/duke-git/lancet/v2/structs"
- **<big>IsSlice</big>** : check if the field is a slice
[[doc](https://github.com/duke-git/lancet/blob/main/docs/structs/field.md#IsSlice)]
### 18. Strutil package contains some functions to manipulate string.
### 19. Strutil package contains some functions to manipulate string.
```go
import "github.com/duke-git/lancet/v2/strutil"
@@ -1156,8 +1260,7 @@ import "github.com/duke-git/lancet/v2/strutil"
[[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.
### 20. System package contain some functions about os, runtime, shell command.
```go
import "github.com/duke-git/lancet/v2/system"
@@ -1193,7 +1296,7 @@ import "github.com/duke-git/lancet/v2/system"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/system.md#GetOsBits)]
[[play](https://go.dev/play/p/ml-_XH3gJbW)]
### 20. Validator package contains some functions for data validation.
### 21. Validator package contains some functions for data validation.
```go
import "github.com/duke-git/lancet/v2/validator"
@@ -1246,9 +1349,13 @@ import "github.com/duke-git/lancet/v2/validator"
- **<big>IsEmptyString</big>** : check if the string is empty.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsEmptyString)]
[[play](https://go.dev/play/p/dpzgUjFnBCX)]
- **<big>IsFloat</big>** : check if the value is float(float32, float34) or not.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsFloat)]
- **<big>IsFloatStr</big>** : check if the string can convert to a float.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator.md#LOYwS_Oyl7U)]
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsFloatStr)]
[[play](https://go.dev/play/p/LOYwS_Oyl7U)]
- **<big>IsNumber</big>** : check if the value is number(integer, float) or not.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsNumber)]
- **<big>IsNumberStr</big>** : check if the string can convert to a number.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsNumberStr)]
[[play](https://go.dev/play/p/LzaKocSV79u)]
@@ -1258,6 +1365,8 @@ import "github.com/duke-git/lancet/v2/validator"
- **<big>IsRegexMatch</big>** : check if the string match the regexp.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsRegexMatch)]
[[play](https://go.dev/play/p/z_XeZo_litG)]
- **<big>IsInt</big>** : check if the string can convert to a number.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsInt)]
- **<big>IsIntStr</big>** : check if the string can convert to a integer.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator.md#IsIntStr)]
[[play](https://go.dev/play/p/jQRtFv-a0Rk)]
@@ -1292,7 +1401,7 @@ import "github.com/duke-git/lancet/v2/validator"
[[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.
### 22. xerror package implements helpers for errors.
```go
import "github.com/duke-git/lancet/v2/xerror"

View File

@@ -540,6 +540,8 @@ import "github.com/duke-git/lancet/v2/fileutil"
- **<big>UnZip</big>** : zip 解压缩文件并保存在目录中。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#UnZip)]
[[play](https://go.dev/play/p/g0w34kS7B8m)]
- **<big>CurrentPath</big>** : 返回当前位置的绝对路径。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/fileutil_zh-CN.md#CurrentPath)]
### 9. formatter 格式化器包含一些数据格式化处理方法。
@@ -552,6 +554,18 @@ import "github.com/duke-git/lancet/v2/formatter"
- **<big>Comma</big>** : 用逗号每隔 3 位分割数字/字符串,支持前缀添加符号。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/formatter_zh-CN.md#Comma)]
[[play](https://go.dev/play/p/eRD5k2vzUVX)]
- **<big>Pretty</big>** : 返回 pretty JSON 字符串。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/formatter_zh-CN.md#Pretty)]
- **<big>PrettyToWriter</big>** : Pretty encode 数据到 writer。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/formatter_zh-CN.md#PrettyToWriter)]
- **<big>DecimalBytes</big>** : 返回十进制标准(以 1000 为基数下的可读字节单位字符串。precision 参数指定小数点后的位数,默认为 4。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/formatter_zh-CN.md#DecimalBytes)]
- **<big>BinaryBytes</big>** : 返回 binary 标准(以 1024 为基数下的可读字节单位字符串。precision 参数指定小数点后的位数,默认为 4。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/formatter_zh-CN.md#BinaryBytes)]
- **<big>ParseDecimalBytes</big>** : 将字节单位字符串转换成其所表示的字节数(以 1000 为基数)。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/formatter_zh-CN.md#ParseDecimalBytes)]
- **<big>ParseBinaryBytes</big>** : 将字节单位字符串转换成其所表示的字节数(以 1024 为基数)。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/formatter_zh-CN.md#ParseBinaryBytes)]
### 10. function 函数包控制函数执行流程,包含部分函数式编程。
@@ -597,6 +611,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 函数。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/maputil_zh-CN.md#ForEach)]
[[play](https://go.dev/play/p/OaThj6iNVXK)]
@@ -969,9 +985,13 @@ import "github.com/duke-git/lancet/v2/slice"
- **<big>Reverse</big>** : 反转切片中的元素顺序。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Reverse)]
[[play](https://go.dev/play/p/8uI8f1lwNrQ)]
- **<big>Reduce</big>** : 将切片中的元素依次运行 iteratee 函数,返回运行结果。
- **<big>Reduce<sup>deprecated</sup></big>** : 将切片中的元素依次运行 iteratee 函数,返回运行结果。(废弃:建议使用 ReduceBy)
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Reduce)]
[[play](https://go.dev/play/p/_RfXJJWIsIm)]
- **<big>ReduceBy</big>** : 对切片元素执行 reduce 操作。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ReduceBy)]
- **<big>ReduceRight</big>** : 类似 ReduceBy 操作,迭代切片元素顺序从右至左。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ReduceRight)]
- **<big>Replace</big>** : 返回切片的副本,其中前 n 个不重叠的 old 替换为 new。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Replace)]
[[play](https://go.dev/play/p/P5mZp7IhOFo)]
@@ -1042,7 +1062,91 @@ import "github.com/duke-git/lancet/v2/slice"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#KeyBy)]
[[play](https://go.dev/play/p/uXod2LWD1Kg)]
### 17. structs 提供操作 struct, tag, field 的相关函数
### 17. Stream 流,该包仅验证简单的 stream 实现,功能有限
```go
import "github.com/duke-git/lancet/v2/stream"
```
#### Function list:
- **<big>Of</big>** : 创建元素为指定值的 stream。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#Of)]
[[play](https://go.dev/play/p/jI6_iZZuVFE)]
- **<big>FromSlice</big>** : 从切片创建 stream。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#FromSlice)]
[[play](https://go.dev/play/p/wywTO0XZtI4)]
- **<big>FromChannel</big>** : 从通道创建 stream。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#FromChannel)]
[[play](https://go.dev/play/p/9TZYugGMhXZ)]
- **<big>FromRange</big>** : 指定一个数字范围创建 stream, 范围两端点值都包括在内。. [start, end]
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#FromRange)]
[[play](https://go.dev/play/p/9Ex1-zcg-B-)]
- **<big>Generate</big>** : 创建一个 stream其中每个元素都由提供的生成器函数生成。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#Generate)]
[[play](https://go.dev/play/p/rkOWL1yA3j9)]
- **<big>Concat</big>** : 创建一个延迟连接 stream其元素是第一个 stream 的所有元素,后跟第二个 stream 的全部元素。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#Concat)]
[[play](https://go.dev/play/p/HM4OlYk_OUC)]
- **<big>Distinct</big>** : 创建并返回一个 stream用于删除重复的项。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#Distinct)]
[[play](https://go.dev/play/p/eGkOSrm64cB)]
- **<big>Filter</big>** : 返回一个通过判定函数的 stream。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#Filter)]
[[play](https://go.dev/play/p/MFlSANo-buc)]
- **<big>Map</big>** : 返回一个 stream该 stream 由将给定函数应用于源 stream 元素的元素组成。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#Map)]
[[play](https://go.dev/play/p/OtNQUImdYko)]
- **<big>Peek</big>** : 返回一个由源 stream 的元素组成的 stream并在从生成的 stream 中消耗元素时对每个元素执行所提供的操作。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#Peek)]
[[play](https://go.dev/play/p/u1VNzHs6cb2)]
- **<big>Skip</big>** : 在丢弃 stream 的前 n 个元素后,返回由源 stream 的其余元素组成的 stream。如果此 stream 包含的元素少于 n 个,则将返回一个空 stream。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#Skip)]
[[play](https://go.dev/play/p/fNdHbqjahum)]
- **<big>Limit</big>** : 返回由源 stream 的元素组成的 stream该 stream 被截断为长度不超过 maxSize。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#Limit)]
[[play](https://go.dev/play/p/qsO4aniDcGf)]
- **<big>Reverse</big>** : 返回元素与源 stream 的顺序相反的 stream。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#Reverse)]
[[play](https://go.dev/play/p/A8_zkJnLHm4)]
- **<big>Range</big>** : 返回一个 stream该 stream 的元素在从源 stream 的开始(包含)到结束(排除)的范围内。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#Range)]
[[play](https://go.dev/play/p/indZY5V2f4j)]
- **<big>Sorted</big>** : 返回一个 stream该 stream 由源 stream 的元素组成,并根据提供的 less 函数进行排序。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#Sorted)]
[[play](https://go.dev/play/p/XXtng5uonFj)]
- **<big>ForEach</big>** : 对 stream 的每个元素执行一个操作。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#ForEach)]
[[play](https://go.dev/play/p/Dsm0fPqcidk)]
- **<big>Reduce</big>** : 使用关联累加函数对 stream 的元素执行 reduce 操作,并 reduce 操作结果(如果有)。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#Reduce)]
[[play](https://go.dev/play/p/6uzZjq_DJLU)]
- **<big>FindFirst</big>** : 返回此 stream 的第一个元素和 true如果 stream 为空,则返回零值和 false。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#FindFirst)]
[[play](https://go.dev/play/p/9xEf0-6C1e3)]
- **<big>Max</big>** : 根据提供的 less 函数返回 stream 的最大元素。less 函数: a > b
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#Max)]
[[play](https://go.dev/play/p/fm-1KOPtGzn)]
- **<big>Min</big>** : 根据提供的 less 函数返回 stream 的最小元素。less 函数: a < b
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#Min)]
[[play](https://go.dev/play/p/vZfIDgGNRe_0)]
- **<big>AllMatch</big>** : 判断 stream 的所有元素是否全部匹配指定判定函数。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#AllMatch)]
[[play](https://go.dev/play/p/V5TBpVRs-Cx)]
- **<big>AnyMatch</big>** : 判断 stream 是否包含匹配指定判定函数的元素。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#AnyMatch)]
[[play](https://go.dev/play/p/PTCnWn4OxSn)]
- **<big>NoneMatch</big>** : 判断 stream 的元素是否全部不匹配指定的判定函数。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#NoneMatch)]
[[play](https://go.dev/play/p/iWS64pL1oo3)]
- **<big>Count</big>** : 返回 stream 中元素的数量。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#Count)]
[[play](https://go.dev/play/p/r3koY6y_Xo-)]
- **<big>ToSlice</big>** : 返回 stream 中的元素切片。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/stream_zh-CN.md#ToSlice)]
[[play](https://go.dev/play/p/jI6_iZZuVFE)]
### 18. structs 提供操作 struct, tag, field 的相关函数。
```go
import "github.com/duke-git/lancet/v2/structs"
@@ -1077,7 +1181,7 @@ import "github.com/duke-git/lancet/v2/structs"
- **<big>IsSlice</big>** : 判断属性是否是切片。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/structs/field_zh-CN.md#IsSlice)]
### 18. strutil 包含字符串处理的相关函数。
### 19. strutil 包含字符串处理的相关函数。
```go
import "github.com/duke-git/lancet/v2/strutil"
@@ -1158,7 +1262,7 @@ import "github.com/duke-git/lancet/v2/strutil"
[[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 的相关函数。
### 20. system 包含 os, runtime, shell command 的相关函数。
```go
import "github.com/duke-git/lancet/v2/system"
@@ -1194,7 +1298,7 @@ import "github.com/duke-git/lancet/v2/system"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/system_zh-CN#GetOsBits)]
[[play](https://go.dev/play/p/ml-_XH3gJbW)]
### 20. validator 验证器包,包含常用字符串格式验证函数。
### 21. validator 验证器包,包含常用字符串格式验证函数。
```go
import "github.com/duke-git/lancet/v2/validator"
@@ -1247,9 +1351,13 @@ import "github.com/duke-git/lancet/v2/validator"
- **<big>IsEmptyString</big>** : 验证字符串是否是空字符串。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsEmptyString)]
[[play](https://go.dev/play/p/dpzgUjFnBCX)]
- **<big>IsFloat</big>** : 验证参数是否是浮点数((float32float34)。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsFloat)]
- **<big>IsFloatStr</big>** : 验证字符串是否是可以转换为浮点数。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#LOYwS_Oyl7U)]
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsFloatStr)]
[[play](https://go.dev/play/p/LOYwS_Oyl7U)]
- **<big>IsNumber</big>** : 验证参数是否是数字(integerfloat)。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsNumber)]
- **<big>IsNumberStr</big>** : 验证字符串是否是可以转换为数字。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsNumberStr)]
[[play](https://go.dev/play/p/LzaKocSV79u)]
@@ -1259,6 +1367,8 @@ import "github.com/duke-git/lancet/v2/validator"
- **<big>IsRegexMatch</big>** : 验证字符串是否可以匹配正则表达式。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsRegexMatch)]
[[play](https://go.dev/play/p/z_XeZo_litG)]
- **<big>IsInt</big>** : 验证参数是否是整数(int, unit)。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsInt)]
- **<big>IsIntStr</big>** : 验证字符串是否是可以转换为整数。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsIntStr)]
[[play](https://go.dev/play/p/jQRtFv-a0Rk)]
@@ -1293,7 +1403,7 @@ import "github.com/duke-git/lancet/v2/validator"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/validator_zh-CN.md#IsPrintable)]
[[play](https://go.dev/play/p/Pe1FE2gdtTP)]
### 21. xerror 包实现一些错误处理函数
### 22. xerror 包实现一些错误处理函数
```go
import "github.com/duke-git/lancet/v2/xerror"

View File

@@ -22,6 +22,7 @@ import (
## Index
- [MapTo](#MapTo)
- [ForEach](#ForEach)
- [Filter](#Filter)
- [FilterByKeys](#FilterByKeys)
@@ -47,6 +48,64 @@ import (
## 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>
<p>Executes iteratee funcation for every key and value pair in map.</p>
@@ -123,7 +182,7 @@ func main() {
maputil.Filter(m, func(_ string, value int) {
sum += value
})
result := maputil.Filter(m, isEven)
fmt.Println(result)
@@ -133,7 +192,6 @@ func main() {
}
```
### <span id="FilterByKeys">FilterByKeys</span>
<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>
<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>
<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>
<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>
<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>
<p>Iterates over maps, return a new map of key and value pairs in all given maps.</p>
@@ -419,7 +472,7 @@ func main() {
keys := maputil.Keys(m)
sort.Ints(keys)
fmt.Println(keys)
// Output:
@@ -498,7 +551,7 @@ func main() {
"b": 22,
"d": 33,
}
result := maputil.Minus(m1, m2)
fmt.Println(result)
@@ -638,7 +691,6 @@ func main() {
}
```
### <span id="MapKeys">MapKeys</span>
<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>
<p>Transforms a map into array of key/value pairs.</p>
@@ -763,7 +814,6 @@ func main() {
}
```
### <span id="FromEntries">FromEntries</span>
<p>Creates a map based on a slice of key/value pairs.</p>
@@ -841,7 +891,6 @@ func main() {
}
```
### <span id="IsDisjoint">IsDisjoint</span>
<p>Checks two maps are disjoint if they have no keys in common</p>

View File

@@ -22,6 +22,7 @@ import (
## 目录:
- [MapTo](#MapTo)
- [ForEach](#ForEach)
- [Filter](#Filter)
- [FilterByKeys](#FilterByKeys)
@@ -47,6 +48,63 @@ import (
## 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>
<p>对map中的每对key和value执行iteratee函数</p>
@@ -80,7 +138,7 @@ func main() {
maputil.ForEach(m, func(_ string, value int) {
sum += value
})
fmt.Println(sum)
// Output:
@@ -123,7 +181,7 @@ func main() {
maputil.Filter(m, func(_ string, value int) {
sum += value
})
result := Filter(m, isEven)
fmt.Println(result)
@@ -171,7 +229,6 @@ func main() {
}
```
### <span id="FilterByValues">FilterByValues</span>
<p>迭代map, 返回一个新map其value都是给定的value值。</p>
@@ -210,7 +267,6 @@ func main() {
}
```
### <span id="OmitBy">OmitBy</span>
<p>Filter的反向操作, 迭代map中的每对key和value, 删除符合predicate函数的key, value, 返回新map。</p>
@@ -252,7 +308,6 @@ func main() {
}
```
### <span id="OmitByKeys">OmitByKeys</span>
<p>FilterByKeys的反向操作, 迭代map, 返回一个新map其key不包括给定的key值。</p>
@@ -291,7 +346,6 @@ func main() {
}
```
### <span id="OmitByValues">OmitByValues</span>
<p>FilterByValues的反向操作, 迭代map, 返回一个新map其value不包括给定的value值。</p>
@@ -416,7 +470,7 @@ func main() {
keys := maputil.Keys(m)
sort.Ints(keys)
fmt.Println(keys)
// Output:
@@ -453,7 +507,7 @@ func main() {
1: "1",
3: "2",
}
result := maputil.Merge(m1, m2)
fmt.Println(result)
@@ -632,7 +686,6 @@ func main() {
}
```
### <span id="MapKeys">MapKeys</span>
<p>操作map的每个key然后转为新的map。</p>
@@ -711,7 +764,6 @@ func main() {
}
```
### <span id="Entry">Entry</span>
<p>将map转换为键/值对切片。</p>
@@ -757,7 +809,6 @@ func main() {
}
```
### <span id="FromEntries">FromEntries</span>
<p>基于键/值对的切片创建map。</p>

View File

@@ -62,7 +62,7 @@ import (
- [FlatMap](#FlatMap)
- [Merge](#Merge)
- [Reverse](#Reverse)
- [Reduce](#Reduce)
- [Reduce<sup>deprecated</sup>](#Reduce)
- [ReduceBy](#ReduceBy)
- [ReduceRight](#ReduceRight)
- [Replace](#Replace)
@@ -1474,7 +1474,7 @@ func main() {
### <span id="Reduce">Reduce</span>
<p>Reduce slice.</p>
<p>Reduce slice.(Deprecated: use ReduceBy)</p>
<b>Signature:</b>

View File

@@ -62,7 +62,7 @@ import (
- [FlatMap](#FlatMap)
- [Merge](#Merge)
- [Reverse](#Reverse)
- [Reduce](#Reduce)
- [Reduce<sup>deprecated</sup>](#Reduce)
- [ReduceBy](#ReduceBy)
- [ReduceRight](#ReduceRight)
- [Replace](#Replace)
@@ -1475,7 +1475,7 @@ func main() {
### <span id="Reduce">Reduce</span>
<p>将切片中的元素依次运行iteratee函数返回运行结果</p>
<p>将切片中的元素依次运行iteratee函数返回运行结果(废弃建议使用ReduceBy)</p>
<b>函数签名:</b>
@@ -1509,7 +1509,7 @@ func main() {
### <span id="ReduceBy">ReduceBy</span>
<p>对切片执行reduce操作。</p>
<p>对切片元素执行reduce操作。</p>
<b>函数签名:</b>

View File

@@ -1,6 +1,6 @@
# Strutil
# Stream
Stream 实现,该包仅验证简单 go stream 实现,功能有限。
Stream ,该包仅验证简单 stream 实现,功能有限。
<div STYLE="page-break-after: always;"></div>

View File

@@ -629,7 +629,7 @@ func main() {
}
```
### <span id="IsFloat">IsInt</span>
### <span id="IsFloat">IsFloat</span>
<p>Check if the value is float(float32, float34) or not.</p>

View File

@@ -629,7 +629,7 @@ func main() {
}
```
### <span id="IsFloat">IsInt</span>
### <span id="IsFloat">IsFloat</span>
<p>验证参数是否是浮点数((float32, float34)。</p>

View File

@@ -5,6 +5,7 @@
package internal
import (
"bytes"
"fmt"
"reflect"
"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
func (a *Assert) Greater(expected, actual any) {
if compare(expected, actual) != compareGreater {

View File

@@ -397,3 +397,39 @@ func ExampleOmitByValues() {
// Output:
// 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
View 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 := maputil.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
View 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)
}

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by MIT license
// Package stream implements a sequence of elements supporting sequential and operations.
// this package is an experiment to explore if stream in go can work as the way java does. it's function is very limited.
// this package is an experiment to explore if stream in go can work as the way java does. its function is very limited.
package stream
import (