This commit is contained in:
Carlos Alexandro Becker
2025-07-22 20:35:39 -03:00
parent 7f10a03074
commit 9f66b30091
3 changed files with 1 additions and 1 deletions

34
internal/csync/slices.go Normal file
View File

@@ -0,0 +1,34 @@
package csync
import (
"iter"
"sync"
)
type LazySlice[K any] struct {
inner []K
mu sync.Mutex
}
func NewLazySlice[K any](load func() []K) *LazySlice[K] {
s := &LazySlice[K]{}
s.mu.Lock()
go func() {
s.inner = load()
s.mu.Unlock()
}()
return s
}
func (s *LazySlice[K]) Iter() iter.Seq[K] {
s.mu.Lock()
inner := s.inner
s.mu.Unlock()
return func(yield func(K) bool) {
for _, v := range inner {
if !yield(v) {
return
}
}
}
}

View File

@@ -0,0 +1,86 @@
package csync
import (
"sync/atomic"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestLazySlice_Iter(t *testing.T) {
t.Parallel()
data := []string{"a", "b", "c"}
s := NewLazySlice(func() []string {
// TODO: use synctest when new Go is out.
time.Sleep(10 * time.Millisecond) // Small delay to ensure loading happens
return data
})
var result []string
for v := range s.Iter() {
result = append(result, v)
}
assert.Equal(t, data, result)
}
func TestLazySlice_IterWaitsForLoading(t *testing.T) {
t.Parallel()
var loaded atomic.Bool
data := []string{"x", "y", "z"}
s := NewLazySlice(func() []string {
// TODO: use synctest when new Go is out.
time.Sleep(100 * time.Millisecond)
loaded.Store(true)
return data
})
assert.False(t, loaded.Load(), "should not be loaded immediately")
var result []string
for v := range s.Iter() {
result = append(result, v)
}
assert.True(t, loaded.Load(), "should be loaded after Iter")
assert.Equal(t, data, result)
}
func TestLazySlice_EmptySlice(t *testing.T) {
t.Parallel()
s := NewLazySlice(func() []string {
return []string{}
})
var result []string
for v := range s.Iter() {
result = append(result, v)
}
assert.Empty(t, result)
}
func TestLazySlice_EarlyBreak(t *testing.T) {
t.Parallel()
data := []string{"a", "b", "c", "d", "e"}
s := NewLazySlice(func() []string {
time.Sleep(10 * time.Millisecond) // Small delay to ensure loading happens
return data
})
var result []string
for v := range s.Iter() {
result = append(result, v)
if len(result) == 2 {
break
}
}
assert.Equal(t, []string{"a", "b"}, result)
}

View File

@@ -10,8 +10,8 @@ import (
"sync"
"time"
"github.com/charmbracelet/crush/csync"
"github.com/charmbracelet/crush/internal/config"
"github.com/charmbracelet/crush/internal/csync"
fur "github.com/charmbracelet/crush/internal/fur/provider"
"github.com/charmbracelet/crush/internal/history"
"github.com/charmbracelet/crush/internal/llm/prompt"