package context import ( "io" "os" ) // Context interface for handling command-line arguments and standard input/output streams type Context interface { Args() []string // Get the list of arguments passed to the program Stdin() io.Reader // Get the standard input stream Stdout() io.Writer // Get the standard output stream Stderr() io.Writer // Get the error output stream Exit(int) // Exit the program with a specific status code } type context struct { args []string stdin io.Reader stdout io.Writer stderr io.Writer exit func(int) } func (ctx context) Args() []string { return ctx.args } func (ctx context) Stdin() io.Reader { return ctx.stdin } func (ctx context) Stdout() io.Writer { return ctx.stdout } func (ctx context) Stderr() io.Writer { return ctx.stderr } func (ctx context) Exit(status int) { ctx.exit(status) } type Option func(ctx *context) func WithArgs(args []string) Option { return func(ctx *context) { ctx.args = args } } func WithStdin(stdin io.Reader) Option { return func(ctx *context) { ctx.stdin = stdin } } func WithStdout(stdout io.Writer) Option { return func(ctx *context) { ctx.stdout = stdout } } func WithStderr(stderr io.Writer) Option { return func(ctx *context) { ctx.stderr = stderr } } func WithExit(exit func(int)) Option { return func(ctx *context) { ctx.exit = exit } } // New returns a new instance of the Context interface with // the standard input, output, and error streams. func New(opts ...Option) Context { ctx := &context{ args: os.Args[1:], // Skip monkey binary itself stdin: os.Stdin, stdout: os.Stdout, stderr: os.Stderr, exit: os.Exit, } for _, opt := range opts { opt(ctx) } return ctx }