scan

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 26, 2026 License: AGPL-3.0 Imports: 7 Imported by: 0

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

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

func WithBackoff(d time.Duration) Option

WithBackoff configures the duration to wait before retrying interruptions or errors.

func WithBufferSize

func WithBufferSize(size int) Option

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

func WithErrorHandler(fn func(err error)) Option

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

func WithLineHandler(fn func(line string)) Option

WithLineHandler sets the callback for complete lines.

func WithProcess added in v0.5.0

func WithProcess(p interface{ IsAlive() bool }) Option

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

func WithThreshold(n int) Option

WithForceExitThreshold sets the number of consecutive EOFs required to stop scanning.

func WithUnsafeMode

func WithUnsafeMode(unsafe bool) Option

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

func NewScanner(r io.Reader, opts ...Option) *Scanner

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

func (s *Scanner) Start(ctx context.Context)

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

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL