Documentation
¶
Overview ¶
Package scan provides a robust, context-aware command and line scanner.
It is designed to replace bufio.Scanner for interactive CLI applications, offering features like:
- Context cancellation support (cooperates with interruptible readers).
- "Fake EOF" detection for Windows consoles (filtering transient interrupts).
- Configurable buffering and line handling callbacks.
Index ¶
- type LivenessChecker
- type Option
- func WithBackoff(d time.Duration) Option
- func WithBufferSize(size int) Option
- func WithClearHandler(fn func()) Option
- func WithErrorHandler(fn func(err error)) Option
- func WithInterruptible() Option
- func WithLineHandler(fn func(line string)) Option
- func WithProcess(p interface{ ... }) Option
- func WithProcessLiveness(check LivenessChecker) Option
- func WithThreshold(n int) Option
- func WithUnsafeMode(unsafe bool) Option
- type Scanner
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type LivenessChecker ¶ added in v0.5.0
type LivenessChecker func() bool
LivenessChecker is a function that returns true if the source process is still running.
type Option ¶
type Option func(*Scanner)
Option configures the Scanner.
func WithBackoff ¶
WithBackoff configures the duration to wait before retrying interruptions or errors.
func WithBufferSize ¶
WithBufferSize sets the size of the internal read buffer.
func WithClearHandler ¶
func WithClearHandler(fn func()) Option
WithClearHandler sets the callback for when the line buffer is cleared (e.g. on interrupt).
func WithErrorHandler ¶
WithErrorHandler sets the callback for non-fatal errors.
func WithInterruptible ¶ added in v0.1.1
func WithInterruptible() Option
WithInterruptible enables automatic terminal upgrade and interruptible reads. When enabled, Start will attempt to upgrade the reader via termio.Upgrade and wrap it in an InterruptibleReader bound to the context passed to Start. This makes context cancellation effective even when the underlying Read blocks on a real terminal handle.
Example ¶
package main
import (
"context"
"fmt"
"os"
"github.com/aretw0/procio/scan"
)
func main() {
// WithInterruptible combines termio.Upgrade + InterruptibleReader
// so context cancellation works even on blocking terminal reads.
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
scanner := scan.NewScanner(os.Stdin,
scan.WithInterruptible(),
scan.WithLineHandler(func(line string) {
fmt.Println("User typed:", line)
}),
)
go scanner.Start(ctx)
}
func WithLineHandler ¶
WithLineHandler sets the callback for complete lines.
func WithProcess ¶ added in v0.5.0
WithProcess is a convenience wrapper that binds a *procio.Cmd liveness to the scanner.
func WithProcessLiveness ¶ added in v0.5.0
func WithProcessLiveness(check LivenessChecker) Option
WithProcessLiveness binds an external liveness check to the scanner. When an EOF is encountered, the scanner will use this check to decide if it's a real exit or a transient interruption.
func WithThreshold ¶
WithForceExitThreshold sets the number of consecutive EOFs required to stop scanning.
func WithUnsafeMode ¶
WithUnsafeMode disables the EOF threshold check.
type Scanner ¶
type Scanner struct {
// contains filtered or unexported fields
}
Scanner reads lines from an io.Reader (typically os.Stdin) with robust behavior for interactive environments, featuring Context-awareness and "Deterministic EOF" protection.
func NewScanner ¶
NewScanner creates a new robust scanner.
Example ¶
package main
import (
"context"
"fmt"
"os"
"github.com/aretw0/procio/scan"
)
func main() {
// Read from Stdin with context cancellation
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
scanner := scan.NewScanner(os.Stdin,
scan.WithLineHandler(func(line string) {
fmt.Println("User typed:", line)
}),
)
// Run in a goroutine if you need non-blocking start
go scanner.Start(ctx)
}
func (*Scanner) Start ¶
Start runs the read loop until context cancellation or persistent failure.
Example ¶
package main
import (
"context"
"fmt"
"strings"
"github.com/aretw0/procio/scan"
)
func main() {
// Simulate input
input := "hello\nworld"
reader := strings.NewReader(input)
// Create scanner
scanner := scan.NewScanner(reader,
scan.WithLineHandler(func(line string) {
fmt.Printf("Received: %s\n", line)
}),
)
// Block until EOF
scanner.Start(context.Background())
}
Output: Received: hello Received: world