1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-03-01 00:35:28 +08:00

Compare commits

..

11 Commits

Author SHA1 Message Date
dudaodong
889d0cc3d6 doc: update readme file 2025-11-01 21:45:56 +08:00
dudaodong
aa05027cab doc: update readme file 2025-11-01 21:44:03 +08:00
dudaodong
fabc3483ed doc: update readme file 2025-11-01 21:37:15 +08:00
dudaodong
30363242bb doc: update document for version v2.3.8 2025-11-01 21:25:10 +08:00
dudaodong
5d3964d81a release v2.3.8 2025-11-01 19:39:46 +08:00
dudaodong
6c3dc3e7d6 Merge branch 'rc' of github.com:duke-git/lancet into rc 2025-10-31 14:59:25 +08:00
dudaodong
2a2e1ca551 doc: add enum and update overview index 2025-10-31 14:57:54 +08:00
dudaodong
e1821eed2c doc: add docment for enum package 2025-10-31 14:48:32 +08:00
dudaodong
62f0a96d91 doc: add docment for enum package 2025-10-31 14:48:22 +08:00
dudaodong
cbdc3971dd doc: add docment for new or fixed function 2025-10-31 13:37:41 +08:00
Javen
350450bb67 feat: add ContainAny (#338)
Co-authored-by: Jiawen <im@linjiawen.com>
2025-10-30 19:24:45 +08:00
33 changed files with 3239 additions and 495 deletions

143
README.md
View File

@@ -4,7 +4,7 @@
<br/>
![Go version](https://img.shields.io/badge/go-%3E%3Dv1.18-9cf)
[![Release](https://img.shields.io/badge/release-2.3.7-green.svg)](https://github.com/duke-git/lancet/releases)
[![Release](https://img.shields.io/badge/release-2.3.8-green.svg)](https://github.com/duke-git/lancet/releases)
[![GoDoc](https://godoc.org/github.com/duke-git/lancet/v2?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet/v2)
[![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet/v2)](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
[![test](https://github.com/duke-git/lancet/actions/workflows/codecov.yml/badge.svg?branch=main&event=push)](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
@@ -84,6 +84,8 @@ func main() {
- [Cryptor](#user-content-cryptor)
- [Datetime](#user-content-datetime)
- [Datastructure](#user-content-datastructure)
- [EventBus](#user-content-eventbus)
- [Enum](#user-content-enum)
- [Fileutil](#user-content-fileutil)
- [Formatter](#user-content-formatter)
- [Function](#user-content-function)
@@ -313,6 +315,15 @@ import "github.com/duke-git/lancet/v2/convertor"
- **<big>ToPointer</big>** : return a pointer of passed value.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/convertor.md#ToPointer)]
[[play](https://go.dev/play/p/ASf_etHNlw1)]
- **<big>ToPointers</big>** : convert a slice of values to a slice of pointers.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/convertor.md#ToPointers)]
[[play](https://go.dev/play/p/ZUoXd2i5ZkV)]
- **<big>FromPointer</big>** : returns the value pointed to by the pointer.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/convertor.md#FromPointer)]
[[play](https://go.dev/play/p/wAp90V7Zu6g)]
- **<big>FromPointers</big>** : convert a slice of pointers to a slice of values.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/convertor.md#FromPointers)]
[[play](https://go.dev/play/p/qIPsyYtNy3Q)]
- **<big>ToString</big>** : convert value to string.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/convertor.md#ToString)]
[[play](https://go.dev/play/p/nF1zOOslpQq)]
@@ -724,7 +735,7 @@ import optional "github.com/duke-git/lancet/v2/datastructure/optional"
import "github.com/duke-git/lancet/v2/eventbus"
```
#### 函数列表:
#### Function list:
- **<big>NewEventBus</big>** : Create an EventBus instance.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/eventbus.md#NewEventBus)]
@@ -757,7 +768,70 @@ import "github.com/duke-git/lancet/v2/eventbus"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/eventbus.md#SetErrorHandler)]
[[play](https://go.dev/play/p/gmB0gnFe5mc)]
<h3 id="fileutil"> 9. Fileutil package implements some basic functions for file operations. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
<h3 id="enum"> 10. Package enum provides a simple enum implementation. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">Index</a></h3>
```go
import "github.com/duke-git/lancet/v2/enum"
```
#### Function list:
- **<big>NewItem</big>** : Creates a new enum item.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/enum.md#NewEventBus)]
[[play](https://go.dev/play/p/8qNsLw01HD5)]
- **<big>NewItemsFromPairs</big>** : Creates enum items from a slice of Pair structs.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/enum.md#NewItemsFromPairs)]
[[play](https://go.dev/play/p/xKnoGa7gnev)]
- **<big>Value</big>** : Returns the value of the enum item.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/enum.md#Value)]
[[play](https://go.dev/play/p/xKnoGa7gnev)]
- **<big>Name</big>** : Returns the name of the enum item.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/enum.md#Name)]
[[play](https://go.dev/play/p/xKnoGa7gnev)]
- **<big>Valid</big>** : Checks if the enum item is valid. If a custom check function is provided, it will be used to validate the value.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/enum.md#Valid)]
[[play](https://go.dev/play/p/pA3lYY2VSm3)]
- **<big>MarshalJSON</big>** : Implementation of json.Marshaler interface.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/enum.md#MarshalJSON)]
[[play](https://go.dev/play/p/zIZEdAnneB5)]
- **<big>NewRegistry</big>** : Creates a new enum registry.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/enum.md#NewRegistry)]
[[play](https://go.dev/play/p/ABEXsYfJKMo)]
- **<big>Add</big>** : Adds enum items to the registry.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/enum.md#Add)]
[[play](https://go.dev/play/p/ABEXsYfJKMo)]
- **<big>Remove</big>** : Removes an enum item from the registry by its value.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/enum.md#Remove)]
[[play](https://go.dev/play/p/dSG84wQ3TuC)]
- **<big>Update</big>** : Updates the name of an enum item in the registry by its value.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/enum.md#Update)]
[[play](https://go.dev/play/p/Ol0moT1J9Xl)]
- **<big>GetByValue</big>** : Retrieves an enum item by its value.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/enum.md#GetByValue)]
[[play](https://go.dev/play/p/niJ1U2KlE_m)]
- **<big>GetByName</big>** : Retrieves an enum item by its name.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/enum.md#GetByName)]
[[play](https://go.dev/play/p/49ie_gpqH0m)]
- **<big>Items</big>** : Returns a slice of all enum items in the registry.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/enum.md#Items)]
[[play](https://go.dev/play/p/lAJFAradbvQ)]
- **<big>Contains</big>** : Checks if an enum item with the given value exists in the registry.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/enum.md#Contains)]
[[play](https://go.dev/play/p/_T-lPYkZn2j)]
- **<big>Size</big>** : Returns the number of enum items in the registry.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/enum.md#Size)]
[[play](https://go.dev/play/p/TeDArWhlQe2)]
- **<big>Range</big>** : Iterates over all enum items in the registry and applies the given function.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/enum.md#Range)]
[[play](https://go.dev/play/p/GPsZbQbefWN)]
- **<big>SortedItems</big>** : Returns a slice of all enum items sorted by the given less function.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/enum.md#SortedItems)]
[[play](https://go.dev/play/p/tN9RE_m_WEI)]
- **<big>Filter</big>** : Returns a slice of enum items that satisfy the given predicate function.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/enum.md#Filter)]
[[play](https://go.dev/play/p/uTUpTdcyoCU)]
<h3 id="fileutil"> 11. Fileutil package implements some basic functions for file operations. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
```go
import "github.com/duke-git/lancet/v2/fileutil"
@@ -859,7 +933,7 @@ import "github.com/duke-git/lancet/v2/fileutil"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/fileutil.md#GetExeOrDllVersion)]
[[play](https://go.dev/play/p/iLRrDBhE38E)]
<h3 id="formatter"> 10. Formatter contains some functions for data formatting. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
<h3 id="formatter"> 12. Formatter contains some functions for data formatting. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
```go
import "github.com/duke-git/lancet/v2/formatter"
@@ -889,7 +963,7 @@ import "github.com/duke-git/lancet/v2/formatter"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/formatter.md#ParseBinaryBytes)]
[[play](https://go.dev/play/p/69v1tTT62x8)]
<h3 id="function"> 11. Function package can control the flow of function execution and support part of functional programming.&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
<h3 id="function"> 13. Function package can control the flow of function execution and support part of functional programming.&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
```go
import "github.com/duke-git/lancet/v2/function"
@@ -952,7 +1026,7 @@ import "github.com/duke-git/lancet/v2/function"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/function.md#Watcher)]
[[play](https://go.dev/play/p/l2yrOpCLd1I)]
<h3 id="maputil"> 12. Maputil package includes some functions to manipulate map.&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
<h3 id="maputil"> 14. Maputil package includes some functions to manipulate map.&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
```go
import "github.com/duke-git/lancet/v2/maputil"
@@ -1125,8 +1199,11 @@ import "github.com/duke-git/lancet/v2/maputil"
- **<big>FindValuesBy</big>** : returns a slice of values from the map that satisfy the given predicate function.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/maputil.md#FindValuesBy)]
[[play](https://go.dev/play/p/bvNwNBZDm6v)]
- **<big>ToMarkdownTable</big>** : Convert a map slice data to a Markdown table string. It supports custom header display names and column display order.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/maputil.md#ToMarkdownTable)]
[[play](https://go.dev/play/p/w_pSLfeyEB5)]
<h3 id="mathutil"> 13. Mathutil package implements some functions for math calculation. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
<h3 id="mathutil"> 15. Mathutil package implements some functions for math calculation. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
```go
import "github.com/duke-git/lancet/v2/mathutil"
@@ -1237,7 +1314,7 @@ import "github.com/duke-git/lancet/v2/mathutil"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/mathutil.md#Combination)]
[[play](https://go.dev/play/p/ENFQRDQUFi9)]
<h3 id="netutil"> 14. Netutil package contains functions to get net information and send http request. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
<h3 id="netutil"> 16. Netutil package contains functions to get net information and send http request. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
```go
import "github.com/duke-git/lancet/v2/netutil"
@@ -1316,7 +1393,7 @@ import "github.com/duke-git/lancet/v2/netutil"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/netutil.md#AddQueryParams)]
[[play](https://go.dev/play/p/JLXl1hZK7l4)]
<h3 id="pointer"> 15. Pointer package contains some util functions to operate go pointer. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
<h3 id="pointer"> 17. Pointer package contains some util functions to operate go pointer. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
```go
import "github.com/duke-git/lancet/v2/pointer"
@@ -1340,7 +1417,7 @@ import "github.com/duke-git/lancet/v2/pointer"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/pointer.md#UnwrapOrDefault)]
[[play](https://go.dev/play/p/ZnGIHf8_o4E)]
<h3 id="random"> 16. Random package implements some basic functions to generate random int and string. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
<h3 id="random"> 18. Random package implements some basic functions to generate random int and string. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
```go
import "github.com/duke-git/lancet/v2/random"
@@ -1406,7 +1483,7 @@ import "github.com/duke-git/lancet/v2/random"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/random.md#RandNumberOfLength)]
[[play](https://go.dev/play/p/oyZbuV7bu7b)]
<h3 id="retry"> 17. Retry package is for executing a function repeatedly until it was successful or canceled by the context. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
<h3 id="retry"> 19. Retry package is for executing a function repeatedly until it was successful or canceled by the context. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
```go
import "github.com/duke-git/lancet/v2/retry"
@@ -1441,7 +1518,7 @@ import "github.com/duke-git/lancet/v2/retry"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/retry.md#RetryWithExponentialWithJitterBackoff)]
[[play](https://go.dev/play/p/xp1avQmn16X)]
<h3 id="slice"> 18. Slice contains some functions to manipulate slice. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
<h3 id="slice"> 20. Slice contains some functions to manipulate slice. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
```go
import "github.com/duke-git/lancet/v2/slice"
@@ -1461,6 +1538,9 @@ import "github.com/duke-git/lancet/v2/slice"
- **<big>ContainSubSlice</big>** : check if the slice contain a given subslice or not.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#ContainSubSlice)]
[[play](https://go.dev/play/p/bcuQ3UT6Sev)]
- **<big>ContainAny</big>** : check if the slice contains any element from the targets slice.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#ContainAny)]
[[play](https://go.dev/play/p/4xoxhc9XSSw)]
- **<big>Chunk</big>** : creates a slice of elements split into groups the length of size.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#Chunk)]
[[play](https://go.dev/play/p/b4Pou5j2L_C)]
@@ -1710,7 +1790,7 @@ import "github.com/duke-git/lancet/v2/slice"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/slice.md#ConcatBy)]
[[play](https://go.dev/play/p/6QcUpcY4UMW)]
<h3 id="stream"> 19. 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. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
<h3 id="stream"> 21. 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. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
```go
import "github.com/duke-git/lancet/v2/stream"
@@ -1809,7 +1889,7 @@ import "github.com/duke-git/lancet/v2/stream"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/stream.md#LastIndexOf)]
[[play](https://go.dev/play/p/CjeoNw2eac_G)]
<h3 id="structs"> 20. Structs package provides several high level functions to manipulate struct, tag, and field. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
<h3 id="structs"> 22. Structs package provides several high level functions to manipulate struct, tag, and field. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
```go
import "github.com/duke-git/lancet/v2/structs"
@@ -1819,32 +1899,51 @@ import "github.com/duke-git/lancet/v2/structs"
- **<big>New</big>** : creates a `Struct` instance.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#New)]
[[play](https://go.dev/play/p/O29l8kk-Z17)]
- **<big>ToMap</big>** : converts a valid struct to a map.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#ToMap)]
[[play](https://go.dev/play/p/qQbLySBgerZ)]
- **<big>Fields</big>** : get all fields of a given struct, that the fields are abstract struct field.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#Fields)]
[[play](https://go.dev/play/p/w3Kk_CyVY7D)]
- **<big>Field</big>** : get an abstract field of a struct by given field name
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#Field)]
[[play](https://go.dev/play/p/KocZMSYarza)]
- **<big>IsStruct</big>** : check if the struct is valid.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#IsStruct)]
[[play](https://go.dev/play/p/bU2FSdkbK1C)]
- **<big>Tag</big>** : get a `Tag` of the `Field`, `Tag` is a abstract struct field tag.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#Tag)]
[[play](https://go.dev/play/p/DVrx5HvvUJr)]
- **<big>Name</big>** : get the field name.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#Name)]
[[play](https://go.dev/play/p/zfIGlqsatee)]
- **<big>Value</big>** : get the `Field` underlying value.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#Value)]
[[play](https://go.dev/play/p/qufYEU2o4Oi)]
- **<big>Kind</big>** : get the field's kind.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#Kind)]
[[play](https://go.dev/play/p/wg4NlcUNG5o)]
- **<big>IsEmbedded</big>** : check if the field is an embedded field.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#IsEmbedded)]
[[play](https://go.dev/play/p/wV2PrbYm3Ec)]
- **<big>IsExported</big>** : check if the field is exported.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#IsExported)]
[[play](https://go.dev/play/p/csK4AXYaNbJ)]
- **<big>IsZero</big>** : check if the field is zero value.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#IsZero)]
[[play](https://go.dev/play/p/RzqpGISf87r)]
- **<big>IsSlice</big>** : check if the field is a slice.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#IsSlice)]
[[play](https://go.dev/play/p/MKz4CgBIUrU)]
- **<big>IsTargetType</big>** : check if the field is target type.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#IsTargetType)]
[[play](https://go.dev/play/p/Ig75P-agN39)]
- **<big>TypeName</big>** : Return struct type name.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/struct.md#TypeName)]
[[play](https://go.dev/play/p/SWLWd0XBaBb)]
<h3 id="strutil"> 21. Strutil package contains some functions to manipulate string. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
<h3 id="strutil"> 23. Strutil package contains some functions to manipulate string. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
```go
import "github.com/duke-git/lancet/v2/strutil"
@@ -1996,7 +2095,7 @@ import "github.com/duke-git/lancet/v2/strutil"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/strutil.md#FindAllOccurrences)]
[[play](https://go.dev/play/p/uvyA6azGLB1)]
<h3 id="system"> 22. System package contain some functions about os, runtime, shell command. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
<h3 id="system"> 24. System package contain some functions about os, runtime, shell command. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
```go
import "github.com/duke-git/lancet/v2/system"
@@ -2044,7 +2143,7 @@ import "github.com/duke-git/lancet/v2/system"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/system.md#GetProcessInfo)]
[[play](https://go.dev/play/p/NQDVywEYYx7)]
<h3 id="tuple"> 23. Tuple package implements tuple data type and some operations on it. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
<h3 id="tuple"> 25. Tuple package implements tuple data type and some operations on it. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
```go
import "github.com/duke-git/lancet/v2/tuple"
@@ -2161,7 +2260,7 @@ import "github.com/duke-git/lancet/v2/tuple"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/tuple.md#Unzip10)]
[[play](https://go.dev/play/p/-taQB6Wfre_z)]
<h3 id="validator"> 24. Validator package contains some functions for data validation. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
<h3 id="validator"> 26. Validator package contains some functions for data validation. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
```go
import "github.com/duke-git/lancet/v2/validator"
@@ -2301,8 +2400,14 @@ import "github.com/duke-git/lancet/v2/validator"
- **<big>IsChinaUnionPay</big>** : check if a give string is a valid china union pay number or not.
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsChinaUnionPay)]
[[play](https://go.dev/play/p/yafpdxLiymu)]
- **<big>IsPassport</big>** : Passport validation(using regex).
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsPassport)]
[[play](https://go.dev/play/p/dvOiV2BW7Aw)]
- **<big>IsChineseHMPassport</big>** : Mainland travel permit for Hong Kong, Macao validation (using regex).
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/validator.md#IsChineseHMPassport)]
[[play](https://go.dev/play/p/xKG6spQTcY0)]
<h3 id="xerror"> 25. Xerror package implements helpers for errors. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
<h3 id="xerror"> 27. Xerror package implements helpers for errors. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">index</a></h3>
```go
import "github.com/duke-git/lancet/v2/xerror"

View File

@@ -4,7 +4,7 @@
<br/>
![Go version](https://img.shields.io/badge/go-%3E%3Dv1.18-9cf)
[![Release](https://img.shields.io/badge/release-2.3.7-green.svg)](https://github.com/duke-git/lancet/releases)
[![Release](https://img.shields.io/badge/release-2.3.8-green.svg)](https://github.com/duke-git/lancet/releases)
[![GoDoc](https://godoc.org/github.com/duke-git/lancet/v2?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet/v2)
[![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet/v2)](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
[![test](https://github.com/duke-git/lancet/actions/workflows/codecov.yml/badge.svg?branch=main&event=push)](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
@@ -83,6 +83,8 @@ func main() {
- [Cryptor](#user-content-cryptor)
- [Datetime](#user-content-datetime)
- [Datastructure](#user-content-datastructure)
- [EventBus](#user-content-eventbus)
- [Enum](#user-content-enum)
- [Fileutil](#user-content-fileutil)
- [Formatter](#user-content-formatter)
- [Function](#user-content-function)
@@ -312,6 +314,15 @@ import "github.com/duke-git/lancet/v2/convertor"
- **<big>ToPointer</big>** : 返回传入值的指针。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/convertor.md#ToPointer)]
[[play](https://go.dev/play/p/ASf_etHNlw1)]
- **<big>ToPointers</big>** : 将值的切片转换为指针的切片。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/convertor.md#ToPointers)]
[[play](https://go.dev/play/p/ZUoXd2i5ZkV)]
- **<big>FromPointer</big>** : 返回指针所指向的值。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/convertor.md#FromPointer)]
[[play](https://go.dev/play/p/wAp90V7Zu6g)]
- **<big>FromPointers</big>** : 将指针的切片转换为值的切片。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/convertor.md#FromPointers)]
[[play](https://go.dev/play/p/qIPsyYtNy3Q)]
- **<big>ToString</big>** : 将值转换为字符串,对于数字、字符串、[]byte将转换为字符串。 对于其他类型(切片、映射、数组、结构)将调用 json.Marshal。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/convertor.md#ToString)]
[[play](https://go.dev/play/p/nF1zOOslpQq)]
@@ -767,7 +778,70 @@ import "github.com/duke-git/lancet/v2/eventbus"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/eventbus.md#SetErrorHandler)]
[[play](https://go.dev/play/p/gmB0gnFe5mc)]
<h3 id="fileutil"> 10. fileutil 包含文件基本操作。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
<h3 id="enum"> 10. Enum实现一个简单枚举工具包。. &nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">Index</a></h3>
```go
import "github.com/duke-git/lancet/v2/enum"
```
#### Function list:
- **<big>NewItem</big>** : 创建枚举项。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/enum.md#NewItem)]
[[play](https://go.dev/play/p/8qNsLw01HD5)]
- **<big>NewItemsFromPairs</big>** : 从 Pair 结构体的切片创建枚举项。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/enum.md#NewItemsFromPairs)]
[[play](https://go.dev/play/p/xKnoGa7gnev)]
- **<big>Value</big>** : 返回枚举项的值。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/enum.md#Value)]
[[play](https://go.dev/play/p/xKnoGa7gnev)]
- **<big>Name</big>** : 返回枚举项的名称。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/enum.md#Name)]
[[play](https://go.dev/play/p/xKnoGa7gnev)]
- **<big>Valid</big>** : 检查枚举项是否有效。如果提供了自定义检查函数,将使用该函数验证值。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/enum.md#Valid)]
[[play](https://go.dev/play/p/pA3lYY2VSm3)]
- **<big>MarshalJSON</big>** : 枚举项实现 json.Marshaler 接口。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/enum.md#MarshalJSON)]
[[play](https://go.dev/play/p/zIZEdAnneB5)]
- **<big>NewRegistry</big>** : Registry 定义了一个通用的枚举注册表结构体。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/enum.md#NewRegistry)]
[[play](https://go.dev/play/p/ABEXsYfJKMo)]
- **<big>Add</big>** : 向枚举注册表添加枚举项。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/enum.md#Add)]
[[play](https://go.dev/play/p/ABEXsYfJKMo)]
- **<big>Remove</big>** : 在枚举注册表中删除枚举项。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/enum.md#Remove)]
[[play](https://go.dev/play/p/dSG84wQ3TuC)]
- **<big>Update</big>** : 在枚举注册表中更新枚举项。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/enum.md#Update)]
[[play](https://go.dev/play/p/Ol0moT1J9Xl)]
- **<big>GetByValue</big>** : 在枚举注册表中通过值获取枚举项。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/enum.md#GetByValue)]
[[play](https://go.dev/play/p/niJ1U2KlE_m)]
- **<big>GetByName</big>** : 在枚举注册表中通过名称获取枚举项。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/enum.md#GetByName)]
[[play](https://go.dev/play/p/49ie_gpqH0m)]
- **<big>Items</big>** : 返回枚举注册表中的枚举项。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/enum.md#Items)]
[[play](https://go.dev/play/p/lAJFAradbvQ)]
- **<big>Contains</big>** : 检查注册表中是否存在具有给定值的枚举项。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/enum.md#Contains)]
[[play](https://go.dev/play/p/_T-lPYkZn2j)]
- **<big>Size</big>** : 返回注册表中枚举项的数目。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/enum.md#Size)]
[[play](https://go.dev/play/p/TeDArWhlQe2)]
- **<big>Range</big>** : 遍历注册表中的所有枚举项,并应用给定的函数。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/enum.md#Range)]
[[play](https://go.dev/play/p/GPsZbQbefWN)]
- **<big>SortedItems</big>** : 返回按给定比较函数排序的所有枚举项的切片。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/enum.md#SortedItems)]
[[play](https://go.dev/play/p/tN9RE_m_WEI)]
- **<big>Filter</big>** : 返回满足给定谓词函数的枚举项切片。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/enum.md#Filter)]
[[play](https://go.dev/play/p/uTUpTdcyoCU)]
<h3 id="fileutil"> 11. fileutil 包含文件基本操作。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
```go
import "github.com/duke-git/lancet/v2/fileutil"
@@ -869,7 +943,7 @@ import "github.com/duke-git/lancet/v2/fileutil"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#GetExeOrDllVersion)]
[[play](https://go.dev/play/p/iLRrDBhE38E)]
<h3 id="formatter"> 11. formatter 格式化器包含一些数据格式化处理方法。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
<h3 id="formatter"> 12. formatter 格式化器包含一些数据格式化处理方法。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
```go
import "github.com/duke-git/lancet/v2/formatter"
@@ -899,7 +973,7 @@ import "github.com/duke-git/lancet/v2/formatter"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/formatter.md#ParseBinaryBytes)]
[[play](https://go.dev/play/p/69v1tTT62x8)]
<h3 id="function"> 12. function 函数包控制函数执行流程,包含部分函数式编程。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
<h3 id="function"> 13. function 函数包控制函数执行流程,包含部分函数式编程。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
```go
import "github.com/duke-git/lancet/v2/function"
@@ -962,7 +1036,7 @@ import "github.com/duke-git/lancet/v2/function"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/function.md#Watcher)]
[[play](https://go.dev/play/p/l2yrOpCLd1I)]
<h3 id="maputil"> 13. maputil 包括一些操作 map 的函数。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
<h3 id="maputil"> 14. maputil 包括一些操作 map 的函数。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
```go
import "github.com/duke-git/lancet/v2/maputil"
@@ -1135,8 +1209,11 @@ import "github.com/duke-git/lancet/v2/maputil"
- **<big>FindValuesBy</big>** : 返回一个切片,包含满足给定谓词判断函数的 map 中的值。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/maputil.md#FindValuesBy)]
[[play](https://go.dev/play/p/bvNwNBZDm6v)]
- **<big>ToMarkdownTable</big>** : 将一个 map 切片数据转换为 Markdown 表格字符串。支持自定义表头显示名称和列的显示顺序。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/maputil.md#ToMarkdownTable)]
[[play](https://go.dev/play/p/w_pSLfeyEB5)]
<h3 id="mathutil"> 14. mathutil 包实现了一些数学计算的函数。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
<h3 id="mathutil"> 15. mathutil 包实现了一些数学计算的函数。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
```go
import "github.com/duke-git/lancet/v2/mathutil"
@@ -1247,7 +1324,7 @@ import "github.com/duke-git/lancet/v2/mathutil"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/mathutil.md#Combination)]
[[play](https://go.dev/play/p/ENFQRDQUFi9)]
<h3 id="netutil"> 15. netutil 网络包支持获取 ip 地址,发送 http 请求。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
<h3 id="netutil"> 16. netutil 网络包支持获取 ip 地址,发送 http 请求。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
```go
import "github.com/duke-git/lancet/v2/netutil"
@@ -1326,7 +1403,7 @@ import "github.com/duke-git/lancet/v2/netutil"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/netutil.md#AddQueryParams)]
[[play](https://go.dev/play/p/JLXl1hZK7l4)]
<h3 id="pointer"> 16. pointer 包支持一些指针类型的操作。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
<h3 id="pointer"> 17. pointer 包支持一些指针类型的操作。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
```go
import "github.com/duke-git/lancet/v2/pointer"
@@ -1350,7 +1427,7 @@ import "github.com/duke-git/lancet/v2/pointer"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/pointer.md#UnwrapOrDefault)]
[[play](https://go.dev/play/p/ZnGIHf8_o4E)]
<h3 id="random"> 17. random 随机数生成器包,可以生成随机[]bytes, int, string。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
<h3 id="random"> 18. random 随机数生成器包,可以生成随机[]bytes, int, string。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
```go
import "github.com/duke-git/lancet/v2/random"
@@ -1416,7 +1493,7 @@ import "github.com/duke-git/lancet/v2/random"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/random.md#RandNumberOfLength)]
[[play](https://go.dev/play/p/oyZbuV7bu7b)]
<h3 id="retry"> 18. retry 重试执行函数直到函数运行成功或被 context cancel。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
<h3 id="retry"> 19. retry 重试执行函数直到函数运行成功或被 context cancel。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
```go
import "github.com/duke-git/lancet/v2/retry"
@@ -1448,7 +1525,7 @@ import "github.com/duke-git/lancet/v2/retry"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/retry.md#RetryWithExponentialWithJitterBackoff)]
[[play](https://go.dev/play/p/xp1avQmn16X)]
<h3 id="slice"> 19. slice 包含操作切片的方法集合。&nbsp; &nbsp; &nbsp; &nbsp; <a href="#index">回到目录</a></h3>
<h3 id="slice"> 20. slice 包含操作切片的方法集合。&nbsp; &nbsp; &nbsp; &nbsp; <a href="#index">回到目录</a></h3>
```go
import "github.com/duke-git/lancet/v2/slice"
@@ -1468,6 +1545,9 @@ import "github.com/duke-git/lancet/v2/slice"
- **<big>ContainSubSlice</big>** : 判断 slice 是否包含 subslice。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#ContainSubSlice)]
[[play](https://go.dev/play/p/bcuQ3UT6Sev)]
- **<big>ContainAny</big>** : 判断 slice 是否包含 targets 切片中的任意一个元素。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#ContainAny)]
[[play](https://go.dev/play/p/4xoxhc9XSSw)]
- **<big>Chunk</big>** : 按照 size 参数均分 slice。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#Chunk)]
[[play](https://go.dev/play/p/b4Pou5j2L_C)]
@@ -1719,7 +1799,7 @@ import "github.com/duke-git/lancet/v2/slice"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/slice.md#ConcatBy)]
[[play](https://go.dev/play/p/6QcUpcY4UMW)]
<h3 id="stream"> 20. stream 流,该包仅验证简单的 stream 实现,功能有限。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
<h3 id="stream"> 21. stream 流,该包仅验证简单的 stream 实现,功能有限。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
```go
import "github.com/duke-git/lancet/v2/stream"
@@ -1815,7 +1895,7 @@ import "github.com/duke-git/lancet/v2/stream"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/stream.md#LastIndexOf)]
[[play](https://go.dev/play/p/CjeoNw2eac_G)]
<h3 id="structs"> 21. structs 提供操作 struct, tag, field 的相关函数。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
<h3 id="structs"> 22. structs 提供操作 struct, tag, field 的相关函数。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
```go
import "github.com/duke-git/lancet/v2/structs"
@@ -1825,34 +1905,51 @@ import "github.com/duke-git/lancet/v2/structs"
- **<big>New</big>** : `Struct`结构体的构造函数。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#New)]
[[play](https://go.dev/play/p/O29l8kk-Z17)]
- **<big>ToMap</big>** : 将一个合法的 struct 对象转换为 map[string]any。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#ToMap)]
[[play](https://go.dev/play/p/qQbLySBgerZ)]
- **<big>Fields</big>** : 获取一个 struct 对象的属性列表。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#Fields)]
[[play](https://go.dev/play/p/w3Kk_CyVY7D)]
- **<big>Field</big>** : 根据属性名获取一个 struct 对象的属性。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#Fields)]
[[play](https://go.dev/play/p/KocZMSYarza)]
- **<big>IsStruct</big>** : 判断是否为一个合法的 struct 对象。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#IsStruct)]
[[play](https://go.dev/play/p/bU2FSdkbK1C)]
- **<big>Tag</big>** : 获取`Field``Tag`,默认的 tag key 是 json。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#Tag)]
[[play](https://go.dev/play/p/DVrx5HvvUJr)]
- **<big>Name</big>** : 获取属性名。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#Name)]
[[play](https://go.dev/play/p/zfIGlqsatee)]
- **<big>Value</big>** : 获取`Field`属性的值。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#Value)]
[[play](https://go.dev/play/p/qufYEU2o4Oi)]
- **<big>Kind</big>** : 获取属性 Kind。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#Kind)]
[[play](https://go.dev/play/p/wg4NlcUNG5o)]
- **<big>IsEmbedded</big>** : 判断属性是否为嵌入。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#IsEmbedded)]
[[play](https://go.dev/play/p/wV2PrbYm3Ec)]
- **<big>IsExported</big>** : 判断属性是否导出。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#IsExported)]
[[play](https://go.dev/play/p/csK4AXYaNbJ)]
- **<big>IsZero</big>** : 判断属性是否为零值。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#IsZero)]
[[play](https://go.dev/play/p/RzqpGISf87r)]
- **<big>IsSlice</big>** : 判断属性是否是切片。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#IsSlice)]
[[play](https://go.dev/play/p/MKz4CgBIUrU)]
- **<big>IsTargetType</big>** : 判断属性是否是目标类型。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#IsTargetType)]
[[play](https://go.dev/play/p/Ig75P-agN39)]
- **<big>TypeName</big>** : 获取结构体类型名。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/struct.md#TypeName)]
[[play](https://go.dev/play/p/SWLWd0XBaBb)]
<h3 id="strutil"> 22. strutil 包含字符串处理的相关函数。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
<h3 id="strutil"> 23. strutil 包含字符串处理的相关函数。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
```go
import "github.com/duke-git/lancet/v2/strutil"
@@ -2005,7 +2102,7 @@ import "github.com/duke-git/lancet/v2/strutil"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/strutil.md#FindAllOccurrences)]
[[play](https://go.dev/play/p/uvyA6azGLB1)]
<h3 id="system"> 23. system 包含 os, runtime, shell command 的相关函数。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
<h3 id="system"> 24. system 包含 os, runtime, shell command 的相关函数。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
```go
import "github.com/duke-git/lancet/v2/system"
@@ -2053,7 +2150,7 @@ import "github.com/duke-git/lancet/v2/system"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/system.md#GetProcessInfo)]
[[play](https://go.dev/play/p/NQDVywEYYx7)]
<h3 id="tuple"> 24. Tuple 包实现一个元组数据类型。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
<h3 id="tuple"> 25. Tuple 包实现一个元组数据类型。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
```go
import "github.com/duke-git/lancet/v2/tuple"
@@ -2170,7 +2267,7 @@ import "github.com/duke-git/lancet/v2/tuple"
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/tuple.md#Unzip10)]
[[play](https://go.dev/play/p/-taQB6Wfre_z)]
<h3 id="validator"> 25. validator 验证器包,包含常用字符串格式验证函数。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
<h3 id="validator"> 26. validator 验证器包,包含常用字符串格式验证函数。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
```go
import "github.com/duke-git/lancet/v2/validator"
@@ -2310,8 +2407,14 @@ import "github.com/duke-git/lancet/v2/validator"
- **<big>IsChinaUnionPay</big>** : 检查字符串是否是有效的中国银联卡号。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/validator.md#IsChinaUnionPay)]
[[play](https://go.dev/play/p/yafpdxLiymu)]
- **<big>IsPassport</big>** : 判断护照(正则判断)。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/validator.md#IsPassport)]
[[play](https://go.dev/play/p/dvOiV2BW7Aw)]
- **<big>IsChineseHMPassport</big>** : 判断港澳台通行证(正则判断)。
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/validator.md#IsChineseHMPassport)]
[[play](https://go.dev/play/p/xKG6spQTcY0)]
<h3 id="xerror"> 26. xerror 包实现一些错误处理函数。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
<h3 id="xerror"> 27. xerror 包实现一些错误处理函数。&nbsp; &nbsp; &nbsp; &nbsp;<a href="#index">回到目录</a></h3>
```go
import "github.com/duke-git/lancet/v2/xerror"

View File

@@ -229,7 +229,7 @@ func ToPointer[T any](value T) *T {
}
// ToPointers convert a slice of values to a slice of pointers.
// Play: todo
// Play: https://go.dev/play/p/ZUoXd2i5ZkV
func ToPointers[T any](values []T) []*T {
result := make([]*T, len(values))
for i := range values {
@@ -239,7 +239,7 @@ func ToPointers[T any](values []T) []*T {
}
// FromPointer returns the value pointed to by the pointer.
// Play: todo
// Play: https://go.dev/play/p/wAp90V7Zu6g
func FromPointer[T any](ptr *T) T {
if ptr == nil {
var zeroValue T
@@ -250,7 +250,7 @@ func FromPointer[T any](ptr *T) T {
}
// FromPointers convert a slice of pointers to a slice of values.
// Play: todo
// Play: https://go.dev/play/p/qIPsyYtNy3Q
func FromPointers[T any](pointers []*T) []T {
result := make([]T, len(pointers))
for i, ptr := range pointers {

View File

@@ -169,6 +169,45 @@ func ExampleToPointer() {
// 123
}
func ExampleToPointers() {
strs := []string{"a", "b", "c"}
pointerStrs := ToPointers(strs)
fmt.Println(*pointerStrs[0])
fmt.Println(*pointerStrs[1])
fmt.Println(*pointerStrs[2])
// Output:
// a
// b
// c
}
func ExampleFromPointer() {
str := "abc"
strPtr := &str
result := FromPointer(strPtr)
fmt.Println(result)
// Output:
// abc
}
func ExampleFromPointers() {
strs := []string{"a", "b", "c"}
strPtr := []*string{&strs[0], &strs[1], &strs[2]}
result := FromPointers(strPtr)
fmt.Println(result[0])
fmt.Println(result[1])
fmt.Println(result[2])
// Output:
// a
// b
// c
}
func ExampleToMap() {
type Message struct {
name string

View File

@@ -1,51 +1,51 @@
-----BEGIN rsa private key-----
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
-----END rsa private key-----

View File

@@ -1,14 +1,14 @@
-----BEGIN rsa public key-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAv25yPU83rpR+acaNoyEO
rIBo3gBcykscNL1vbMDbYc5jYib7BvxoOkdfeIhjTIDfMVzkzBXAC0eNbMey1/nC
cjoFNPXDShsyig8paDl7PG0IVOYpuXDQ/vi82F7rrXehESrImIBPPDTrZWeg3jqF
VkZt6QnB/j7dMKPMeJcarLvwMDKqTM3xguPAAoCAEy9Lylu2zncI8BPyhvz+++j0
jBdRl8RYHUyE60BIEROFcHI7lnWMoH/Uj8cWu8aTRPtNZdk4l9hBHotfi7qvO9b4
jB/75Qko/MY5YyrohAwQN/f9zVuTtlfFxKCb1+5Lxq4v4llwUv9eA7euMJf/nDU2
9m4Oshu7snkYgwB4Cd+bVqS8z9vW+brXtP6ZZTJls6pBX4FFukNkCUgiNBuUVDO0
4AUNSBfAxiHXS88zLdrTRIfM9MdgoGQapqHaiieQ4GdFbndKfck0AfoSXy0NtWOX
4/IZWUphqnyAKO1w8hzK1iydgv4mHpjKr5I3sh1ARh9baNUXLH2A9rTQvk3fXsK7
RRkwP8gH9BKvtQiHfVVqAh9MPdPygHiOUgGgqTQj2xb1KXS1yzJVcgDFYNv8NrE1
M8EdCaItfRWU7MkzecGriQFQ42AvIMFLMyD25hXDj/mZgaw1CgGoemMJoAm+yu1N
RUB4dW1vHqn/UxhcWHrLhJsCAwEAAQ==
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuzBz+aC+e7Lvny2zYlcy
AfG6AAtPkxZqJ9JkYkM+0CP87pe0xOXQh4dz9iJekOwAq7FKpasUEUzkTm6Z0PUo
j/TWY/xpoPNXXzz/5dz3u6r/A5TumJ6BmX/7K/x8FsokIeP+lWaN1l+7uBKK8rgf
m4AZOXd/plzBkTrnu6lKG/rH9cnr2leKWDqk2jcG6r15r/07MdStpWgt0OBYoHzv
jLJWmJ08VrnF9PFtWhL939xSAIicFzJ0T9fAdmSSYmg22mKgN1zeWtZndJ/Ejv+5
YlWmuFJ8YKvwR0+4XIRLX9qsMy7qPTh7zsZhgtKzyb7qvVqDh2pmwekGJcwxGcoC
LHLqNKf/dD+4vXxgS+f1ObfOcJpDqBajD/U6BXtrZ/p4cvoYnZA383YR/CRG/nJ8
jIvt2FutT4hsNSd0L6c2mfo5mTnoDOEL3mkreZ4Az+GE57jMw1Ia9jwkM1QQoy0a
+kTiW8BedNqcRnVVGT9/OS/ggyKFwxJ/Xh1DfxZXAuyCBRUJUyVl9YCr2y30zngu
CdaTTViA9UbrjtcE2bZtnqOMAU2s08F0IiaGLKKMhrxUoXLgngXSX7gomC4aEfcg
5hf7ft6FA+bXB9DHwGdv/UyrGr88nve5um1OT5kmyOujKpka4QZ5/rU+RznBE0UW
DcHAyc+Zv+te0DqPUNcAW5ECAwEAAQ==
-----END rsa public key-----

View File

@@ -114,6 +114,7 @@ export const enConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
],
},
{ text: 'datetime', link: '/en/api/packages/datetime' },
{ text: 'enum', link: '/en/api/packages/enum' },
{ text: 'eventbus', link: '/en/api/packages/eventbus' },
{ text: 'fileutil', link: '/en/api/packages/fileutil' },
{ text: 'formatter', link: '/en/api/packages/formatter' },
@@ -128,9 +129,9 @@ export const enConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
{ text: 'stream', link: '/en/api/packages/stream' },
{ text: 'struct', link: '/en/api/packages/struct' },
{ text: 'strutil', link: '/en/api/packages/strutil' },
{ text: 'system', link: '/en/api/packages/system' },
{ text: 'tuple', link: '/en/api/packages/tuple' },
{ text: 'validator', link: '/en/api/packages/validator' },
{ text: 'system', link: '/en/api/packages/system' },
{ text: 'xerror', link: '/en/api/packages/xerror' },
],
},

View File

@@ -128,7 +128,7 @@ export const zhConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
},
{ text: '日期&时间', link: '/api/packages/datetime' },
{ text: '事件总线', link: '/api/packages/eventbus' },
{ text: '文件', link: '/api/packages/fileutil' },
{ text: '文件处理', link: '/api/packages/fileutil' },
{ text: '格式化工具', link: '/api/packages/formatter' },
{ text: '函数', link: '/api/packages/function' },
{ text: '数学工具', link: '/api/packages/mathutil' },
@@ -141,9 +141,10 @@ export const zhConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
{ text: '流', link: '/api/packages/stream' },
{ text: '结构体', link: '/api/packages/struct' },
{ text: '字符串', link: '/api/packages/strutil' },
{ text: '系统', link: '/api/packages/system' },
{ text: '枚举', link: '/api/packages/enum' },
{ text: '元组', link: '/api/packages/tuple' },
{ text: '验证器', link: '/api/packages/validator' },
{ text: '系统工具函数', link: '/api/packages/system' },
{ text: '错误处理', link: '/api/packages/xerror' },
],
},

View File

@@ -46,6 +46,7 @@ outline: deep
<div class="package-cell">cryptor</div>
<div class="package-cell">datastructure</div>
<div class="package-cell">datetime</div>
<div class="package-cell">enum</div>
<div class="package-cell">eventbus</div>
<div class="package-cell">fileutil</div>
<div class="package-cell">formatter</div>

View File

@@ -33,6 +33,9 @@ import (
- [ToJson](#ToJson)
- [ToMap](#ToMap)
- [ToPointer](#ToPointer)
- [ToPointers](#ToPointers)
- [FromPointer](#FromPointer)
- [FromPointers](#FromPointers)
- [ToString](#ToString)
- [StructToMap](#StructToMap)
- [MapToSlice](#MapToSlice)
@@ -456,6 +459,108 @@ func main() {
}
```
### <span id="ToPointers">ToPointers</span>
<p>将值的切片转换为指针的切片。</p>
<b>函数签名:</b>
```go
func ToPointers[T any](values []T) []*T
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/ZUoXd2i5ZkV)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/convertor"
)
func main() {
strs := []string{"a", "b", "c"}
pointerStrs := convertor.ToPointers(strs)
fmt.Println(*pointerStrs[0])
fmt.Println(*pointerStrs[1])
fmt.Println(*pointerStrs[2])
// Output:
// a
// b
// c
}
```
### <span id="FromPointer">FromPointer</span>
<p>返回指针所指向的值。</p>
<b>函数签名:</b>
```go
func FromPointer[T any](ptr *T) T
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/wAp90V7Zu6g)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/convertor"
)
func main() {
str := "abc"
strPtr := &str
result := convertor.FromPointer(strPtr)
fmt.Println(result)
// Output:
// abc
}
```
### <span id="FromPointers">FromPointers</span>
<p>将指针的切片转换为值的切片。</p>
<b>函数签名:</b>
```go
func FromPointers[T any](pointers []*T) []T
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/qIPsyYtNy3Q)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/convertor"
)
func main() {
strs := []string{"a", "b", "c"}
strPtr := []*string{&strs[0], &strs[1], &strs[2]}
result := convertor.FromPointers(strPtr)
fmt.Println(result[0])
fmt.Println(result[1])
fmt.Println(result[2])
// Output:
// a
// b
// c
}
```
### <span id="ToString">ToString</span>
<p>将值转换为字符串,对于数字、字符串、[]byte将转换为字符串。 对于其他类型(切片、映射、数组、结构体)将调用 json.Marshal</p>
@@ -1179,4 +1284,4 @@ func main() {
// Output:
// 9876543210
}
```
```

850
docs/api/packages/enum.md Normal file
View File

@@ -0,0 +1,850 @@
# Enum
Enum 实现一个简单枚举工具包。
<div STYLE="page-break-after: always;"></div>
## 源码:
- [https://github.com/duke-git/lancet/blob/main/enum/enum.go](https://github.com/duke-git/lancet/blob/main/enum/enum.go)
<div STYLE="page-break-after: always;"></div>
## 用法:
```go
import (
"github.com/duke-git/lancet/v2/enum"
)
```
<div STYLE="page-break-after: always;"></div>
## 目录
- [NewItem](#NewItem)
- [NewItemsFromPairs](#NewItemsFromPairs)
- [Value](#Value)
- [Name](#Name)
- [Valid](#Valid)
- [MarshalJSON](#MarshalJSON)
- [NewRegistry](#NewRegistry)
- [Add](#Add)
- [Remove](#Remove)
- [Update](#Update)
- [GetByValue](#GetByValue)
- [GetByName](#GetByName)
- [Items](#Items)
- [Contains](#Contains)
- [Size](#Size)
- [Range](#Range)
- [SortedItems](#SortedItems)
- [Filter](#Filter)
<div STYLE="page-break-after: always;"></div>
## 文档
### <span id="NewItem">NewItem</span>
<p>创建枚举项。</p>
<b>函数签名:</b>
```go
func NewItem[T comparable](value T, name string) *Item[T]
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/8qNsLw01HD5)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
item1 := enum.NewItem(Active, "Active")
item2 := enum.NewItem(Inactive, "Inactive")
fmt.Println(item1.Name(), item1.Value())
fmt.Println(item2.Name(), item2.Value())
// Output:
// Active 1
// Inactive 2
}
```
### <span id="NewItemsFromPairs">NewItemsFromPairs</span>
<p>从Pair结构体的切片创建枚举项。</p>
<b>函数签名:</b>
```go
func NewItemsFromPairs[T comparable](pairs ...Pair[T]) []*Item[T]
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/xKnoGa7gnev)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
items := enum.NewItemsFromPairs(
enum.Pair[Status]{Value: Active, Name: "Active"},
enum.Pair[Status]{Value: Inactive, Name: "Inactive"},
)
fmt.Println(items[0].Name(), items[0].Value())
fmt.Println(items[1].Name(), items[1].Value())
// Output:
// Active 1
// Inactive 2
}
```
### <span id="Value">Value</span>
<p>返回枚举项的值。</p>
<b>函数签名:</b>
```go
func (it *Item[T]) Value() T
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/xKnoGa7gnev)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
items := enum.NewItemsFromPairs(
enum.Pair[Status]{Value: Active, Name: "Active"},
enum.Pair[Status]{Value: Inactive, Name: "Inactive"},
)
fmt.Println(items[0].Name(), items[0].Value())
fmt.Println(items[1].Name(), items[1].Value())
// Output:
// Active 1
// Inactive 2
}
```
### <span id="Name">Name</span>
<p>返回枚举项的名称。</p>
<b>函数签名:</b>
```go
func (it *Item[T]) Name() string
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/xKnoGa7gnev)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
items := enum.NewItemsFromPairs(
enum.Pair[Status]{Value: Active, Name: "Active"},
enum.Pair[Status]{Value: Inactive, Name: "Inactive"},
)
fmt.Println(items[0].Name(), items[0].Value())
fmt.Println(items[1].Name(), items[1].Value())
// Output:
// Active 1
// Inactive 2
}
```
### <span id="Valid">Valid</span>
<p>检查枚举项是否有效。如果提供了自定义检查函数,将使用该函数验证值。</p>
<b>函数签名:</b>
```go
func (it *Item[T]) Valid(checker ...func(T) bool) bool
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/pA3lYY2VSm3)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
item := enum.NewItem(Active, "Active")
fmt.Println(item.Valid())
invalidItem := enum.NewItem(Unknown, "")
fmt.Println(invalidItem.Valid())
// Output:
// true
// false
}
```
### <span id="MarshalJSON">MarshalJSON</span>
<p>枚举项实现json.Marshaler接口。</p>
<b>函数签名:</b>
```go
func (it *Item[T]) MarshalJSON() ([]byte, error)
func (it *Item[T]) UnmarshalJSON(data []byte) error
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/zIZEdAnneB5)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
item := enum.NewItem(Active, "Active")
data, _ := item.MarshalJSON()
fmt.Println(string(data))
var unmarshaledItem enum.Item[Status]
_ = unmarshaledItem.UnmarshalJSON(data)
fmt.Println(unmarshaledItem.Name(), unmarshaledItem.Value())
// Output:
// {"name":"Active","value":1}
// Active 1
}
```
### <span id="NewRegistry">NewRegistry</span>
<p>Registry 定义了一个通用的枚举注册表结构体。</p>
<b>函数签名:</b>
```go
func NewRegistry[T comparable](items ...*Item[T]) *Registry[T]
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/ABEXsYfJKMo)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item1 := enum.NewItem(Active, "Active")
item2 := enum.NewItem(Inactive, "Inactive")
registry.Add(item1, item2)
if item, found := registry.GetByValue(Active); found {
fmt.Println("Found by value:", item.Name())
}
if item, found := registry.GetByName("Inactive"); found {
fmt.Println("Found by name:", item.Value())
}
// Output:
// Found by value: Active
// Found by name: 2
}
```
### <span id="Add">Add</span>
<p>向枚举注册表添加枚举项。</p>
<b>函数签名:</b>
```go
func (r *Registry[T]) Add(items ...*Item[T])
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/ABEXsYfJKMo)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item1 := enum.NewItem(Active, "Active")
item2 := enum.NewItem(Inactive, "Inactive")
registry.Add(item1, item2)
if item, found := registry.GetByValue(Active); found {
fmt.Println("Found by value:", item.Name())
}
if item, found := registry.GetByName("Inactive"); found {
fmt.Println("Found by name:", item.Value())
}
// Output:
// Found by value: Active
// Found by name: 2
}
```
### <span id="Remove">Remove</span>
<p>在枚举注册表中删除枚举项。</p>
<b>函数签名:</b>
```go
func (r *Registry[T]) Remove(value T) bool
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/dSG84wQ3TuC)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item1 := enum.NewItem(Active, "Active")
registry.Add(item1)
fmt.Println("Size before removal:", registry.Size())
removed := registry.Remove(Active)
fmt.Println("Removed:", removed)
fmt.Println("Size after removal:", registry.Size())
// Output:
// Size before removal: 1
// Removed: true
// Size after removal: 0
}
```
### <span id="Update">Update</span>
<p>在枚举注册表中更新枚举项。</p>
<b>函数签名:</b>
```go
func (r *Registry[T]) Update(value T, newName string) bool
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/Ol0moT1J9Xl)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item1 := enum.NewItem(Active, "Active")
registry.Add(item1)
updated := registry.Update(Active, "Activated")
fmt.Println("Updated:", updated)
if item, found := registry.GetByValue(Active); found {
fmt.Println("New name:", item.Name())
}
// Output:
// Updated: true
// New name: Activated
}
```
### <span id="GetByValue">GetByValue</span>
<p>在枚举注册表中通过值获取枚举项。</p>
<b>函数签名:</b>
```go
func (r *Registry[T]) GetByValue(value T) (*Item[T], bool)
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/niJ1U2KlE_m)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item := enum.NewItem(Active, "Active")
registry.Add(item)
if item, found := registry.GetByValue(Active); found {
fmt.Println("Found name by value:", item.Name())
}
// Output:
// Found name by value: Active
}
```
### <span id="GetByName">GetByName</span>
<p>在枚举注册表中通过名称获取枚举项。</p>
<b>函数签名:</b>
```go
func (r *Registry[T]) GetByName(name string) (*Item[T], bool)
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/49ie_gpqH0m)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item := enum.NewItem(Active, "Active")
registry.Add(item)
if item, found := registry.GetByName("Active"); found {
fmt.Println("Found value by name:", item.Value())
}
// Output:
// Found value by name: 1
}
```
### <span id="Items">Items</span>
<p>返回枚举注册表中的枚举项。</p>
<b>函数签名:</b>
```go
func (r *Registry[T]) Items() []*Item[T]
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/lAJFAradbvQ)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item1 := enum.NewItem(Active, "Active")
item2 := enum.NewItem(Inactive, "Inactive")
registry.Add(item1, item2)
for _, item := range registry.Items() {
fmt.Println(item.Name(), item.Value())
}
// Output:
// Active 1
// Inactive 2
}
```
### <span id="Contains">Contains</span>
<p>检查注册表中是否存在具有给定值的枚举项。</p>
<b>函数签名:</b>
```go
func (r *Registry[T]) Contains(value T) bool
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/_T-lPYkZn2j)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item := enum.NewItem(Active, "Active")
registry.Add(item)
fmt.Println(registry.Contains(Active))
fmt.Println(registry.Contains(Inactive))
// Output:
// true
// false
}
```
### <span id="Size">Size</span>
<p>返回注册表中枚举项的数目。</p>
<b>函数签名:</b>
```go
func (r *Registry[T]) Size() int
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/TeDArWhlQe2)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
fmt.Println("Initial size:", registry.Size())
item1 := enum.NewItem(Active, "Active")
item2 := enum.NewItem(Inactive, "Inactive")
registry.Add(item1, item2)
fmt.Println("Size after adding items:", registry.Size())
registry.Remove(Active)
fmt.Println("Size after removing an item:", registry.Size())
// Output:
// Initial size: 0
// Size after adding items: 2
// Size after removing an item: 1
}
```
### <span id="Range">Range</span>
<p>遍历注册表中的所有枚举项,并应用给定的函数。</p>
<b>函数签名:</b>
```go
func (r *Registry[T]) Range(fn func(*Item[T]) bool)
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/GPsZbQbefWN)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item1 := enum.NewItem(Active, "Active")
item2 := enum.NewItem(Inactive, "Inactive")
registry.Add(item1, item2)
registry.Range(func(item *enum.Item[Status]) bool {
fmt.Println(item.Name(), item.Value())
return true // continue iteration
})
// Output:
// Active 1
// Inactive 2
}
```
### <span id="SortedItems">SortedItems</span>
<p>返回按给定比较函数排序的所有枚举项的切片。</p>
<b>函数签名:</b>
```go
func (r *Registry[T]) SortedItems(less func(*Item[T], *Item[T]) bool) []*Item[T]
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/tN9RE_m_WEI)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item1 := enum.NewItem(Inactive, "Inactive")
item2 := enum.NewItem(Active, "Active")
registry.Add(item1, item2)
for _, item := range registry.SortedItems(func(i1, i2 *enum.Item[Status]) bool {
return i1.Value() < i2.Value()
}) {
fmt.Println(item.Name(), item.Value())
}
// Output:
// Active 1
// Inactive 2
}
```
### <span id="Filter">Filter</span>
<p>返回满足给定谓词函数的枚举项切片。</p>
<b>函数签名:</b>
```go
func (r *Registry[T]) Filter(predicate func(*Item[T]) bool) []*Item[T]
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/uTUpTdcyoCU)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item1 := enum.NewItem(Active, "Active")
item2 := enum.NewItem(Inactive, "Inactive")
registry.Add(item1, item2)
activeItems := registry.Filter(func(item *enum.Item[Status]) bool {
return item.Value() == Active
})
for _, item := range activeItems {
fmt.Println(item.Name(), item.Value())
}
// Output:
// Active 1
}
```

View File

@@ -2357,8 +2357,8 @@ func main() {
编辑
func ToMarkdownTable(data []map[string]interface{}, headerMap map[string]string, columnOrder []string) string
```
<b>示例:<span style="float:right;display:inline-block;">[运行]()</span></b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/w_pSLfeyEB5)</span></b>
```go
package main
@@ -2410,4 +2410,4 @@ func main() {
// |50000|Alice|
// |60000|Bob|
}
```
```

View File

@@ -27,6 +27,7 @@ import (
- [Contain](#Contain)
- [ContainBy](#ContainBy)
- [ContainSubSlice](#ContainSubSlice)
- [ContainAny](#ContainAny)
- [Chunk](#Chunk)
- [Compact](#Compact)
- [Concat](#Concat)
@@ -256,6 +257,43 @@ func main() {
}
```
### <span id="ContainAny">ContainAny</span>
<p>判断slice是否包含targets切片中的任意一个元素</p>
<b>函数签名:</b>
```go
func ContainAny[T comparable](slice []T, targets []T) bool
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/4xoxhc9XSSw)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
result1 := slice.ContainAny([]string{"a", "b", "c"}, []string{"a"})
result2 := slice.ContainAny([]string{"a", "b", "c"}, []string{"d", "e"})
result3 := slice.ContainAny([]string{"a", "b", "c"}, []string{"d", "a"})
result4 := slice.ContainAny([]string{"a", "b", "c"}, []string{})
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
// Output:
// true
// false
// true
// false
}
```
### <span id="Chunk">Chunk</span>
<p>按照size参数均分slice</p>

View File

@@ -31,6 +31,7 @@ import (
- [IsStruct](#IsStruct)
- [Tag](#Tag)
- [Name](#Name)
- [TypeName](#TypeName)
- [Value](#Value)
- [Kind](#Kind)
- [IsEmbedded](#IsEmbedded)
@@ -53,7 +54,7 @@ import (
func New(value any, tagName ...string) *Struct
```
<b>示例:</b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/O29l8kk-Z17)</span></b>
```go
package main
@@ -68,7 +69,11 @@ func main() {
}
p1 := &People{Name: "11"}
s := structs.New(p1)
// to do something
fmt.Println(s.ToMap())
// Output:
// map[name:11] <nil>
}
```
@@ -88,7 +93,7 @@ func (s *Struct) ToMap() (map[string]any, error)
func ToMap(v any) (map[string]any, error)
```
<b>示例:</b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/qQbLySBgerZ)</span></b>
```go
package main
@@ -129,7 +134,7 @@ func main() {
func (s *Struct) Fields() []*Field
```
<b>示例:</b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/w3Kk_CyVY7D)</span></b>
```go
package main
@@ -161,10 +166,10 @@ func main() {
<b>函数签名:</b>
```go
func (s *Struct) Field(name string) *Field
func (s *Struct) Field(name string) (*Field, bool)
```
<b>示例:</b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/KocZMSYarza)</span></b>
```go
package main
@@ -180,12 +185,14 @@ func main() {
}
p1 := &People{Name: "11"}
s := structs.New(p1)
f := s.Field("Name")
f, found := s.Field("Name")
fmt.Println(f.Value())
fmt.Println(found)
// Output:
// 11
// true
}
```
@@ -199,7 +206,7 @@ func main() {
func (s *Struct) IsStruct() bool
```
<b>示例:</b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/bU2FSdkbK1C)</span></b>
```go
package main
@@ -233,7 +240,7 @@ func main() {
func (f *Field) Tag() *Tag
```
<b>示例:</b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/DVrx5HvvUJr)</span></b>
```go
package main
@@ -254,7 +261,7 @@ func main() {
tag := n.Tag()
fmt.Println(tag.Name)
// Output:
// name
}
@@ -270,7 +277,7 @@ func main() {
func (f *Field) Value() any
```
<b>示例:</b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/qufYEU2o4Oi)</span></b>
```go
package main
@@ -288,10 +295,10 @@ func main() {
s := structs.New(p1)
n, _ := s.Field("Name")
fmt.Println(n.Value())
// Output:
// Output:
// 111
}
```
@@ -306,7 +313,7 @@ func main() {
func (f *Field) IsEmbedded() bool
```
<b>示例:</b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/wV2PrbYm3Ec)</span></b>
```go
package main
@@ -331,11 +338,11 @@ func main() {
s := structs.New(c1)
n, _ := s.Field("Name")
a, _ := s.Field("Age")
fmt.Println(n.IsEmbedded())
fmt.Println(a.IsEmbedded())
// Output:
// Output:
// true
// false
}
@@ -351,7 +358,7 @@ func main() {
func (f *Field) IsExported() bool
```
<b>示例:</b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/csK4AXYaNbJ)</span></b>
```go
package main
@@ -370,11 +377,11 @@ func main() {
s := structs.New(p1)
n, _ := s.Field("Name")
a, _ := s.Field("age")
fmt.Println(n.IsExported())
fmt.Println(a.IsExported())
// Output:
// Output:
// true
// false
}
@@ -390,7 +397,7 @@ func main() {
func (f *Field) IsZero() bool
```
<b>示例:</b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/RzqpGISf87r)</span></b>
```go
package main
@@ -409,11 +416,11 @@ func main() {
s := structs.New(p1)
n, _ := s.Field("Name")
a, _ := s.Field("Age")
fmt.Println(n.IsZero())
fmt.Println(a.IsZero())
// Output:
// Output:
// true
// false
}
@@ -429,7 +436,7 @@ func main() {
func (f *Field) Name() string
```
<b>示例:</b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/zfIGlqsatee)</span></b>
```go
package main
@@ -448,11 +455,11 @@ func main() {
s := structs.New(p1)
n, _ := s.Field("Name")
a, _ := s.Field("Age")
fmt.Println(n.Name())
fmt.Println(a.Name())
// Output:
// Output:
// Name
// Age
}
@@ -468,7 +475,7 @@ func main() {
func (f *Field) Kind() reflect.Kind
```
<b>示例:</b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/wg4NlcUNG5o)</span></b>
```go
package main
@@ -487,16 +494,52 @@ func main() {
s := structs.New(p1)
n, _ := s.Field("Name")
a, _ := s.Field("Age")
fmt.Println(n.Kind())
fmt.Println(a.Kind())
// Output:
// Output:
// string
// int
}
```
### <span id="TypeName">TypeName</span>
<p>获取结构体类型名。</p>
<b>函数签名:</b>
```go
func (s *Struct) TypeName() string
```
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/SWLWd0XBaBb)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/structs"
)
func main() {
type Parent struct {
Name string
Age int
}
p := &Parent{Age: 11}
s := structs.New(p)
fmt.Println(s.TypeName())
// Output:
// Parent
}
```
### <span id="IsSlice">IsSlice</span>
<p>判断属性是否是切片</p>
@@ -507,7 +550,7 @@ func main() {
func (f *Field) IsSlice() bool
```
<b>示例:</b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/MKz4CgBIUrU)</span></b>
```go
package main
@@ -526,10 +569,10 @@ func main() {
p1 := &Parent{arr: []int{1, 2, 3}}
s := structs.New(p1)
a, _ := s.Field("arr")
fmt.Println(a.IsSlice())
// Output:
// Output:
// true
}
```
@@ -544,7 +587,7 @@ func main() {
func (f *Field) IsTargetType(targetType reflect.Kind) bool
```
<b>示例:</b>
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/Ig75P-agN39)</span></b>
```go
package main
@@ -565,12 +608,12 @@ func main() {
s := structs.New(p1)
n, _ := s.Field("Name")
a, _ := s.Field("arr")
fmt.Println(n.IsTargetType(reflect.String))
fmt.Println(a.IsTargetType(reflect.Slice))
// Output:
// Output:
// true
// true
}
```
```

View File

@@ -65,6 +65,8 @@ import (
- [IsAmericanExpress](#IsAmericanExpress)
- [IsUnionPay](#IsUnionPay)
- [IsChinaUnionPay](#IsChinaUnionPay)
- [IsPassport](#IsPassport)
- [IsChineseHMPassport](#IsChineseHMPassport)
<div STYLE="page-break-after: always;"></div>
@@ -844,20 +846,20 @@ import (
func main() {
result1 := validator.IsAlphaNumeric("ABC")
result2 := validator.IsAlphaNumeric("123")
result3 := validator.IsAlphaNumeric("abc123")
result4 := validator.IsAlphaNumeric("abc123@#$")
result2 := validator.IsAlphaNumeric("123")
result3 := validator.IsAlphaNumeric("abc123")
result4 := validator.IsAlphaNumeric("abc123@#$")
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
// Output:
// true
// true
// true
// false
// Output:
// true
// true
// true
// false
}
```
@@ -1550,6 +1552,8 @@ func IsChinaUnionPay(v string) bool
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/yafpdxLiymu)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
@@ -1567,3 +1571,82 @@ func main() {
// false
}
```
### <span id="IsPassport">IsPassport</span>
<p>判断护照(正则判断)。</p>
<b>函数签名:</b>
```go
func IsPassport(passport, country string) bool
```
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/dvOiV2BW7Aw)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsPassport("P123456789", "CN")
result2 := validator.IsPassport("123456789", "US")
result3 := validator.IsPassport("AB1234567", "RU")
result4 := validator.IsPassport("123456789", "CN")
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
// Output:
// true
// true
// true
// false
}
```
### <span id="IsChineseHMPassport">IsChineseHMPassport</span>
<p>判断港澳台通行证(正则判断)。</p>
<b>函数签名:</b>
```go
func IsChineseHMPassport(hmPassport string) bool
```
<b>示例:<span style="float:right;display:inline-block">[运行](https://go.dev/play/p/xKG6spQTcY0)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsChineseHMPassport("C12345678")
result2 := validator.IsChineseHMPassport("C00000000")
result3 := validator.IsChineseHMPassport("M12345678")
result4 := validator.IsChineseHMPassport("c12345678")
result5 := validator.IsChineseHMPassport("C1234567")
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
fmt.Println(result5)
// Output:
// true
// true
// true
// false
// false
}
```

View File

@@ -46,6 +46,7 @@ outline: deep
<div class="package-cell">cryptor</div>
<div class="package-cell">datastructure</div>
<div class="package-cell">datetime</div>
<div class="package-cell">enum</div>
<div class="package-cell">eventbus</div>
<div class="package-cell">fileutil</div>
<div class="package-cell">formatter</div>

View File

@@ -33,6 +33,9 @@ import (
- [ToJson](#ToJson)
- [ToMap](#ToMap)
- [ToPointer](#ToPointer)
- [ToPointers](#ToPointers)
- [FromPointer](#FromPointer)
- [FromPointers](#FromPointers)
- [ToString](#ToString)
- [StructToMap](#StructToMap)
- [MapToSlice](#MapToSlice)
@@ -456,6 +459,108 @@ func main() {
}
```
### <span id="ToPointers">ToPointers</span>
<p>Convert a slice of values to a slice of pointers.</p>
<b>Signature:</b>
```go
func ToPointers[T any](values []T) []*T
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/ZUoXd2i5ZkV)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/convertor"
)
func main() {
strs := []string{"a", "b", "c"}
pointerStrs := convertor.ToPointers(strs)
fmt.Println(*pointerStrs[0])
fmt.Println(*pointerStrs[1])
fmt.Println(*pointerStrs[2])
// Output:
// a
// b
// c
}
```
### <span id="FromPointer">FromPointer</span>
<p>Returns the value pointed to by the pointer.</p>
<b>Signature:</b>
```go
func FromPointer[T any](ptr *T) T
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/wAp90V7Zu6g)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/convertor"
)
func main() {
str := "abc"
strPtr := &str
result := convertor.FromPointer(strPtr)
fmt.Println(result)
// Output:
// abc
}
```
### <span id="FromPointers">FromPointers</span>
<p>Convert a slice of pointers to a slice of values.</p>
<b>Signature:</b>
```go
func FromPointers[T any](pointers []*T) []T
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/qIPsyYtNy3Q)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/convertor"
)
func main() {
strs := []string{"a", "b", "c"}
strPtr := []*string{&strs[0], &strs[1], &strs[2]}
result := convertor.FromPointers(strPtr)
fmt.Println(result[0])
fmt.Println(result[1])
fmt.Println(result[2])
// Output:
// a
// b
// c
}
```
### <span id="ToString">ToString</span>
<p>ToString convert value to string, for number, string, []byte, will convert to string. For other type (slice, map, array, struct) will call json.Marshal</p>
@@ -572,7 +677,6 @@ func main() {
}
```
### <span id="EncodeByte">EncodeByte</span>
<p>Encode data to byte slice.</p>
@@ -638,7 +742,6 @@ func main() {
}
```
### <span id="CopyProperties">CopyProperties</span>
<p>Copies each field from the source struct into the destination struct. Use json.Marshal/Unmarshal, so json tag should be set for fields of dst and src struct.</p>
@@ -748,7 +851,7 @@ func main() {
// Output:
// true
// true
// true
}
```
@@ -781,7 +884,7 @@ func main() {
// Output:
// true
// hello
// hello
}
```
@@ -857,8 +960,6 @@ func main() {
```
### <span id="ToUrlBase64">ToUrlBase64</span>
<p>Convert a value to a string encoded in url Base64. Error data of type "error" will also be encoded, and complex structures will be converted to a JSON formatted string.</p>
@@ -1147,4 +1248,4 @@ func main() {
// Output:
// 9876543210
}
```
```

View File

@@ -0,0 +1,850 @@
# Enum
Package enum provides a simple enum implementation.
<div STYLE="page-break-after: always;"></div>
## Source:
- [https://github.com/duke-git/lancet/blob/main/enum/enum.go](https://github.com/duke-git/lancet/blob/main/enum/enum.go)
<div STYLE="page-break-after: always;"></div>
## Usage:
```go
import (
"github.com/duke-git/lancet/v2/enum"
)
```
<div STYLE="page-break-after: always;"></div>
## Index
- [NewItem](#NewItem)
- [NewItemsFromPairs](#NewItemsFromPairs)
- [Value](#Value)
- [Name](#Name)
- [Valid](#Valid)
- [MarshalJSON](#MarshalJSON)
- [NewRegistry](#NewRegistry)
- [Add](#Add)
- [Remove](#Remove)
- [Update](#Update)
- [GetByValue](#GetByValue)
- [GetByName](#GetByName)
- [Items](#Items)
- [Contains](#Contains)
- [Size](#Size)
- [Range](#Range)
- [SortedItems](#SortedItems)
- [Filter](#Filter)
<div STYLE="page-break-after: always;"></div>
## Documentation
### <span id="NewItem">NewItem</span>
<p>Creates a new enum item.</p>
<b>Signature:</b>
```go
func NewItem[T comparable](value T, name string) *Item[T]
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/8qNsLw01HD5)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
item1 := enum.NewItem(Active, "Active")
item2 := enum.NewItem(Inactive, "Inactive")
fmt.Println(item1.Name(), item1.Value())
fmt.Println(item2.Name(), item2.Value())
// Output:
// Active 1
// Inactive 2
}
```
### <span id="NewItemsFromPairs">NewItemsFromPairs</span>
<p>Creates enum items from a slice of Pair structs.</p>
<b>Signature:</b>
```go
func NewItemsFromPairs[T comparable](pairs ...Pair[T]) []*Item[T]
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/xKnoGa7gnev)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
items := enum.NewItemsFromPairs(
enum.Pair[Status]{Value: Active, Name: "Active"},
enum.Pair[Status]{Value: Inactive, Name: "Inactive"},
)
fmt.Println(items[0].Name(), items[0].Value())
fmt.Println(items[1].Name(), items[1].Value())
// Output:
// Active 1
// Inactive 2
}
```
### <span id="Value">Value</span>
<p>Returns the value of the enum item.</p>
<b>Signature:</b>
```go
func (it *Item[T]) Value() T
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/xKnoGa7gnev)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
items := enum.NewItemsFromPairs(
enum.Pair[Status]{Value: Active, Name: "Active"},
enum.Pair[Status]{Value: Inactive, Name: "Inactive"},
)
fmt.Println(items[0].Name(), items[0].Value())
fmt.Println(items[1].Name(), items[1].Value())
// Output:
// Active 1
// Inactive 2
}
```
### <span id="Name">Name</span>
<p>Returns the name of the enum item.</p>
<b>Signature:</b>
```go
func (it *Item[T]) Name() string
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/xKnoGa7gnev)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
items := enum.NewItemsFromPairs(
enum.Pair[Status]{Value: Active, Name: "Active"},
enum.Pair[Status]{Value: Inactive, Name: "Inactive"},
)
fmt.Println(items[0].Name(), items[0].Value())
fmt.Println(items[1].Name(), items[1].Value())
// Output:
// Active 1
// Inactive 2
}
```
### <span id="Valid">Valid</span>
<p>Checks if the enum item is valid. If a custom check function is provided, it will be used to validate the value.</p>
<b>Signature:</b>
```go
func (it *Item[T]) Valid(checker ...func(T) bool) bool
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/pA3lYY2VSm3)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
item := enum.NewItem(Active, "Active")
fmt.Println(item.Valid())
invalidItem := enum.NewItem(Unknown, "")
fmt.Println(invalidItem.Valid())
// Output:
// true
// false
}
```
### <span id="MarshalJSON">MarshalJSON</span>
<p>Implementation of json.Marshaler interface.</p>
<b>Signature:</b>
```go
func (it *Item[T]) MarshalJSON() ([]byte, error)
func (it *Item[T]) UnmarshalJSON(data []byte) error
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/zIZEdAnneB5)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
item := enum.NewItem(Active, "Active")
data, _ := item.MarshalJSON()
fmt.Println(string(data))
var unmarshaledItem enum.Item[Status]
_ = unmarshaledItem.UnmarshalJSON(data)
fmt.Println(unmarshaledItem.Name(), unmarshaledItem.Value())
// Output:
// {"name":"Active","value":1}
// Active 1
}
```
### <span id="NewRegistry">NewRegistry</span>
<p>Creates a new enum registry.</p>
<b>Signature:</b>
```go
func NewRegistry[T comparable](items ...*Item[T]) *Registry[T]
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/ABEXsYfJKMo)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item1 := enum.NewItem(Active, "Active")
item2 := enum.NewItem(Inactive, "Inactive")
registry.Add(item1, item2)
if item, found := registry.GetByValue(Active); found {
fmt.Println("Found by value:", item.Name())
}
if item, found := registry.GetByName("Inactive"); found {
fmt.Println("Found by name:", item.Value())
}
// Output:
// Found by value: Active
// Found by name: 2
}
```
### <span id="Add">Add</span>
<p>Adds enum items to the registry.</p>
<b>Signature:</b>
```go
func (r *Registry[T]) Add(items ...*Item[T])
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/ABEXsYfJKMo)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item1 := enum.NewItem(Active, "Active")
item2 := enum.NewItem(Inactive, "Inactive")
registry.Add(item1, item2)
if item, found := registry.GetByValue(Active); found {
fmt.Println("Found by value:", item.Name())
}
if item, found := registry.GetByName("Inactive"); found {
fmt.Println("Found by name:", item.Value())
}
// Output:
// Found by value: Active
// Found by name: 2
}
```
### <span id="Remove">Remove</span>
<p>Removes an enum item from the registry by its value.</p>
<b>Signature:</b>
```go
func (r *Registry[T]) Remove(value T) bool
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/dSG84wQ3TuC)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item1 := enum.NewItem(Active, "Active")
registry.Add(item1)
fmt.Println("Size before removal:", registry.Size())
removed := registry.Remove(Active)
fmt.Println("Removed:", removed)
fmt.Println("Size after removal:", registry.Size())
// Output:
// Size before removal: 1
// Removed: true
// Size after removal: 0
}
```
### <span id="Update">Update</span>
<p>Updates the name of an enum item in the registry by its value.</p>
<b>Signature:</b>
```go
func (r *Registry[T]) Update(value T, newName string) bool
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/Ol0moT1J9Xl)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item1 := enum.NewItem(Active, "Active")
registry.Add(item1)
updated := registry.Update(Active, "Activated")
fmt.Println("Updated:", updated)
if item, found := registry.GetByValue(Active); found {
fmt.Println("New name:", item.Name())
}
// Output:
// Updated: true
// New name: Activated
}
```
### <span id="GetByValue">GetByValue</span>
<p>Retrieves an enum item by its value.</p>
<b>Signature:</b>
```go
func (r *Registry[T]) GetByValue(value T) (*Item[T], bool)
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/niJ1U2KlE_m)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item := enum.NewItem(Active, "Active")
registry.Add(item)
if item, found := registry.GetByValue(Active); found {
fmt.Println("Found name by value:", item.Name())
}
// Output:
// Found name by value: Active
}
```
### <span id="GetByName">GetByName</span>
<p>Retrieves an enum item by its name.</p>
<b>Signature:</b>
```go
func (r *Registry[T]) GetByName(name string) (*Item[T], bool)
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/49ie_gpqH0m)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item := enum.NewItem(Active, "Active")
registry.Add(item)
if item, found := registry.GetByName("Active"); found {
fmt.Println("Found value by name:", item.Value())
}
// Output:
// Found value by name: 1
}
```
### <span id="Items">Items</span>
<p>Returns a slice of all enum items in the registry.</p>
<b>Signature:</b>
```go
func (r *Registry[T]) Items() []*Item[T]
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/lAJFAradbvQ)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item1 := enum.NewItem(Active, "Active")
item2 := enum.NewItem(Inactive, "Inactive")
registry.Add(item1, item2)
for _, item := range registry.Items() {
fmt.Println(item.Name(), item.Value())
}
// Output:
// Active 1
// Inactive 2
}
```
### <span id="Contains">Contains</span>
<p>Checks if an enum item with the given value exists in the registry.</p>
<b>Signature:</b>
```go
func (r *Registry[T]) Contains(value T) bool
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/_T-lPYkZn2j)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item := enum.NewItem(Active, "Active")
registry.Add(item)
fmt.Println(registry.Contains(Active))
fmt.Println(registry.Contains(Inactive))
// Output:
// true
// false
}
```
### <span id="Size">Size</span>
<p>Returns the number of enum items in the registry.</p>
<b>Signature:</b>
```go
func (r *Registry[T]) Size() int
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/TeDArWhlQe2)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
fmt.Println("Initial size:", registry.Size())
item1 := enum.NewItem(Active, "Active")
item2 := enum.NewItem(Inactive, "Inactive")
registry.Add(item1, item2)
fmt.Println("Size after adding items:", registry.Size())
registry.Remove(Active)
fmt.Println("Size after removing an item:", registry.Size())
// Output:
// Initial size: 0
// Size after adding items: 2
// Size after removing an item: 1
}
```
### <span id="Range">Range</span>
<p>Iterates over all enum items in the registry and applies the given function.</p>
<b>Signature:</b>
```go
func (r *Registry[T]) Range(fn func(*Item[T]) bool)
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/GPsZbQbefWN)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item1 := enum.NewItem(Active, "Active")
item2 := enum.NewItem(Inactive, "Inactive")
registry.Add(item1, item2)
registry.Range(func(item *enum.Item[Status]) bool {
fmt.Println(item.Name(), item.Value())
return true // continue iteration
})
// Output:
// Active 1
// Inactive 2
}
```
### <span id="SortedItems">SortedItems</span>
<p>Returns a slice of all enum items sorted by the given less function.</p>
<b>Signature:</b>
```go
func (r *Registry[T]) SortedItems(less func(*Item[T], *Item[T]) bool) []*Item[T]
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/tN9RE_m_WEI)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item1 := enum.NewItem(Inactive, "Inactive")
item2 := enum.NewItem(Active, "Active")
registry.Add(item1, item2)
for _, item := range registry.SortedItems(func(i1, i2 *enum.Item[Status]) bool {
return i1.Value() < i2.Value()
}) {
fmt.Println(item.Name(), item.Value())
}
// Output:
// Active 1
// Inactive 2
}
```
### <span id="Filter">Filter</span>
<p>Returns a slice of enum items that satisfy the given predicate function.</p>
<b>Signature:</b>
```go
func (r *Registry[T]) Filter(predicate func(*Item[T]) bool) []*Item[T]
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/uTUpTdcyoCU)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/enum"
)
type Status int
const (
Unknown Status = iota
Active
Inactive
)
func main() {
registry := enum.NewRegistry[Status]()
item1 := enum.NewItem(Active, "Active")
item2 := enum.NewItem(Inactive, "Inactive")
registry.Add(item1, item2)
activeItems := registry.Filter(func(item *enum.Item[Status]) bool {
return item.Value() == Active
})
for _, item := range activeItems {
fmt.Println(item.Name(), item.Value())
}
// Output:
// Active 1
}
```

View File

@@ -79,6 +79,7 @@ import (
- [SortByKey](#SortByKey)
- [GetOrDefault](#GetOrDefault)
- [FindValuesBy](#FindValuesBy)
- [ToMarkdownTable](#ToMarkdownTable)
<div STYLE="page-break-after: always;"></div>
@@ -2363,3 +2364,69 @@ func main() {
// [b d]
}
```
### <span id="ToMarkdownTable">ToMarkdownTable</span>
<p>Convert a map slice data to a Markdown table string. It supports custom header display names and column display order.</p>
<b>Signature:</b>
```go
编辑
func ToMarkdownTable(data []map[string]interface{}, headerMap map[string]string, columnOrder []string) string
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/w_pSLfeyEB5)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/maputil"
)
func main() {
// basic usage: automatically extract column names from data as table headers
data := []map[string]interface{}{
{"name": "Alice", "age": 25, "salary": 50000},
{"name": "Bob", "age": 30, "salary": 60000},
}
result := maputil.ToMarkdownTable(data, nil, nil)
fmt.Println(result)
// output:
// |name|age|salary|
// |---|---|---|
// |Alice|25|50000|
// |Bob|30|60000|
// custom header name
headerMap := map[string]string{
"name": "n",
"age": "a",
"salary": "s",
}
result = maputil.ToMarkdownTable(data, headerMap, nil)
fmt.Println(result)
// ouput:
// |m|a|s|
// |---|---|---|
// |Alice|25|50000|
// |Bob|30|60000|
// custom column display order
columnOrder := []string{"salary", "name"}
result = maputil.ToMarkdownTable(data, nil, columnOrder)
fmt.Println(result)
// output:
// |salary|name|
// |---|---|
// |50000|Alice|
// |60000|Bob|
}
```

View File

@@ -27,6 +27,7 @@ import (
- [Contain](#Contain)
- [ContainBy](#ContainBy)
- [ContainSubSlice](#ContainSubSlice)
- [ContainAny](#ContainAny)
- [Chunk](#Chunk)
- [Compact](#Compact)
- [Concat](#Concat)
@@ -256,6 +257,43 @@ func main() {
}
```
### <span id="ContainAny">ContainAny</span>
<p>Check if the slice contains any element from the targets slice.</p>
<b>Signature:</b>
```go
func ContainAny[T comparable](slice []T, targets []T) bool
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/4xoxhc9XSSw)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
result1 := slice.ContainAny([]string{"a", "b", "c"}, []string{"a"})
result2 := slice.ContainAny([]string{"a", "b", "c"}, []string{"d", "e"})
result3 := slice.ContainAny([]string{"a", "b", "c"}, []string{"d", "a"})
result4 := slice.ContainAny([]string{"a", "b", "c"}, []string{})
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
// Output:
// true
// false
// true
// false
}
```
### <span id="Chunk">Chunk</span>
<p>Creates an slice of elements split into groups the length of `size`.</p>

View File

@@ -31,6 +31,7 @@ import (
- [IsStruct](#IsStruct)
- [Tag](#Tag)
- [Name](#Name)
- [TypeName](#TypeName)
- [Value](#Value)
- [Kind](#Kind)
- [IsEmbedded](#IsEmbedded)
@@ -53,12 +54,13 @@ import (
func New(value any, tagName ...string) *Struct
```
<b>Example:</b>
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/O29l8kk-Z17)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/structs"
)
@@ -68,7 +70,11 @@ func main() {
}
p1 := &People{Name: "11"}
s := structs.New(p1)
// to do something
fmt.Println(s.ToMap())
// Output:
// map[name:11] <nil>
}
```
@@ -88,7 +94,7 @@ func (s *Struct) ToMap() (map[string]any, error)
func ToMap(v any) (map[string]any, error)
```
<b>Example:</b>
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/qQbLySBgerZ)</span></b>
```go
package main
@@ -130,7 +136,7 @@ func main() {
func (s *Struct) Fields() []*Field
```
<b>Example:</b>
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/w3Kk_CyVY7D)</span></b>
```go
package main
@@ -162,10 +168,10 @@ func main() {
<b>Signature:</b>
```go
func (s *Struct) Field(name string) *Field
func (s *Struct) Field(name string) (*Field, bool)
```
<b>Example:</b>
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/KocZMSYarza)</span></b>
```go
package main
@@ -181,12 +187,14 @@ func main() {
}
p1 := &People{Name: "11"}
s := structs.New(p1)
f := s.Field("Name")
f, found := s.Field("Name")
fmt.Println(f.Value())
fmt.Println(found)
// Output:
// 11
// true
}
```
@@ -200,7 +208,7 @@ func main() {
func (s *Struct) IsStruct() bool
```
<b>Example:</b>
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/bU2FSdkbK1C)</span></b>
```go
package main
@@ -234,7 +242,7 @@ func main() {
func (f *Field) Tag() *Tag
```
<b>Example:</b>
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/DVrx5HvvUJr)</span></b>
```go
package main
@@ -271,7 +279,7 @@ func main() {
func (f *Field) Value() any
```
<b>Example:</b>
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/qufYEU2o4Oi)</span></b>
```go
package main
@@ -307,7 +315,7 @@ func main() {
func (f *Field) IsEmbedded() bool
```
<b>Example:</b>
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/wV2PrbYm3Ec)</span></b>
```go
package main
@@ -352,7 +360,7 @@ func main() {
func (f *Field) IsExported() bool
```
<b>Example:</b>
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/csK4AXYaNbJ)</span></b>
```go
package main
@@ -391,7 +399,7 @@ func main() {
func (f *Field) IsZero() bool
```
<b>Example:</b>
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/RzqpGISf87r)</span></b>
```go
package main
@@ -430,7 +438,7 @@ func main() {
func (f *Field) Name() string
```
<b>Example:</b>
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/zfIGlqsatee)</span></b>
```go
package main
@@ -469,7 +477,7 @@ func main() {
func (f *Field) Kind() reflect.Kind
```
<b>Example:</b>
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/wg4NlcUNG5o)</span></b>
```go
package main
@@ -498,6 +506,42 @@ func main() {
}
```
### <span id="TypeName">TypeName</span>
<p>Return struct type name.</p>
<b>Signature:</b>
```go
func (s *Struct) TypeName() string
```
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/SWLWd0XBaBb)</span></b>
```go
package main
import (
"fmt"
"github.com/duke-git/lancet/v2/structs"
)
func main() {
type Parent struct {
Name string
Age int
}
p := &Parent{Age: 11}
s := structs.New(p)
fmt.Println(s.TypeName())
// Output:
// Parent
}
```
### <span id="IsSlice">IsSlice</span>
<p>Check if the field is a slice</p>
@@ -508,7 +552,7 @@ func main() {
func (f *Field) IsSlice() bool
```
<b>Example:</b>
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/MKz4CgBIUrU)</span></b>
```go
package main
@@ -545,7 +589,7 @@ func main() {
func (f *Field) IsTargetType(targetType reflect.Kind) bool
```
<b>Example:</b>
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/Ig75P-agN39)</span></b>
```go
package main
@@ -566,12 +610,12 @@ func main() {
s := structs.New(p1)
n, _ := s.Field("Name")
a, _ := s.Field("arr")
fmt.Println(n.IsTargetType(reflect.String))
fmt.Println(a.IsTargetType(reflect.Slice))
// Output:
// Output:
// true
// true
}
```
```

View File

@@ -65,6 +65,8 @@ import (
- [IsAmericanExpress](#IsAmericanExpress)
- [IsUnionPay](#IsUnionPay)
- [IsChinaUnionPay](#IsChinaUnionPay)
- [IsPassport](#IsPassport)
- [IsChineseHMPassport](#IsChineseHMPassport)
<div STYLE="page-break-after: always;"></div>
@@ -1569,3 +1571,80 @@ func main() {
// false
}
```
### <span id="IsPassport">IsPassport</span>
<p>Passport validation(using regex).</p>
<b>Signature:</b>
```go
func IsPassport(passport, country string) bool
```
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/dvOiV2BW7Aw)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsPassport("P123456789", "CN")
result2 := validator.IsPassport("123456789", "US")
result3 := validator.IsPassport("AB1234567", "RU")
result4 := validator.IsPassport("123456789", "CN")
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
// Output:
// true
// true
// true
// false
}
```
### <span id="IsChineseHMPassport">IsChineseHMPassport</span>
<p>Mainland travel permit for Hong Kong, Macao validation (using regex). </p>
<b>Signature:</b>
```go
func IsChineseHMPassport(hmPassport string) bool
```
<b>Example:<span style="float:right;display:inline-block">[Run](https://go.dev/play/p/xKG6spQTcY0)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/validator"
)
func main() {
result1 := validator.IsChineseHMPassport("C12345678")
result2 := validator.IsChineseHMPassport("C00000000")
result3 := validator.IsChineseHMPassport("M12345678")
result4 := validator.IsChineseHMPassport("c12345678")
result5 := validator.IsChineseHMPassport("C1234567")
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
fmt.Println(result5)
// Output:
// true
// true
// true
// false
// false
}
```

526
docs/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -26,6 +26,8 @@ type Item[T comparable] struct {
name string
}
// NewItem creates a new enum item.
// Play: https://go.dev/play/p/8qNsLw01HD5
func NewItem[T comparable](value T, name string) *Item[T] {
return &Item[T]{value: value, name: name}
}
@@ -37,7 +39,8 @@ type Pair[T comparable] struct {
}
// NewItemsFromPairs creates enum items from a slice of Pair structs.
func NewItems[T comparable](pairs ...Pair[T]) []*Item[T] {
// Play: https://go.dev/play/p/xKnoGa7gnev
func NewItemsFromPairs[T comparable](pairs ...Pair[T]) []*Item[T] {
if len(pairs) == 0 {
return []*Item[T]{}
}
@@ -50,37 +53,45 @@ func NewItems[T comparable](pairs ...Pair[T]) []*Item[T] {
return items
}
func (e *Item[T]) Value() T {
return e.value
// Value returns the value of the enum item.
// Play: https://go.dev/play/p/xKnoGa7gnev
func (it *Item[T]) Value() T {
return it.value
}
func (e *Item[T]) Name() string {
return e.name
// Name returns the name of the enum item.
// Play: https://go.dev/play/p/xKnoGa7gnev
func (it *Item[T]) Name() string {
return it.name
}
func (e *Item[T]) String() string {
return e.name
// String returns the string representation of the enum item.
func (it *Item[T]) String() string {
return it.name
}
// Valid checks if the enum item is valid. If a custom check function is provided, it will be used to validate the value.
func (e *Item[T]) Valid(checker ...func(T) bool) bool {
// Play: https://go.dev/play/p/pA3lYY2VSm3
func (it *Item[T]) Valid(checker ...func(T) bool) bool {
if len(checker) > 0 {
return checker[0](e.value) && e.name != ""
return checker[0](it.value) && it.name != ""
}
var zero T
return e.value != zero && e.name != ""
return it.value != zero && it.name != ""
}
// MarshalJSON implements the json.Marshaler interface.
func (e *Item[T]) MarshalJSON() ([]byte, error) {
// Play: https://go.dev/play/p/zIZEdAnneB5
func (it *Item[T]) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]any{
"value": e.value,
"name": e.name,
"value": it.value,
"name": it.name,
})
}
// UnmarshalJSON implements the json.Unmarshaler interface.
func (e *Item[T]) UnmarshalJSON(data []byte) error {
// Play: https://go.dev/play/p/zIZEdAnneB5
func (it *Item[T]) UnmarshalJSON(data []byte) error {
type alias struct {
Value any `json:"value"`
Name string `json:"name"`
@@ -99,48 +110,47 @@ func (e *Item[T]) UnmarshalJSON(data []byte) error {
return fmt.Errorf("invalid type for value, want int family")
}
converted := reflect.ValueOf(int64(val)).Convert(rv)
e.value = converted.Interface().(T)
it.value = converted.Interface().(T)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
val, ok := temp.Value.(float64)
if !ok {
return fmt.Errorf("invalid type for value, want uint family")
}
converted := reflect.ValueOf(uint64(val)).Convert(rv)
e.value = converted.Interface().(T)
it.value = converted.Interface().(T)
case reflect.Float32, reflect.Float64:
val, ok := temp.Value.(float64)
if !ok {
return fmt.Errorf("invalid type for value, want float family")
}
converted := reflect.ValueOf(val).Convert(rv)
e.value = converted.Interface().(T)
it.value = converted.Interface().(T)
case reflect.String:
val, ok := temp.Value.(string)
if !ok {
return fmt.Errorf("invalid type for value, want string")
}
e.value = any(val).(T)
it.value = any(val).(T)
case reflect.Bool:
val, ok := temp.Value.(bool)
if !ok {
return fmt.Errorf("invalid type for value, want bool")
}
e.value = any(val).(T)
it.value = any(val).(T)
default:
// 枚举类型底层通常是 int可以尝试 float64->int64->底层类型
val, ok := temp.Value.(float64)
if ok {
converted := reflect.ValueOf(int64(val)).Convert(rv)
e.value = converted.Interface().(T)
it.value = converted.Interface().(T)
} else {
val2, ok2 := temp.Value.(T)
if !ok2 {
return fmt.Errorf("invalid type for value")
}
e.value = val2
it.value = val2
}
}
e.name = temp.Name
it.name = temp.Name
return nil
}
@@ -152,6 +162,8 @@ type Registry[T comparable] struct {
items []*Item[T]
}
// NewRegistry creates a new enum registry.
// Play: https://go.dev/play/p/ABEXsYfJKMo
func NewRegistry[T comparable](items ...*Item[T]) *Registry[T] {
r := &Registry[T]{
values: make(map[T]*Item[T]),
@@ -165,6 +177,7 @@ func NewRegistry[T comparable](items ...*Item[T]) *Registry[T] {
}
// Add adds enum items to the registry.
// Play: https://go.dev/play/p/ABEXsYfJKMo
func (r *Registry[T]) Add(items ...*Item[T]) {
r.mu.Lock()
defer r.mu.Unlock()
@@ -184,6 +197,7 @@ func (r *Registry[T]) Add(items ...*Item[T]) {
}
// Remove removes an enum item from the registry by its value.
// Play: https://go.dev/play/p/dSG84wQ3TuC
func (r *Registry[T]) Remove(value T) bool {
r.mu.Lock()
defer r.mu.Unlock()
@@ -203,6 +217,7 @@ func (r *Registry[T]) Remove(value T) bool {
}
// Update updates the name of an enum item in the registry by its value.
// Play: https://go.dev/play/p/Ol0moT1J9Xl
func (r *Registry[T]) Update(value T, newName string) bool {
r.mu.Lock()
defer r.mu.Unlock()
@@ -217,6 +232,7 @@ func (r *Registry[T]) Update(value T, newName string) bool {
}
// GetByValue retrieves an enum item by its value.
// Play: https://go.dev/play/p/niJ1U2KlE_m
func (r *Registry[T]) GetByValue(value T) (*Item[T], bool) {
r.mu.RLock()
defer r.mu.RUnlock()
@@ -226,6 +242,7 @@ func (r *Registry[T]) GetByValue(value T) (*Item[T], bool) {
}
// GetByName retrieves an enum item by its name.
// Play: https://go.dev/play/p/49ie_gpqH0m
func (r *Registry[T]) GetByName(name string) (*Item[T], bool) {
r.mu.RLock()
defer r.mu.RUnlock()
@@ -235,6 +252,7 @@ func (r *Registry[T]) GetByName(name string) (*Item[T], bool) {
}
// Items returns a slice of all enum items in the registry.
// Play: https://go.dev/play/p/lAJFAradbvQ
func (r *Registry[T]) Items() []*Item[T] {
r.mu.RLock()
defer r.mu.RUnlock()
@@ -245,30 +263,14 @@ func (r *Registry[T]) Items() []*Item[T] {
}
// Contains checks if an enum item with the given value exists in the registry.
// Play: https://go.dev/play/p/_T-lPYkZn2j
func (r *Registry[T]) Contains(value T) bool {
_, ok := r.GetByValue(value)
return ok
}
// Validate checks if the given value is a valid enum item in the registry.
func (r *Registry[T]) Validate(value T) error {
if !r.Contains(value) {
return fmt.Errorf("invalid enum value: %v", value)
}
return nil
}
// ValidateAll checks if all given values are valid enum items in the registry.
func (r *Registry[T]) ValidateAll(values ...T) error {
for _, value := range values {
if err := r.Validate(value); err != nil {
return err
}
}
return nil
}
// Size returns the number of enum items in the registry.
// Play: https://go.dev/play/p/TeDArWhlQe2
func (r *Registry[T]) Size() int {
r.mu.RLock()
defer r.mu.RUnlock()
@@ -277,6 +279,7 @@ func (r *Registry[T]) Size() int {
}
// Range iterates over all enum items in the registry and applies the given function.
// Play: https://go.dev/play/p/GPsZbQbefWN
func (r *Registry[T]) Range(fn func(*Item[T]) bool) {
r.mu.RLock()
defer r.mu.RUnlock()
@@ -289,6 +292,7 @@ func (r *Registry[T]) Range(fn func(*Item[T]) bool) {
}
// SortedItems returns a slice of all enum items sorted by the given less function.
// Play: https://go.dev/play/p/tN9RE_m_WEI
func (r *Registry[T]) SortedItems(less func(*Item[T], *Item[T]) bool) []*Item[T] {
items := r.Items()
sort.Slice(items, func(i, j int) bool {
@@ -298,6 +302,7 @@ func (r *Registry[T]) SortedItems(less func(*Item[T], *Item[T]) bool) []*Item[T]
}
// Filter returns a slice of enum items that satisfy the given predicate function.
// Play: https://go.dev/play/p/uTUpTdcyoCU
func (r *Registry[T]) Filter(predicate func(*Item[T]) bool) []*Item[T] {
r.mu.RLock()
defer r.mu.RUnlock()

View File

@@ -3,7 +3,19 @@ package enum
import "fmt"
func ExampleNewItem() {
items := NewItems(
item1 := NewItem(Active, "Active")
item2 := NewItem(Inactive, "Inactive")
fmt.Println(item1.Name(), item1.Value())
fmt.Println(item2.Name(), item2.Value())
// Output:
// Active 1
// Inactive 2
}
func ExampleNewItemsFromPairs() {
items := NewItemsFromPairs(
Pair[Status]{Value: Active, Name: "Active"},
Pair[Status]{Value: Inactive, Name: "Inactive"},
)
@@ -114,41 +126,15 @@ func ExampleRegistry_Items() {
func ExampleRegistry_Contains() {
registry := NewRegistry[Status]()
item1 := NewItem(Active, "Active")
registry.Add(item1)
item := NewItem(Active, "Active")
registry.Add(item)
fmt.Println("Contains Active:", registry.Contains(Active))
fmt.Println("Contains Inactive:", registry.Contains(Inactive))
}
func ExampleRegistry_Validate() {
registry := NewRegistry[Status]()
item1 := NewItem(Active, "Active")
item2 := NewItem(Inactive, "Inactive")
registry.Add(item1, item2)
fmt.Println("Validate Active:", registry.Validate(Active))
fmt.Println("Validate Inactive:", registry.Validate(Inactive))
fmt.Println("Validate Unknown:", registry.Validate(Unknown))
fmt.Println(registry.Contains(Active))
fmt.Println(registry.Contains(Inactive))
// Output:
// Validate Active: <nil>
// Validate Inactive: <nil>
// Validate Unknown: invalid enum value: 0
}
func ExampleRegistry_ValidateAll() {
registry := NewRegistry[Status]()
item1 := NewItem(Active, "Active")
item2 := NewItem(Inactive, "Inactive")
registry.Add(item1, item2)
fmt.Println("ValidateAll Active, Inactive:", registry.ValidateAll(Active, Inactive))
fmt.Println("ValidateAll Active, Unknown:", registry.ValidateAll(Active, Unknown))
// Output:
// ValidateAll Active, Inactive: <nil>
// ValidateAll Active, Unknown: invalid enum value: 0
// true
// false
}
func ExampleRegistry_Size() {

View File

@@ -17,11 +17,11 @@ const (
Inactive
)
func TestNewItem(t *testing.T) {
func TestNewItemsFromPairs(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestNewItem")
assert := internal.NewAssert(t, "TestNewItemsFromPairs")
items := NewItems(
items := NewItemsFromPairs(
Pair[Status]{Value: Active, Name: "Active"},
Pair[Status]{Value: Inactive, Name: "Inactive"},
)
@@ -128,40 +128,6 @@ func TestRegistry_Contains(t *testing.T) {
assert.Equal(false, registry.Contains(Inactive))
}
func TestRegistry_Validate(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestRegistry_Validate")
registry := NewRegistry[Status]()
item1 := NewItem(Active, "Active")
item2 := NewItem(Inactive, "Inactive")
registry.Add(item1, item2)
err := registry.Validate(Active)
assert.IsNil(err)
err = registry.Validate(Inactive)
assert.IsNil(err)
err = registry.Validate(Unknown)
assert.IsNotNil(err)
}
func TestRegistry_ValidateAll(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestRegistry_ValidateAll")
registry := NewRegistry[Status]()
item1 := NewItem(Active, "Active")
item2 := NewItem(Inactive, "Inactive")
registry.Add(item1, item2)
err := registry.ValidateAll(Active, Inactive)
assert.IsNil(err)
err = registry.ValidateAll(Active, Unknown)
assert.IsNotNil(err)
}
func TestRegistry_Range(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestRegistry_Range")

View File

@@ -683,6 +683,7 @@ func FindValuesBy[K comparable, V any](m map[K]V, predicate func(key K, value V)
}
// ToMarkdownTable converts a slice of maps to a Markdown table.
// Play: ttps://go.dev/play/p/w_pSLfeyEB5
func ToMarkdownTable(data []map[string]interface{}, headerMap map[string]string, columnOrder []string) string {
if len(data) == 0 {
return "| |\n|---|\n"

View File

@@ -74,6 +74,27 @@ func ContainSubSlice[T comparable](slice, subSlice []T) bool {
return true
}
// ContainAny check if the slice contains any element from the targets slice.
// Play: https://go.dev/play/p/4xoxhc9XSSw
func ContainAny[T comparable](slice []T, targets []T) bool {
if len(targets) == 0 {
return false
}
sliceMap := make(map[T]struct{}, len(slice))
for _, item := range slice {
sliceMap[item] = struct{}{}
}
for _, target := range targets {
if _, exists := sliceMap[target]; exists {
return true
}
}
return false
}
// Chunk creates a slice of elements split into groups the length of size.
// Play: https://go.dev/play/p/b4Pou5j2L_C
func Chunk[T any](slice []T, size int) [][]T {

View File

@@ -58,6 +58,24 @@ func ExampleContainSubSlice() {
// false
}
func ExampleContainAny() {
result1 := ContainAny([]string{"a", "b", "c"}, []string{"a"})
result2 := ContainAny([]string{"a", "b", "c"}, []string{"d", "e"})
result3 := ContainAny([]string{"a", "b", "c"}, []string{"d", "a"})
result4 := ContainAny([]string{"a", "b", "c"}, []string{})
fmt.Println(result1)
fmt.Println(result2)
fmt.Println(result3)
fmt.Println(result4)
// Output:
// true
// false
// true
// false
}
func ExampleChunk() {
arr := []string{"a", "b", "c", "d", "e"}

View File

@@ -89,6 +89,46 @@ func TestContainSubSlice(t *testing.T) {
}
}
func TestContainAny(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestContainAny")
tests := []struct {
slice []string
targets []string
want bool
}{
{[]string{"a", "b", "c"}, []string{"a"}, true},
{[]string{"a", "b", "c"}, []string{"a", "b"}, true},
{[]string{"a", "b", "c"}, []string{"d", "e"}, false},
{[]string{"a", "b", "c"}, []string{"d", "a"}, true},
{[]string{"a", "b", "c"}, []string{}, false},
{[]string{}, []string{"a"}, false},
{[]string{}, []string{}, false},
{[]string{"a", "b", "c"}, []string{"c", "d", "e"}, true},
}
for _, tt := range tests {
assert.Equal(tt.want, ContainAny(tt.slice, tt.targets))
}
intTests := []struct {
slice []int
targets []int
want bool
}{
{[]int{1, 2, 3, 4, 5}, []int{3}, true},
{[]int{1, 2, 3, 4, 5}, []int{6, 7}, false},
{[]int{1, 2, 3, 4, 5}, []int{5, 6, 7}, true},
{[]int{1, 2, 3, 4, 5}, []int{}, false},
}
for _, tt := range intTests {
assert.Equal(tt.want, ContainAny(tt.slice, tt.targets))
}
}
func TestChunk(t *testing.T) {
t.Parallel()

View File

@@ -26,26 +26,31 @@ func newField(v reflect.Value, f reflect.StructField, tagName string) *Field {
}
// Tag returns the value that the key in the tag string.
// Play: https://go.dev/play/p/DVrx5HvvUJr
func (f *Field) Tag() *Tag {
return f.tag
}
// Value returns the underlying value of the field.
// Play: https://go.dev/play/p/qufYEU2o4Oi
func (f *Field) Value() any {
return f.rvalue.Interface()
}
// IsEmbedded returns true if the given field is an embedded field.
// Play: https://go.dev/play/p/wV2PrbYm3Ec
func (f *Field) IsEmbedded() bool {
return len(f.field.Index) > 1
}
// IsExported returns true if the given field is exported.
// Play: https://go.dev/play/p/csK4AXYaNbJ
func (f *Field) IsExported() bool {
return f.field.IsExported()
}
// IsZero returns true if the given field is zero value.
// Play: https://go.dev/play/p/RzqpGISf87r
func (f *Field) IsZero() bool {
z := reflect.Zero(f.rvalue.Type()).Interface()
v := f.Value()
@@ -63,22 +68,26 @@ func (f *Field) IsNil() bool {
}
// Name returns the name of the given field
// Play: https://go.dev/play/p/zfIGlqsatee
func (f *Field) Name() string {
return f.field.Name
}
// Kind returns the field's kind
// Play: https://go.dev/play/p/wg4NlcUNG5o
func (f *Field) Kind() reflect.Kind {
return f.rvalue.Kind()
}
// IsSlice check if a struct field type is slice or not
// Play: https://go.dev/play/p/MKz4CgBIUrU
func (f *Field) IsSlice() bool {
k := f.rvalue.Kind()
return k == reflect.Slice
}
// IsTargetType check if a struct field type is target type or not
// Play: https://go.dev/play/p/Ig75P-agN39
func (f *Field) IsTargetType(targetType reflect.Kind) bool {
return f.rvalue.Kind() == targetType
}

View File

@@ -20,6 +20,7 @@ type Struct struct {
}
// New returns a new *Struct
// Play: https://go.dev/play/p/O29l8kk-Z17
func New(value any, tagName ...string) *Struct {
value = pointer.ExtractPointer(value)
v := reflect.ValueOf(value)
@@ -60,6 +61,7 @@ func New(value any, tagName ...string) *Struct {
// Name string `json:"myName"`
//
// ToMap convert the exported fields of a struct to map.
// Play: https://go.dev/play/p/qQbLySBgerZ
func (s *Struct) ToMap() (map[string]any, error) {
if !s.IsStruct() {
return nil, fmt.Errorf("invalid struct %v", s)
@@ -87,6 +89,7 @@ func (s *Struct) ToMap() (map[string]any, error) {
}
// Fields returns all the struct fields within a slice
// Play: https://go.dev/play/p/w3Kk_CyVY7D
func (s *Struct) Fields() []*Field {
fieldNum := s.rvalue.NumField()
fields := make([]*Field, 0, fieldNum)
@@ -100,6 +103,7 @@ func (s *Struct) Fields() []*Field {
}
// Field returns a Field if the given field name was found
// Play: https://go.dev/play/p/KocZMSYarza
func (s *Struct) Field(name string) (*Field, bool) {
f, ok := s.rtype.FieldByName(name)
if !ok {
@@ -109,6 +113,7 @@ func (s *Struct) Field(name string) (*Field, bool) {
}
// IsStruct returns true if the given rvalue is a struct
// Play: https://go.dev/play/p/bU2FSdkbK1C
func (s *Struct) IsStruct() bool {
k := s.rvalue.Kind()
if k == reflect.Invalid {
@@ -119,11 +124,13 @@ func (s *Struct) IsStruct() bool {
// ToMap convert struct to map, only convert exported struct field
// map key is specified same as struct field tag `json` value.
// Play: https://go.dev/play/p/qQbLySBgerZ
func ToMap(v any) (map[string]any, error) {
return New(v).ToMap()
}
// TypeName return struct type name
// Play: https://go.dev/play/p/SWLWd0XBaBb
func (s *Struct) TypeName() string {
return s.rtype.Name()
}

View File

@@ -634,7 +634,7 @@ func IsChinaUnionPay(cardNo string) bool {
// IsPassport checks if the passport number is valid for a given country.
// country is a two-letter country code (ISO 3166-1 alpha-2).
// Play: todo
// Play: https://go.dev/play/p/dvOiV2BW7Aw
func IsPassport(passport, country string) bool {
if matcher, ok := passportMatcher[country]; ok {
return matcher.MatchString(passport)
@@ -645,7 +645,7 @@ func IsPassport(passport, country string) bool {
// IsChineseHMPassport checks if the string is a valid Chinese Hong Kong and Macau Travel Permit number.
// Chinese Hong Kong and Macau Travel Permit format: C or M + 8 digits (e.g., C12345678, M12345678).
// Play: https://go.dev/play/p/TODO
// Play: https://go.dev/play/p/xKG6spQTcY0
func IsChineseHMPassport(hmPassport string) bool {
return chineseHMPassportMatcher.MatchString(hmPassport)
}