From 2191915e6cbcbb5e5ca6a58033b0b4b43e22338b Mon Sep 17 00:00:00 2001 From: "denis.bilenko" Date: Wed, 14 Oct 2026 21:02:59 +0000 Subject: [PATCH] Type-erase iterators in cmdio.RenderIterator The pager and iterator renderers were generic over the element type and got instantiated once per SDK list type (~170 shapes, 2240 functions). Wrapping the iterator as listing.Iterator[any] makes them compile once. Stripped linux/amd64 release build: 55,840,928 -> 52,543,648 bytes (-3.30 MB). Co-authored-by: Isaac --- libs/cmdio/render.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/libs/cmdio/render.go b/libs/cmdio/render.go index 6464814d4a0..bebb63dee72 100644 --- a/libs/cmdio/render.go +++ b/libs/cmdio/render.go @@ -280,6 +280,21 @@ func Render(ctx context.Context, v any) error { // locked from the first batch so columns stay aligned across pages). // Piped output and JSON output keep the existing non-paged behavior. func RenderIterator[T any](ctx context.Context, i listing.Iterator[T]) error { + return renderAnyIterator(ctx, anyIterator[T]{i}) +} + +// anyIterator erases the element type so that the renderers and pager below +// are instantiated once rather than once per listed SDK type, which +// otherwise adds megabytes to the binary. +type anyIterator[T any] struct { + listing.Iterator[T] +} + +func (a anyIterator[T]) Next(ctx context.Context) (any, error) { + return a.Iterator.Next(ctx) +} + +func renderAnyIterator(ctx context.Context, i listing.Iterator[any]) error { c := fromContext(ctx) if c.capabilities.SupportsPager() && c.outputFormat == flags.OutputText && c.template != "" { return renderIteratorPagedTemplate(ctx, i, c.in, c.out, c.headerTemplate, c.template)