github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/commands/io.go (about)

     1  package commands
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  )
     9  
    10  // IO holds settable command
    11  // input, output and error buffers
    12  type IO interface {
    13  	// getters
    14  	In() io.Reader
    15  	Out() io.WriteCloser
    16  	Err() io.WriteCloser
    17  
    18  	// setters and helpers
    19  	SetIn(in io.Reader)
    20  	SetOut(out io.WriteCloser)
    21  	SetErr(err io.WriteCloser)
    22  	Println(args ...interface{})
    23  	Printf(format string, args ...interface{})
    24  	Printfln(format string, args ...interface{})
    25  	ErrPrintln(args ...interface{})
    26  	ErrPrintfln(format string, args ...interface{})
    27  	GetCheckPassword(prompts [2]string, insecure bool) (string, error)
    28  	GetConfirmation(prompt string) (bool, error)
    29  	GetPassword(prompt string, insecure bool) (string, error)
    30  	GetString(prompt string) (string, error)
    31  }
    32  
    33  type IOImpl struct {
    34  	in    io.Reader
    35  	inBuf *bufio.Reader
    36  
    37  	out    io.WriteCloser
    38  	outBuf *bufio.Writer
    39  
    40  	err    io.WriteCloser
    41  	errBuf *bufio.Writer
    42  }
    43  
    44  // NewDefaultIO returns a default command io
    45  // that utilizes standard input / output / error
    46  func NewDefaultIO() IO {
    47  	c := &IOImpl{}
    48  
    49  	c.SetIn(os.Stdin)
    50  	c.SetOut(os.Stdout)
    51  	c.SetErr(os.Stderr)
    52  
    53  	return c
    54  }
    55  
    56  // NewTestIO returns a test command io
    57  // that only sets standard input (to avoid panics)
    58  func NewTestIO() IO {
    59  	c := &IOImpl{}
    60  	c.SetIn(os.Stdin)
    61  
    62  	return c
    63  }
    64  
    65  func (io *IOImpl) In() io.Reader       { return io.in }
    66  func (io *IOImpl) Out() io.WriteCloser { return io.out }
    67  func (io *IOImpl) Err() io.WriteCloser { return io.err }
    68  
    69  // SetIn sets the input reader for the command io
    70  func (io *IOImpl) SetIn(in io.Reader) {
    71  	io.in = in
    72  	if inbuf, ok := io.in.(*bufio.Reader); ok {
    73  		io.inBuf = inbuf
    74  
    75  		return
    76  	}
    77  
    78  	io.inBuf = bufio.NewReader(in)
    79  }
    80  
    81  // SetOut sets the output writer for the command io
    82  func (io *IOImpl) SetOut(out io.WriteCloser) {
    83  	io.out = out
    84  	io.outBuf = bufio.NewWriter(io.out)
    85  }
    86  
    87  // SetErr sets the error writer for the command io
    88  func (io *IOImpl) SetErr(err io.WriteCloser) {
    89  	io.err = err
    90  	io.errBuf = bufio.NewWriter(io.err)
    91  }
    92  
    93  // Println prints a line terminated by a newline
    94  func (io *IOImpl) Println(args ...interface{}) {
    95  	if io.outBuf == nil {
    96  		return
    97  	}
    98  
    99  	_, _ = fmt.Fprintln(io.outBuf, args...)
   100  	_ = io.outBuf.Flush()
   101  }
   102  
   103  // Printf prints a formatted string without trailing newline
   104  func (io *IOImpl) Printf(format string, args ...interface{}) {
   105  	if io.outBuf == nil {
   106  		return
   107  	}
   108  
   109  	_, _ = fmt.Fprintf(io.outBuf, format, args...)
   110  	_ = io.outBuf.Flush()
   111  }
   112  
   113  // Printfln prints a formatted string terminated by a newline
   114  func (io *IOImpl) Printfln(format string, args ...interface{}) {
   115  	if io.outBuf == nil {
   116  		return
   117  	}
   118  
   119  	_, _ = fmt.Fprintf(io.outBuf, format+"\n", args...)
   120  	_ = io.outBuf.Flush()
   121  }
   122  
   123  // ErrPrintln prints a line terminated by a newline to
   124  // cmd.Err(Buf)
   125  func (io *IOImpl) ErrPrintln(args ...interface{}) {
   126  	if io.errBuf == nil {
   127  		return
   128  	}
   129  
   130  	_, _ = fmt.Fprintln(io.errBuf, args...)
   131  	_ = io.errBuf.Flush()
   132  }
   133  
   134  // ErrPrintfln prints a formatted string terminated by a newline to cmd.Err(Buf)
   135  func (io *IOImpl) ErrPrintfln(format string, args ...interface{}) {
   136  	if io.errBuf == nil {
   137  		return
   138  	}
   139  
   140  	_, _ = fmt.Fprintf(io.errBuf, format+"\n", args...)
   141  	_ = io.errBuf.Flush()
   142  }
   143  
   144  type writeNopCloser struct {
   145  	io.Writer
   146  }
   147  
   148  func (writeNopCloser) Close() error { return nil }
   149  
   150  func WriteNopCloser(w io.Writer) io.WriteCloser {
   151  	return writeNopCloser{w}
   152  }