diff --git a/docs/pkg/cli/streaming.md b/docs/pkg/cli/streaming.md index d619d16..67dd41b 100644 --- a/docs/pkg/cli/streaming.md +++ b/docs/pkg/cli/streaming.md @@ -41,10 +41,11 @@ var buf strings.Builder stream := cli.NewStream(cli.WithStreamOutput(&buf)) // ... write tokens ... stream.Done() -result := stream.Captured() // or buf.String() +result, ok := stream.CapturedOK() // or buf.String() ``` `Captured()` returns the output as a string when using a `*strings.Builder` or any `fmt.Stringer`. +`CapturedOK()` reports whether capture is supported by the configured writer. ## Reading from `io.Reader` @@ -68,7 +69,8 @@ stream.Done() | `Done()` | Signal completion (adds trailing newline if needed) | | `Wait()` | Block until `Done` is called | | `Column()` | Current column position | -| `Captured()` | Get output as string (requires `*strings.Builder` or `fmt.Stringer` writer) | +| `Captured()` | Get output as string (returns `""` if capture is unsupported) | +| `CapturedOK()` | Get output and support status | ## Options diff --git a/pkg/cli/stream.go b/pkg/cli/stream.go index 211fd6d..66de4fd 100644 --- a/pkg/cli/stream.go +++ b/pkg/cli/stream.go @@ -132,16 +132,24 @@ func (s *Stream) Column() int { return s.col } -// Captured returns the stream output as a string when using a stringable writer. -// Panics if the output writer is not a *strings.Builder or fmt.Stringer. +// Captured returns the stream output as a string when the output writer is +// capture-capable. If the writer cannot be captured, it returns an empty string. +// Use CapturedOK when you need to distinguish that case. func (s *Stream) Captured() string { + out, _ := s.CapturedOK() + return out +} + +// CapturedOK returns the stream output and whether the configured writer +// supports capture. +func (s *Stream) CapturedOK() (string, bool) { s.mu.Lock() defer s.mu.Unlock() if sb, ok := s.out.(*strings.Builder); ok { - return sb.String() + return sb.String(), true } if st, ok := s.out.(fmt.Stringer); ok { - return st.String() + return st.String(), true } - panic("stream output writer does not support Capture") + return "", false } diff --git a/pkg/cli/stream_test.go b/pkg/cli/stream_test.go index e4d745c..589162f 100644 --- a/pkg/cli/stream_test.go +++ b/pkg/cli/stream_test.go @@ -189,11 +189,12 @@ func TestStream_Bad(t *testing.T) { assert.Equal(t, "", buf.String()) }) - t.Run("Captured panics when output is not stringable", func(t *testing.T) { + t.Run("CapturedOK reports unsupported writers", func(t *testing.T) { s := NewStream(WithStreamOutput(writerOnly{})) - assert.Panics(t, func() { - _ = s.Captured() - }) + got, ok := s.CapturedOK() + assert.False(t, ok) + assert.Equal(t, "", got) + assert.Equal(t, "", s.Captured()) }) }