mirror of
https://github.com/danielmiessler/fabric
synced 2024-11-08 07:11:06 +00:00
135 lines
2.9 KiB
Go
135 lines
2.9 KiB
Go
package common
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/samber/lo"
|
|
)
|
|
|
|
func NewGroupsItemsSelector[I any](selectionLabel string,
|
|
getItemLabel func(I) string) *GroupsItemsSelector[I] {
|
|
|
|
return &GroupsItemsSelector[I]{SelectionLabel: selectionLabel,
|
|
GetItemKey: getItemLabel,
|
|
GroupsItems: make([]*GroupItems[I], 0),
|
|
}
|
|
}
|
|
|
|
type GroupItems[I any] struct {
|
|
Group string
|
|
Items []I
|
|
}
|
|
|
|
func (o *GroupItems[I]) Count() int {
|
|
return len(o.Items)
|
|
}
|
|
|
|
func (o *GroupItems[I]) ContainsItemBy(predicate func(item I) bool) (ret bool) {
|
|
ret = lo.ContainsBy(o.Items, predicate)
|
|
return
|
|
}
|
|
|
|
type GroupsItemsSelector[I any] struct {
|
|
SelectionLabel string
|
|
GetItemKey func(I) string
|
|
|
|
GroupsItems []*GroupItems[I]
|
|
}
|
|
|
|
func (o *GroupsItemsSelector[I]) AddGroupItems(group string, items ...I) {
|
|
o.GroupsItems = append(o.GroupsItems, &GroupItems[I]{group, items})
|
|
}
|
|
|
|
func (o *GroupsItemsSelector[I]) GetGroupAndItemByItemNumber(number int) (group string, item I, err error) {
|
|
var currentItemNumber int
|
|
found := false
|
|
|
|
for _, groupItems := range o.GroupsItems {
|
|
if currentItemNumber+groupItems.Count() < number {
|
|
currentItemNumber += groupItems.Count()
|
|
continue
|
|
}
|
|
|
|
for _, groupItem := range groupItems.Items {
|
|
currentItemNumber++
|
|
if currentItemNumber == number {
|
|
group = groupItems.Group
|
|
item = groupItem
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
if !found {
|
|
err = fmt.Errorf("number %d is out of range", number)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (o *GroupsItemsSelector[I]) Print() {
|
|
fmt.Printf("\n%v:\n", o.SelectionLabel)
|
|
|
|
var currentItemIndex int
|
|
for _, groupItems := range o.GroupsItems {
|
|
fmt.Println()
|
|
fmt.Printf("%s\n", groupItems.Group)
|
|
fmt.Println()
|
|
|
|
for _, item := range groupItems.Items {
|
|
currentItemIndex++
|
|
fmt.Printf("\t[%d]\t%s\n", currentItemIndex, o.GetItemKey(item))
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
func (o *GroupsItemsSelector[I]) HasGroup(group string) (ret bool) {
|
|
for _, groupItems := range o.GroupsItems {
|
|
if ret = groupItems.Group == group; ret {
|
|
break
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (o *GroupsItemsSelector[I]) FindGroupsByItemFirst(item I) (ret string) {
|
|
itemKey := o.GetItemKey(item)
|
|
|
|
for _, groupItems := range o.GroupsItems {
|
|
if groupItems.ContainsItemBy(func(groupItem I) bool {
|
|
groupItemKey := o.GetItemKey(groupItem)
|
|
return groupItemKey == itemKey
|
|
}) {
|
|
ret = groupItems.Group
|
|
break
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (o *GroupsItemsSelector[I]) FindGroupsByItem(item I) (groups []string) {
|
|
itemKey := o.GetItemKey(item)
|
|
|
|
for _, groupItems := range o.GroupsItems {
|
|
if groupItems.ContainsItemBy(func(groupItem I) bool {
|
|
groupItemKey := o.GetItemKey(groupItem)
|
|
return groupItemKey == itemKey
|
|
}) {
|
|
groups = append(groups, groupItems.Group)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func ReturnItem(item string) string {
|
|
return item
|
|
}
|
|
|
|
func NewGroupsItemsSelectorString(selectionLabel string) *GroupsItemsSelectorString {
|
|
return &GroupsItemsSelectorString{GroupsItemsSelector: NewGroupsItemsSelector(selectionLabel, ReturnItem)}
|
|
}
|
|
|
|
type GroupsItemsSelectorString struct {
|
|
*GroupsItemsSelector[string]
|
|
}
|