feat(provider): add registry subset iterators

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-02 00:52:21 +00:00
parent e23d8e9780
commit 6b075a207b
2 changed files with 144 additions and 0 deletions

View file

@ -88,6 +88,24 @@ func (r *Registry) Streamable() []Streamable {
return result
}
// StreamableIter returns an iterator over all registered providers that
// implement the Streamable interface.
func (r *Registry) StreamableIter() iter.Seq[Streamable] {
r.mu.RLock()
providers := slices.Clone(r.providers)
r.mu.RUnlock()
return func(yield func(Streamable) bool) {
for _, p := range providers {
if s, ok := p.(Streamable); ok {
if !yield(s) {
return
}
}
}
}
}
// Describable returns all providers that implement the Describable interface.
func (r *Registry) Describable() []Describable {
r.mu.RLock()
@ -101,6 +119,24 @@ func (r *Registry) Describable() []Describable {
return result
}
// DescribableIter returns an iterator over all registered providers that
// implement the Describable interface.
func (r *Registry) DescribableIter() iter.Seq[Describable] {
r.mu.RLock()
providers := slices.Clone(r.providers)
r.mu.RUnlock()
return func(yield func(Describable) bool) {
for _, p := range providers {
if d, ok := p.(Describable); ok {
if !yield(d) {
return
}
}
}
}
}
// Renderable returns all providers that implement the Renderable interface.
func (r *Registry) Renderable() []Renderable {
r.mu.RLock()
@ -114,6 +150,24 @@ func (r *Registry) Renderable() []Renderable {
return result
}
// RenderableIter returns an iterator over all registered providers that
// implement the Renderable interface.
func (r *Registry) RenderableIter() iter.Seq[Renderable] {
r.mu.RLock()
providers := slices.Clone(r.providers)
r.mu.RUnlock()
return func(yield func(Renderable) bool) {
for _, p := range providers {
if rv, ok := p.(Renderable); ok {
if !yield(rv) {
return
}
}
}
}
}
// ProviderInfo is a serialisable summary of a registered provider.
type ProviderInfo struct {
Name string `json:"name"`

View file

@ -119,6 +119,36 @@ func TestRegistry_Streamable_Good(t *testing.T) {
assert.Equal(t, []string{"stub.event"}, s[0].Channels())
}
func TestRegistry_StreamableIter_Good(t *testing.T) {
reg := provider.NewRegistry()
reg.Add(&stubProvider{})
reg.Add(&streamableProvider{})
var streamables []provider.Streamable
for s := range reg.StreamableIter() {
streamables = append(streamables, s)
}
assert.Len(t, streamables, 1)
assert.Equal(t, []string{"stub.event"}, streamables[0].Channels())
}
func TestRegistry_StreamableIter_Good_SnapshotCurrentProviders(t *testing.T) {
reg := provider.NewRegistry()
reg.Add(&streamableProvider{})
iter := reg.StreamableIter()
reg.Add(&streamableProvider{})
var streamables []provider.Streamable
for s := range iter {
streamables = append(streamables, s)
}
assert.Len(t, streamables, 1)
assert.Equal(t, []string{"stub.event"}, streamables[0].Channels())
}
func TestRegistry_Describable_Good(t *testing.T) {
reg := provider.NewRegistry()
reg.Add(&stubProvider{}) // not describable
@ -129,6 +159,36 @@ func TestRegistry_Describable_Good(t *testing.T) {
assert.Len(t, d[0].Describe(), 1)
}
func TestRegistry_DescribableIter_Good(t *testing.T) {
reg := provider.NewRegistry()
reg.Add(&stubProvider{})
reg.Add(&describableProvider{})
var describables []provider.Describable
for d := range reg.DescribableIter() {
describables = append(describables, d)
}
assert.Len(t, describables, 1)
assert.Len(t, describables[0].Describe(), 1)
}
func TestRegistry_DescribableIter_Good_SnapshotCurrentProviders(t *testing.T) {
reg := provider.NewRegistry()
reg.Add(&describableProvider{})
iter := reg.DescribableIter()
reg.Add(&describableProvider{})
var describables []provider.Describable
for d := range iter {
describables = append(describables, d)
}
assert.Len(t, describables, 1)
assert.Len(t, describables[0].Describe(), 1)
}
func TestRegistry_Renderable_Good(t *testing.T) {
reg := provider.NewRegistry()
reg.Add(&stubProvider{}) // not renderable
@ -139,6 +199,36 @@ func TestRegistry_Renderable_Good(t *testing.T) {
assert.Equal(t, "core-stub-panel", r[0].Element().Tag)
}
func TestRegistry_RenderableIter_Good(t *testing.T) {
reg := provider.NewRegistry()
reg.Add(&stubProvider{})
reg.Add(&renderableProvider{})
var renderables []provider.Renderable
for r := range reg.RenderableIter() {
renderables = append(renderables, r)
}
assert.Len(t, renderables, 1)
assert.Equal(t, "core-stub-panel", renderables[0].Element().Tag)
}
func TestRegistry_RenderableIter_Good_SnapshotCurrentProviders(t *testing.T) {
reg := provider.NewRegistry()
reg.Add(&renderableProvider{})
iter := reg.RenderableIter()
reg.Add(&renderableProvider{})
var renderables []provider.Renderable
for r := range iter {
renderables = append(renderables, r)
}
assert.Len(t, renderables, 1)
assert.Equal(t, "core-stub-panel", renderables[0].Element().Tag)
}
func TestRegistry_Info_Good(t *testing.T) {
reg := provider.NewRegistry()
reg.Add(&fullProvider{})