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 }