mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-04 12:52:28 +08:00
feat: add example for enum package
This commit is contained in:
41
enum/enum.go
41
enum/enum.go
@@ -8,6 +8,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -15,6 +16,7 @@ import (
|
|||||||
type Enum[T comparable] interface {
|
type Enum[T comparable] interface {
|
||||||
Value() T
|
Value() T
|
||||||
String() string
|
String() string
|
||||||
|
Name() string
|
||||||
Valid() bool
|
Valid() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,6 +69,10 @@ func (e *Item[T]) Name() string {
|
|||||||
return e.name
|
return e.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Item[T]) String() string {
|
||||||
|
return e.name
|
||||||
|
}
|
||||||
|
|
||||||
// Valid checks if the enum item is valid. If a custom check function is provided, it will be used to validate the value.
|
// 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(check ...func(T) bool) bool {
|
func (e *Item[T]) Valid(check ...func(T) bool) bool {
|
||||||
if len(check) > 0 {
|
if len(check) > 0 {
|
||||||
@@ -280,3 +286,38 @@ func (r *Registry[T]) Size() int {
|
|||||||
|
|
||||||
return len(r.items)
|
return len(r.items)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Range iterates over all enum items in the registry and applies the given function.
|
||||||
|
func (r *Registry[T]) Range(fn func(*Item[T]) bool) {
|
||||||
|
r.mu.RLock()
|
||||||
|
defer r.mu.RUnlock()
|
||||||
|
|
||||||
|
for _, item := range r.items {
|
||||||
|
if !fn(item) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SortedItems returns a slice of all enum items sorted by the given less function.
|
||||||
|
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 {
|
||||||
|
return less(items[i], items[j])
|
||||||
|
})
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter returns a slice of enum items that satisfy the given predicate function.
|
||||||
|
func (r *Registry[T]) Filter(predicate func(*Item[T]) bool) []*Item[T] {
|
||||||
|
r.mu.RLock()
|
||||||
|
defer r.mu.RUnlock()
|
||||||
|
|
||||||
|
var result []*Item[T]
|
||||||
|
for _, item := range r.items {
|
||||||
|
if predicate(item) {
|
||||||
|
result = append(result, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|||||||
222
enum/enum_example_test.go
Normal file
222
enum/enum_example_test.go
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
package enum
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func ExampleNewItem() {
|
||||||
|
items := NewItems[Status](
|
||||||
|
Active, "Active",
|
||||||
|
Inactive, "Inactive",
|
||||||
|
)
|
||||||
|
|
||||||
|
fmt.Println(items[0].Name(), items[0].Value())
|
||||||
|
fmt.Println(items[1].Name(), items[1].Value())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Active 1
|
||||||
|
// Inactive 2
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleItem_Valid() {
|
||||||
|
item := NewItem(Active, "Active")
|
||||||
|
fmt.Println(item.Valid())
|
||||||
|
|
||||||
|
invalidItem := NewItem(Unknown, "")
|
||||||
|
fmt.Println(invalidItem.Valid())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleItem_MarshalJSON() {
|
||||||
|
item := NewItem(Active, "Active")
|
||||||
|
data, _ := item.MarshalJSON()
|
||||||
|
fmt.Println(string(data))
|
||||||
|
|
||||||
|
var unmarshaledItem Item[Status]
|
||||||
|
_ = unmarshaledItem.UnmarshalJSON(data)
|
||||||
|
fmt.Println(unmarshaledItem.Name(), unmarshaledItem.Value())
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// {"name":"Active","value":1}
|
||||||
|
// Active 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleRegistry_Add() {
|
||||||
|
registry := NewRegistry[Status]()
|
||||||
|
item1 := NewItem(Active, "Active")
|
||||||
|
item2 := 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
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleRegistry_Remove() {
|
||||||
|
registry := NewRegistry[Status]()
|
||||||
|
item1 := 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
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleRegistry_Update() {
|
||||||
|
registry := NewRegistry[Status]()
|
||||||
|
item1 := 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
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleRegistry_Items() {
|
||||||
|
registry := NewRegistry[Status]()
|
||||||
|
item1 := NewItem(Active, "Active")
|
||||||
|
item2 := NewItem(Inactive, "Inactive")
|
||||||
|
|
||||||
|
registry.Add(item1, item2)
|
||||||
|
|
||||||
|
for _, item := range registry.Items() {
|
||||||
|
fmt.Println(item.Name(), item.Value())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Active 1
|
||||||
|
// Inactive 2
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleRegistry_Contains() {
|
||||||
|
registry := NewRegistry[Status]()
|
||||||
|
item1 := NewItem(Active, "Active")
|
||||||
|
registry.Add(item1)
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleRegistry_Size() {
|
||||||
|
registry := NewRegistry[Status]()
|
||||||
|
fmt.Println("Initial size:", registry.Size())
|
||||||
|
|
||||||
|
item1 := NewItem(Active, "Active")
|
||||||
|
item2 := 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
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleRegistry_Range() {
|
||||||
|
registry := NewRegistry[Status]()
|
||||||
|
item1 := NewItem(Active, "Active")
|
||||||
|
item2 := NewItem(Inactive, "Inactive")
|
||||||
|
registry.Add(item1, item2)
|
||||||
|
|
||||||
|
registry.Range(func(item *Item[Status]) bool {
|
||||||
|
fmt.Println(item.Name(), item.Value())
|
||||||
|
return true // continue iteration
|
||||||
|
})
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Active 1
|
||||||
|
// Inactive 2
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleRegistry_SortedItems() {
|
||||||
|
registry := NewRegistry[Status]()
|
||||||
|
item1 := NewItem(Inactive, "Inactive")
|
||||||
|
item2 := NewItem(Active, "Active")
|
||||||
|
registry.Add(item1, item2)
|
||||||
|
|
||||||
|
for _, item := range registry.SortedItems(func(i1, i2 *Item[Status]) bool {
|
||||||
|
return i1.value < i2.value
|
||||||
|
}) {
|
||||||
|
fmt.Println(item.Name(), item.Value())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Active 1
|
||||||
|
// Inactive 2
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleRegistry_Filter() {
|
||||||
|
registry := NewRegistry[Status]()
|
||||||
|
item1 := NewItem(Active, "Active")
|
||||||
|
item2 := NewItem(Inactive, "Inactive")
|
||||||
|
registry.Add(item1, item2)
|
||||||
|
|
||||||
|
activeItems := registry.Filter(func(item *Item[Status]) bool {
|
||||||
|
return item.Value() == Active
|
||||||
|
})
|
||||||
|
|
||||||
|
for _, item := range activeItems {
|
||||||
|
fmt.Println(item.Name(), item.Value())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Active 1
|
||||||
|
}
|
||||||
@@ -161,3 +161,58 @@ func TestRegistry_ValidateAll(t *testing.T) {
|
|||||||
err = registry.ValidateAll(Active, Unknown)
|
err = registry.ValidateAll(Active, Unknown)
|
||||||
assert.IsNotNil(err)
|
assert.IsNotNil(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRegistry_Range(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
assert := internal.NewAssert(t, "TestRegistry_Range")
|
||||||
|
|
||||||
|
registry := NewRegistry[Status]()
|
||||||
|
item1 := NewItem(Active, "Active")
|
||||||
|
item2 := NewItem(Inactive, "Inactive")
|
||||||
|
registry.Add(item1, item2)
|
||||||
|
|
||||||
|
var values []Status
|
||||||
|
registry.Range(func(item *Item[Status]) bool {
|
||||||
|
values = append(values, item.Value())
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(2, len(values))
|
||||||
|
assert.Equal(Active, values[0])
|
||||||
|
assert.Equal(Inactive, values[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRegistry_SortedItems(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
assert := internal.NewAssert(t, "TestRegistry_SortedItems")
|
||||||
|
|
||||||
|
registry := NewRegistry[Status]()
|
||||||
|
item1 := NewItem(Inactive, "Inactive")
|
||||||
|
item2 := NewItem(Active, "Active")
|
||||||
|
registry.Add(item1, item2)
|
||||||
|
|
||||||
|
sortedItems := registry.SortedItems(func(i1, i2 *Item[Status]) bool {
|
||||||
|
return i1.value < i2.value
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(2, len(sortedItems))
|
||||||
|
assert.Equal(Active, sortedItems[0].Value())
|
||||||
|
assert.Equal(Inactive, sortedItems[1].Value())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRegistry_Filter(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
assert := internal.NewAssert(t, "TestRegistry_Filter")
|
||||||
|
|
||||||
|
registry := NewRegistry[Status]()
|
||||||
|
item1 := NewItem(Active, "Active")
|
||||||
|
item2 := NewItem(Inactive, "Inactive")
|
||||||
|
registry.Add(item1, item2)
|
||||||
|
|
||||||
|
filteredItems := registry.Filter(func(item *Item[Status]) bool {
|
||||||
|
return item.Value() == Active
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(1, len(filteredItems))
|
||||||
|
assert.Equal(Active, filteredItems[0].Value())
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user