-
-
Notifications
You must be signed in to change notification settings - Fork 188
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
use functional option for cui (#174)
- Loading branch information
Showing
10 changed files
with
164 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package cui | ||
|
||
import ( | ||
"io" | ||
) | ||
|
||
// Option for basicUI | ||
type Option func(*basicUI) | ||
|
||
func Writer(w io.Writer) Option { | ||
return func(u *basicUI) { | ||
u.writer = w | ||
} | ||
} | ||
|
||
func ErrWriter(ew io.Writer) Option { | ||
return func(u *basicUI) { | ||
u.errWriter = ew | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package cui | ||
|
||
import ( | ||
"io" | ||
"os" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestReader(t *testing.T) { | ||
cases := map[string]struct { | ||
r io.Reader | ||
expected io.Reader | ||
}{ | ||
"normal": { | ||
r: os.Stdin, | ||
expected: os.Stdin, | ||
}, | ||
} | ||
|
||
for name, c := range cases { | ||
t.Run(name, func(t *testing.T) { | ||
ui := &basicUI{} | ||
Reader(c.r)(ui) | ||
assert.Equal(t, c.expected, ui.reader) | ||
}) | ||
} | ||
} | ||
|
||
func TestWriter(t *testing.T) { | ||
cases := map[string]struct { | ||
w io.Writer | ||
expected io.Writer | ||
}{ | ||
"normal": { | ||
w: os.Stdout, | ||
expected: os.Stdout, | ||
}, | ||
} | ||
|
||
for name, c := range cases { | ||
t.Run(name, func(t *testing.T) { | ||
ui := &basicUI{} | ||
Writer(c.w)(ui) | ||
assert.Equal(t, c.expected, ui.writer) | ||
}) | ||
} | ||
} | ||
|
||
func TestErrWriter(t *testing.T) { | ||
cases := map[string]struct { | ||
ew io.Writer | ||
expected io.Writer | ||
}{ | ||
"normal": { | ||
ew: os.Stderr, | ||
expected: os.Stderr, | ||
}, | ||
} | ||
|
||
for name, c := range cases { | ||
t.Run(name, func(t *testing.T) { | ||
ui := &basicUI{} | ||
ErrWriter(c.ew)(ui) | ||
assert.Equal(t, c.expected, ui.errWriter) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,80 @@ | ||
// Package cui defines charcter user interfaces for I/O. | ||
package cui | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"os" | ||
|
||
"github.com/fatih/color" | ||
colorable "github.com/mattn/go-colorable" | ||
) | ||
|
||
var defaultUI = UI{ | ||
Prefix: "evans: ", | ||
Writer: os.Stdout, | ||
ErrWriter: os.Stderr, | ||
// UI provides formatted I/O interfaces. | ||
// It is used from Evans's standard I/O and CLI mode I/O. | ||
type UI interface { | ||
Output(s string) | ||
Info(s string) | ||
Error(s string) | ||
|
||
Writer() io.Writer | ||
} | ||
|
||
// New creates a new UI with passed options. | ||
func New(opts ...Option) UI { | ||
// Creates a new UI with stdin, stdout, stderr. | ||
ui := &basicUI{ | ||
writer: colorable.NewColorableStdout(), | ||
errWriter: colorable.NewColorableStderr(), | ||
} | ||
for _, opt := range opts { | ||
opt(ui) | ||
} | ||
return ui | ||
} | ||
|
||
// UI provides formatted output for the application. Almost users can use | ||
// DefaultUI() as it is. | ||
type UI struct { | ||
Prefix string | ||
Writer, ErrWriter io.Writer | ||
type basicUI struct { | ||
writer, errWriter io.Writer | ||
} | ||
|
||
// Output writes out the passed argument s to Writer with a line break. | ||
func (u *UI) Output(s string) { | ||
fmt.Fprintln(u.Writer, s) | ||
func (u *basicUI) Output(s string) { | ||
fmt.Fprintln(u.writer, s) | ||
} | ||
|
||
// Info is the same as Output, but distinguish these for composition. | ||
func (u *UI) Info(s string) { | ||
func (u *basicUI) Info(s string) { | ||
u.Output(s) | ||
} | ||
|
||
// Error writes out the passed argument s to ErrWriter with a line break. | ||
func (u *UI) Error(s string) { | ||
fmt.Fprintln(u.ErrWriter, s) | ||
func (u *basicUI) Error(s string) { | ||
fmt.Fprintln(u.errWriter, s) | ||
} | ||
|
||
// Writer returns an io.Writer which is used in u. | ||
func (u *basicUI) Writer() io.Writer { | ||
return u.writer | ||
} | ||
|
||
type coloredUI struct { | ||
UI | ||
} | ||
|
||
// NewColored wraps provided `ui` with coloredUI. | ||
// If `ui` is *coloredUI, NewColored returns it as it is. | ||
// Colored output works fine in Windows environment. | ||
func NewColored(ui UI) UI { | ||
if ui, ok := ui.(*coloredUI); ok { | ||
return ui | ||
} | ||
return &coloredUI{ui} | ||
} | ||
|
||
// Info is the same as New, but colored. | ||
func (u *coloredUI) Info(s string) { | ||
u.UI.Info(color.BlueString(s)) | ||
} | ||
|
||
// DefaultUI returns the default UI. | ||
func DefaultUI() *UI { | ||
ui := defaultUI | ||
return &ui | ||
// Error is the same as New, but colored. | ||
func (u *coloredUI) Error(s string) { | ||
u.UI.Error(color.RedString(s)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters