Skip to content

Commit

Permalink
Refactoring: introduce command abstraction that in future will be use…
Browse files Browse the repository at this point in the history
…d for automation and macro
  • Loading branch information
ksysoev committed Nov 6, 2023
1 parent 0ab3e37 commit a4493c0
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 69 deletions.
7 changes: 6 additions & 1 deletion cmd/wsget/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ func run(cmd *cobra.Command, args []string) {
}

if err = client.Run(opts); err != nil {
color.New(color.FgRed).Println(err)
switch err.Error() {
case "interrupted":
return
default:
color.New(color.FgRed).Println(err)
}
}
}
98 changes: 31 additions & 67 deletions pkg/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

const (
HistoryFilename = ".wsget_history"
CommandsLimit = 100
HistoryLimit = 100

MacOSDeleteKey = 127
Expand All @@ -30,6 +31,7 @@ type CLI struct {
editor *Editor
input Inputer
output io.Writer
commands chan Executer
}

type RunOptions struct {
Expand All @@ -52,12 +54,15 @@ func NewCLI(wsConn *ws.Connection, input Inputer, output io.Writer) (*CLI, error

history := NewHistory(homeDir+"/"+HistoryFilename, HistoryLimit)

commands := make(chan Executer, CommandsLimit)

return &CLI{
formater: formater.NewFormatter(),
editor: NewEditor(output, history),
wsConn: wsConn,
input: input,
output: output,
commands: commands,
}, nil
}

Expand All @@ -82,36 +87,40 @@ func (c *CLI) Run(opts RunOptions) error {
fmt.Fprintln(c.output, "Use Enter to input request and send it, Ctrl+C to exit")

if opts.StartEditor {
if err := c.RequestMod(keysEvents); err != nil {
switch err.Error() {
case "interrupted":
return nil
case "empty request":
default:
return err
}
}
c.commands <- NewCommandEdit("")
}

exCtx := &ExecutionContext{
input: keysEvents,
output: c.output,
editor: c.editor,
wsConn: c.wsConn,
outputFile: opts.OutputFile,
formater: c.formater,
}

for {
select {
case cmd, ok := <-c.commands:
if !ok {
return nil
}

nextCmd, err := cmd.Execute(exCtx)

if err != nil {
return err
}

if nextCmd != nil {
c.commands <- nextCmd
}
case event := <-keysEvents:
switch event.Key {
case keyboard.KeyEsc, keyboard.KeyCtrlC, keyboard.KeyCtrlD:
return nil

case keyboard.KeyEnter:
if err := c.RequestMod(keysEvents); err != nil {
switch err.Error() {
case "interrupted":
return nil
case "empty request":
continue
default:
return err
}
}

c.commands <- NewCommandEdit("")
default:
continue
}
Expand All @@ -121,56 +130,11 @@ func (c *CLI) Run(opts RunOptions) error {
return nil
}

output, err := c.formater.FormatMessage(msg)
if err != nil {
return fmt.Errorf("fail to format for output file: %s, data: %q", err, msg.Data)
}

switch msg.Type {
case ws.Request:
color.New(color.FgGreen).Fprint(c.output, "->\n")
case ws.Response:
color.New(color.FgRed).Fprint(c.output, "<-\n")
default:
return fmt.Errorf("unknown message type: %s, data: %q", msg.Type, msg.Data)
}

fmt.Fprintf(c.output, "%s\n", output)

if opts.OutputFile != nil {
output, err := c.formater.FormatForFile(msg)
if err != nil {
return fmt.Errorf("fail to write to output file: %s", err)
}

fmt.Fprintln(opts.OutputFile, output)
}
c.commands <- NewCommandPrintMsg(msg)
}
}
}

func (c *CLI) RequestMod(keysEvents <-chan keyboard.KeyEvent) error {
color.New(color.FgGreen).Fprint(c.output, "->\n")

c.showCursor()
req, err := c.editor.EditRequest(keysEvents, "")
fmt.Fprint(c.output, LineUp+LineClear)
c.hideCursor()

if err != nil {
return err
}

if req != "" {
err = c.wsConn.Send(req)
if err != nil {
return fmt.Errorf("fail to send request: %s", err)
}
}

return nil
}

func (c *CLI) hideCursor() {
fmt.Fprint(c.output, HideCursor)
}
Expand Down
102 changes: 102 additions & 0 deletions pkg/cli/commands.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package cli

import (
"fmt"
"io"

"github.com/eiannone/keyboard"
"github.com/fatih/color"
"github.com/ksysoev/wsget/pkg/formater"
"github.com/ksysoev/wsget/pkg/ws"
)

type ExecutionContext struct {
input <-chan keyboard.KeyEvent
output io.Writer
editor *Editor
wsConn *ws.Connection
outputFile io.Writer
formater *formater.Formater
}

type Executer interface {
Execute(*ExecutionContext) (Executer, error)
}

type CommandEdit struct {
content string
}

func NewCommandEdit(content string) *CommandEdit {
return &CommandEdit{content}
}

func (c *CommandEdit) Execute(exCtx *ExecutionContext) (Executer, error) {
color.New(color.FgGreen).Fprint(exCtx.output, "->\n")

fmt.Fprint(exCtx.output, ShowCursor)
req, err := exCtx.editor.EditRequest(exCtx.input, c.content)
fmt.Fprint(exCtx.output, LineUp+LineClear)
fmt.Fprint(exCtx.output, HideCursor)

if err != nil || req == "" {
return nil, err
}

return NewCommandSend(req), nil
}

type CommandSend struct {
request string
}

func NewCommandSend(request string) *CommandSend {
return &CommandSend{request}
}

func (c *CommandSend) Execute(exCtx *ExecutionContext) (Executer, error) {
if err := exCtx.wsConn.Send(c.request); err != nil {
return nil, fmt.Errorf("fail to send request: %s", err)
}

return nil, nil
}

type CommandPrintMsg struct {
msg ws.Message
}

func NewCommandPrintMsg(msg ws.Message) *CommandPrintMsg {
return &CommandPrintMsg{msg}
}

func (c *CommandPrintMsg) Execute(exCtx *ExecutionContext) (Executer, error) {
msg := c.msg
output, err := exCtx.formater.FormatMessage(msg)

if err != nil {
return nil, fmt.Errorf("fail to format for output file: %s, data: %q", err, msg.Data)
}

switch msg.Type {
case ws.Request:
color.New(color.FgGreen).Fprint(exCtx.output, "->\n")
case ws.Response:
color.New(color.FgRed).Fprint(exCtx.output, "<-\n")
default:
return nil, fmt.Errorf("unknown message type: %s, data: %q", msg.Type, msg.Data)
}

fmt.Fprintf(exCtx.output, "%s\n", output)

if exCtx.outputFile != nil {
output, err := exCtx.formater.FormatForFile(msg)
if err != nil {
return nil, fmt.Errorf("fail to write to output file: %s", err)
}

fmt.Fprintln(exCtx.outputFile, output)
}

return nil, nil
}
2 changes: 1 addition & 1 deletion pkg/cli/editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func (ed *Editor) done() (string, error) {
fmt.Fprint(ed.output, ed.content.Clear())

if req == "" {
return req, fmt.Errorf("empty request")
return req, nil
}

ed.History.AddRequest(req)
Expand Down

0 comments on commit a4493c0

Please sign in to comment.