1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-06-23 00:39:13 +02:00

make more use of generics

This commit is contained in:
Jesse Duffield
2022-03-19 12:26:30 +11:00
parent dde30fa104
commit c7a629c440
52 changed files with 3013 additions and 274 deletions

21
vendor/github.com/jesseduffield/generics/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Jesse Duffield
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,35 @@
package hashmap
func Keys[Key comparable, Value any](m map[Key]Value) []Key {
keys := make([]Key, 0, len(m))
for key := range m {
keys = append(keys, key)
}
return keys
}
func Values[Key comparable, Value any](m map[Key]Value) []Value {
values := make([]Value, 0, len(m))
for _, value := range m {
values = append(values, value)
}
return values
}
func TransformValues[Key comparable, Value any, NewValue any](
m map[Key]Value, fn func(Value) NewValue,
) map[Key]NewValue {
output := make(map[Key]NewValue)
for key, value := range m {
output[key] = fn(value)
}
return output
}
func TransformKeys[Key comparable, Value any, NewKey comparable](m map[Key]Value, fn func(Key) NewKey) map[NewKey]Value {
output := make(map[NewKey]Value)
for key, value := range m {
output[fn(key)] = value
}
return output
}

View File

@ -0,0 +1,49 @@
package list
import (
"golang.org/x/exp/slices"
)
type ComparableList[T comparable] struct {
*List[T]
}
func NewComparable[T comparable]() *ComparableList[T] {
return &ComparableList[T]{List: New[T]()}
}
func NewComparableFromSlice[T comparable](slice []T) *ComparableList[T] {
return &ComparableList[T]{List: NewFromSlice(slice)}
}
func (l *ComparableList[T]) Equal(other *ComparableList[T]) bool {
return l.EqualSlice(other.ToSlice())
}
func (l *ComparableList[T]) EqualSlice(other []T) bool {
return slices.Equal(l.ToSlice(), other)
}
func (l *ComparableList[T]) Compact() {
l.slice = slices.Compact(l.slice)
}
func (l *ComparableList[T]) Index(needle T) int {
return slices.Index(l.slice, needle)
}
func (l *ComparableList[T]) Contains(needle T) bool {
return slices.Contains(l.slice, needle)
}
func (l *ComparableList[T]) SortFuncInPlace(test func(a T, b T) bool) {
slices.SortFunc(l.slice, test)
}
func (l *ComparableList[T]) SortFunc(test func(a T, b T) bool) *ComparableList[T] {
newSlice := slices.Clone(l.slice)
slices.SortFunc(newSlice, test)
return NewComparableFromSlice(newSlice)
}

View File

@ -0,0 +1,72 @@
package list
func Some[T any](slice []T, test func(T) bool) bool {
for _, value := range slice {
if test(value) {
return true
}
}
return false
}
func Every[T any](slice []T, test func(T) bool) bool {
for _, value := range slice {
if !test(value) {
return false
}
}
return true
}
func Map[T any, V any](slice []T, f func(T) V) []V {
result := make([]V, len(slice))
for i, value := range slice {
result[i] = f(value)
}
return result
}
func MapInPlace[T any](slice []T, f func(T) T) {
for i, value := range slice {
slice[i] = f(value)
}
}
func Filter[T any](slice []T, test func(T) bool) []T {
result := make([]T, 0)
for _, element := range slice {
if test(element) {
result = append(result, element)
}
}
return result
}
func FilterInPlace[T any](slice []T, test func(T) bool) []T {
newLength := 0
for _, element := range slice {
if test(element) {
slice[newLength] = element
newLength++
}
}
return slice[:newLength]
}
func Reverse[T any](slice []T) []T {
result := make([]T, len(slice))
for i := range slice {
result[i] = slice[len(slice)-1-i]
}
return result
}
func ReverseInPlace[T any](slice []T) {
for i, j := 0, len(slice)-1; i < j; i, j = i+1, j-1 {
slice[i], slice[j] = slice[j], slice[i]
}
}

117
vendor/github.com/jesseduffield/generics/list/list.go generated vendored Normal file
View File

