aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2018-02-01 18:42:03 -0500
committerDrew DeVault <sir@cmpwn.com>2018-02-01 18:42:03 -0500
commitd24e4712a45e03d79fa1ccb71d00c5b830d5a305 (patch)
tree61e2ba149d7b1197bdc5180200a6e087844131fe
parentee73c419507ef74a78ddd6a3466b605cba140b68 (diff)
downloadaerc-d24e4712a45e03d79fa1ccb71d00c5b830d5a305.tar.gz
Reduce boilerplate in worker/UI
-rw-r--r--ui/account.go46
-rw-r--r--worker/imap/worker.go49
-rw-r--r--worker/types/worker.go59
-rw-r--r--worker/worker.go20
4 files changed, 100 insertions, 74 deletions
diff --git a/ui/account.go b/ui/account.go
index 4b92e760..85c47510 100644
--- a/ui/account.go
+++ b/ui/account.go
@@ -11,12 +11,11 @@ import (
)
type AccountTab struct {
- Config *config.AccountConfig
- Worker worker.Worker
- Parent *UIState
- logger *log.Logger
- counter int
- callbacks map[types.WorkerMessage]func(msg types.WorkerMessage)
+ Config *config.AccountConfig
+ Worker *types.Worker
+ Parent *UIState
+ logger *log.Logger
+ counter int
}
func NewAccountTab(conf *config.AccountConfig,
@@ -26,15 +25,14 @@ func NewAccountTab(conf *config.AccountConfig,
if err != nil {
return nil, err
}
- go work.Run()
+ go work.Backend.Run()
acc := &AccountTab{
- Config: conf,
- Worker: work,
- logger: logger,
- callbacks: make(map[types.WorkerMessage]func(msg types.WorkerMessage)),
+ Config: conf,
+ Worker: work,
+ logger: logger,
}
- acc.postAction(types.Configure{Config: conf}, nil)
- acc.postAction(types.Connect{}, func(msg types.WorkerMessage) {
+ acc.Worker.PostAction(types.Configure{Config: conf}, nil)
+ acc.Worker.PostAction(types.Connect{}, func(msg types.WorkerMessage) {
if _, ok := msg.(types.Ack); ok {
acc.logger.Println("Connected.")
} else {
@@ -68,36 +66,22 @@ func (acc *AccountTab) Render(at Geometry) {
}
func (acc *AccountTab) GetChannel() chan types.WorkerMessage {
- return acc.Worker.GetMessages()
-}
-
-func (acc *AccountTab) postAction(msg types.WorkerMessage,
- cb func(msg types.WorkerMessage)) {
-
- acc.logger.Printf("-> %T\n", msg)
- acc.Worker.PostAction(msg)
- if cb != nil {
- acc.callbacks[msg] = cb
- delete(acc.callbacks, msg)
- }
+ return acc.Worker.Messages
}
func (acc *AccountTab) HandleMessage(msg types.WorkerMessage) {
- acc.logger.Printf("<- %T\n", msg)
- if cb, ok := acc.callbacks[msg.InResponseTo()]; ok {
- cb(msg)
- }
+ msg = acc.Worker.ProcessMessage(msg)
switch msg.(type) {
case types.Ack:
// no-op
case types.ApproveCertificate:
// TODO: Ask the user
acc.logger.Println("Approving certificate")
- acc.postAction(types.Ack{
+ acc.Worker.PostAction(types.Ack{
Message: types.RespondTo(msg),
}, nil)
default:
- acc.postAction(types.Unsupported{
+ acc.Worker.PostAction(types.Unsupported{
Message: types.RespondTo(msg),
}, nil)
}
diff --git a/worker/imap/worker.go b/worker/imap/worker.go
index ceff34d4..9fbaf0c2 100644
--- a/worker/imap/worker.go
+++ b/worker/imap/worker.go
@@ -4,7 +4,6 @@ import (
"crypto/tls"
"crypto/x509"
"fmt"
- "log"
"net/url"
"strings"
@@ -23,9 +22,6 @@ type imapClient struct {
}
type IMAPWorker struct {
- messages chan types.WorkerMessage
- actions chan types.WorkerMessage
-
config struct {
scheme string
insecure bool
@@ -33,33 +29,18 @@ type IMAPWorker struct {
user *url.Userinfo
}
+ worker *types.Worker
client *imapClient
updates chan client.Update
- logger *log.Logger
}
-func NewIMAPWorker(logger *log.Logger) *IMAPWorker {
+func NewIMAPWorker(worker *types.Worker) *IMAPWorker {
return &IMAPWorker{
- messages: make(chan types.WorkerMessage, 50),
- actions: make(chan types.WorkerMessage, 50),
- updates: make(chan client.Update, 50),
- logger: logger,
+ worker: worker,
+ updates: make(chan client.Update, 50),
}
}
-func (w *IMAPWorker) GetMessages() chan types.WorkerMessage {
- return w.messages
-}
-
-func (w *IMAPWorker) PostAction(msg types.WorkerMessage) {
- w.actions <- msg
-}
-
-func (w *IMAPWorker) postMessage(msg types.WorkerMessage) {
- w.logger.Printf("=> %T\n", msg)
- w.messages <- msg
-}
-
func (w *IMAPWorker) verifyPeerCert(msg types.WorkerMessage) func(
rawCerts [][]byte, _ [][]*x509.Certificate) error {
@@ -77,9 +58,9 @@ func (w *IMAPWorker) verifyPeerCert(msg types.WorkerMessage) func(
Message: types.RespondTo(msg),
CertPool: pool,
}
- w.postMessage(request)
+ w.worker.PostMessage(request, nil)
- response := <-w.actions
+ response := <-w.worker.Actions
if response.InResponseTo() != request {
return fmt.Errorf("Expected UI to answer cert request")
}
@@ -176,24 +157,24 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
func (w *IMAPWorker) Run() {
for {
select {
- case msg := <-w.actions:
- w.logger.Printf("<= %T\n", msg)
+ case msg := <-w.worker.Actions:
+ msg = w.worker.ProcessAction(msg)
if err := w.handleMessage(msg); err == errUnsupported {
- w.postMessage(types.Unsupported{
+ w.worker.PostMessage(types.Unsupported{
Message: types.RespondTo(msg),
- })
+ }, nil)
} else if err != nil {
- w.postMessage(types.Error{
+ w.worker.PostMessage(types.Error{
Message: types.RespondTo(msg),
Error: err,
- })
+ }, nil)
} else {
- w.postMessage(types.Ack{
+ w.worker.PostMessage(types.Ack{
Message: types.RespondTo(msg),
- })
+ }, nil)
}
case update := <-w.updates:
- w.logger.Printf("[= %T", update)
+ w.worker.Logger.Printf("(= %T", update)
}
}
}
diff --git a/worker/types/worker.go b/worker/types/worker.go
new file mode 100644
index 00000000..a99d4326
--- /dev/null
+++ b/worker/types/worker.go
@@ -0,0 +1,59 @@
+package types
+
+import (
+ "log"
+)
+
+type Backend interface {
+ Run()
+}
+
+type Worker struct {
+ Actions chan WorkerMessage
+ Backend Backend
+ Callbacks map[WorkerMessage]func(msg WorkerMessage)
+ Messages chan WorkerMessage
+ Logger *log.Logger
+}
+
+func (worker *Worker) PostAction(msg WorkerMessage,
+ cb func(msg WorkerMessage)) {
+
+ worker.Logger.Printf("=> %T\n", msg)
+ worker.Actions <- msg
+
+ if cb != nil {
+ worker.Callbacks[msg] = cb
+ }
+}
+
+func (worker *Worker) PostMessage(msg WorkerMessage,
+ cb func(msg WorkerMessage)) {
+
+ worker.Logger.Printf("-> %T\n", msg)
+ worker.Messages <- msg
+
+ if cb != nil {
+ worker.Callbacks[msg] = cb
+ }
+}
+
+func (worker *Worker) ProcessMessage(msg WorkerMessage) WorkerMessage {
+
+ worker.Logger.Printf("<= %T\n", msg)
+ if cb, ok := worker.Callbacks[msg.InResponseTo()]; ok {
+ cb(msg)
+ delete(worker.Callbacks, msg)
+ }
+ return msg
+}
+
+func (worker *Worker) ProcessAction(msg WorkerMessage) WorkerMessage {
+
+ worker.Logger.Printf("<- %T\n", msg)
+ if cb, ok := worker.Callbacks[msg.InResponseTo()]; ok {
+ cb(msg)
+ delete(worker.Callbacks, msg)
+ }
+ return msg
+}
diff --git a/worker/worker.go b/worker/worker.go
index b6658849..439ab648 100644
--- a/worker/worker.go
+++ b/worker/worker.go
@@ -9,22 +9,24 @@ import (
"net/url"
)
-type Worker interface {
- GetMessages() chan types.WorkerMessage
- PostAction(types.WorkerMessage)
- Run()
-}
-
// Guesses the appropriate worker type based on the given source string
-func NewWorker(source string, logger *log.Logger) (Worker, error) {
+func NewWorker(source string, logger *log.Logger) (*types.Worker, error) {
u, err := url.Parse(source)
if err != nil {
return nil, err
}
+ worker := &types.Worker{
+ Actions: make(chan types.WorkerMessage, 50),
+ Callbacks: make(map[types.WorkerMessage]func(msg types.WorkerMessage)),
+ Messages: make(chan types.WorkerMessage, 50),
+ Logger: logger,
+ }
switch u.Scheme {
case "imap":
case "imaps":
- return imap.NewIMAPWorker(logger), nil
+ worker.Backend = imap.NewIMAPWorker(worker)
+ default:
+ return nil, fmt.Errorf("Unknown backend %s", u.Scheme)
}
- return nil, fmt.Errorf("Unknown backend %s", u.Scheme)
+ return worker, nil
}