@ -0,0 +1,117 @@
package list
import (
"golang.org/x/exp/slices"
)
type List[T any] struct {
slice []T
}
func New[T any]() *List[T] {
return &List[T]{}
}
func NewFromSlice[T any](slice []T) *List[T] {
return &List[T]{slice: slice}
}
func (l *List[T]) ToSlice() []T {
return l.slice
}
// Mutative methods
func (l *List[T]) Push(v T) {
l.slice = append(l.slice, v)
}
func (l *List[T]) Pop() {
l.slice = l.slice[0 : len(l.slice)-1]
}
func (l *List[T]) Insert(index int, values ...T) {
l.slice = slices.Insert(l.slice, index, values...)
}
func (l *List[T]) Append(values ...T) {
l.slice = append(l.slice, values...)
}
func (l *List[T]) Prepend(values ...T) {
l.slice = append(values, l.slice...)
}
func (l *List[T]) Remove(index int) {
l.Delete(index, index+1)
}
func (l *List[T]) Delete(from int, to int) {
l.slice = slices.Delete(l.slice, from, to)
}
func (l *List[T]) FilterInPlace(test func(value T) bool) {
l.slice = FilterInPlace(l.slice, test)
}
func (l *List[T]) MapInPlace(f func(value T) T) {
MapInPlace(l.slice, f)
}
func (l *List[T]) ReverseInPlace() {
ReverseInPlace(l.slice)
}
// Non-mutative methods
// Similar to Append but we leave the original slice untouched and return a new list
func (l *List[T]) Concat(values ...T) *List[T] {
newSlice := make([]T, 0, len(l.slice)+len(values))
newSlice = append(newSlice, l.slice...)
newSlice = append(newSlice, values...)
return &List[T]{slice: newSlice}
}
func (l *List[T]) Filter(test func(value T) bool) *List[T] {
return NewFromSlice(Filter(l.slice, test))
}
// Unfortunately this does not support mapping from one type to another
// because Go does not yet (and may never) support methods defining their own
// type parameters. For that functionality you'll need to use the standalone
// Map function instead
func (l *List[T]) Map(f func(value T) T) *List[T] {
return NewFromSlice(Map(l.slice, f))
}
func (l *List[T]) Clone() *List[T] {
return NewFromSlice(slices.Clone(l.slice))
}
func (l *List[T]) Some(test func(value T) bool) bool {
return Some(l.slice, test)
}
func (l *List[T]) Every(test func(value T) bool) bool {
return Every(l.slice, test)
}
func (l *List[T]) IndexFunc(f func(T) bool) int {
return slices.IndexFunc(l.slice, f)
}
func (l *List[T]) ContainsFunc(f func(T) bool) bool {
return l.IndexFunc(f) != -1
}
func (l *List[T]) Reverse() *List[T] {
return NewFromSlice(Reverse(l.slice))
}
func (l *List[T]) IsEmpty() bool {
return len(l.slice) == 0
}
func (l *List[T]) Len() int {
return len(l.slice)
}

49
vendor/github.com/jesseduffield/generics/set/set.go generated vendored Normal file
View File

@ -0,0 +1,49 @@
package set
import "github.com/jesseduffield/generics/hashmap"
type Set[T comparable] struct {
hashMap map[T]bool
}
func New[T comparable]() *Set[T] {
return &Set[T]{hashMap: make(map[T]bool)}
}
func NewFromSlice[T comparable](slice []T) *Set[T] {
hashMap := make(map[T]bool)
for _, value := range slice {
hashMap[value] = true
}
return &Set[T]{hashMap: hashMap}
}
func (s *Set[T]) Add(value T) {
s.hashMap[value] = true
}
func (s *Set[T]) AddSlice(slice []T) {
for _, value := range slice {
s.Add(value)
}
}
func (s *Set[T]) Remove(value T) {
delete(s.hashMap, value)
}
func (s *Set[T]) RemoveSlice(slice []T) {
for _, value := range slice {
s.Remove(value)
}
}
func (s *Set[T]) Includes(value T) bool {
return s.hashMap[value]
}
// output slice is not necessarily in the same order that items were added
func (s *Set[T]) ToSlice() []T {
return hashmap.Keys(s.hashMap)
}