From 62d7d61381274c4b0fd8f99409d01c7b953cf9c9 Mon Sep 17 00:00:00 2001
From: Matthew Holt <Matthew.Holt+git@gmail.com>
Date: Fri, 30 Jan 2015 10:00:41 -0700
Subject: [PATCH] Refactored the dispenser/controller

---
 config/dispenser.go | 74 +++++++++++++++++++++++++--------------------
 config/parser.go    | 12 ++++----
 config/parsing.go   | 12 ++++----
 3 files changed, 54 insertions(+), 44 deletions(-)

diff --git a/config/dispenser.go b/config/dispenser.go
index a043b808d..b9947dfff 100644
--- a/config/dispenser.go
+++ b/config/dispenser.go
@@ -5,6 +5,48 @@ import (
 	"fmt"
 )
 
+// newController returns a new controller.
+func newController(p *parser) *controller {
+	return &controller{
+		dispenser: dispenser{
+			cursor: -1,
+			parser: p,
+		},
+	}
+}
+
+// controller is a dispenser of tokens and also
+// facilitates setup with the server by providing
+// access to its configuration. It implements
+// the middleware.Controller interface.
+type controller struct {
+	dispenser
+}
+
+// Startup registers a function to execute when the server starts.
+func (c *controller) Startup(fn func() error) {
+	c.parser.cfg.Startup = append(c.parser.cfg.Startup, fn)
+}
+
+// Root returns the server root file path.
+func (c *controller) Root() string {
+	if c.parser.cfg.Root == "" {
+		return "."
+	} else {
+		return c.parser.cfg.Root
+	}
+}
+
+// Host returns the hostname the server is bound to.
+func (c *controller) Host() string {
+	return c.parser.cfg.Host
+}
+
+// Port returns the port that the server is listening on.
+func (c *controller) Port() string {
+	return c.parser.cfg.Port
+}
+
 // dispenser is a type that gets exposed to middleware
 // generators so that they can parse tokens to configure
 // their instance.
@@ -18,14 +60,6 @@ type dispenser struct {
 	tokens  []token
 }
 
-// newDispenser returns a new dispenser.
-func newDispenser(p *parser) *dispenser {
-	d := new(dispenser)
-	d.cursor = -1
-	d.parser = p
-	return d
-}
-
 // Next loads the next token. Returns true if a token
 // was loaded; false otherwise. If false, all tokens
 // have been consumed.
@@ -153,27 +187,3 @@ func (d *dispenser) Args(targets ...*string) bool {
 	}
 	return enough
 }
-
-// Startup registers a function to execute when the server starts.
-func (d *dispenser) Startup(fn func() error) {
-	d.parser.cfg.Startup = append(d.parser.cfg.Startup, fn)
-}
-
-// Root returns the server root file path.
-func (d *dispenser) Root() string {
-	if d.parser.cfg.Root == "" {
-		return "."
-	} else {
-		return d.parser.cfg.Root
-	}
-}
-
-// Host returns the hostname the server is bound to.
-func (d *dispenser) Host() string {
-	return d.parser.cfg.Host
-}
-
-// Port returns the port that the server is listening on.
-func (d *dispenser) Port() string {
-	return d.parser.cfg.Port
-}
diff --git a/config/parser.go b/config/parser.go
index 8201e3170..7c7f0b796 100644
--- a/config/parser.go
+++ b/config/parser.go
@@ -9,11 +9,11 @@ import (
 
 // parser is a type which can parse config files.
 type parser struct {
-	filename string                // the name of the file that we're parsing
-	lexer    lexer                 // the lexer that is giving us tokens from the raw input
-	cfg      Config                // each server gets one Config; this is the one we're currently building
-	other    map[string]*dispenser // tokens to be parsed later by others (middleware generators)
-	unused   bool                  // sometimes the token won't be immediately consumed
+	filename string                 // the name of the file that we're parsing
+	lexer    lexer                  // the lexer that is giving us tokens from the raw input
+	cfg      Config                 // each server gets one Config; this is the one we're currently building
+	other    map[string]*controller // tokens to be parsed later by others (middleware generators)
+	unused   bool                   // sometimes the token won't be immediately consumed
 }
 
 // newParser makes a new parser and prepares it for parsing, given
@@ -84,7 +84,7 @@ func (p *parser) next() bool {
 func (p *parser) parseOne() error {
 	p.cfg = Config{}
 
-	p.other = make(map[string]*dispenser)
+	p.other = make(map[string]*controller)
 
 	err := p.begin()
 	if err != nil {
diff --git a/config/parsing.go b/config/parsing.go
index d04b5f5da..3c09b9e75 100644
--- a/config/parsing.go
+++ b/config/parsing.go
@@ -115,18 +115,18 @@ func (p *parser) collectTokens() error {
 	line := p.line()
 	nesting := 0
 	breakOk := false
-	disp := newDispenser(p)
+	cont := newController(p)
 
-	// Re-use a duplicate directive's dispenser from before
+	// Re-use a duplicate directive's controller from before
 	// (the parsing logic in the middleware generator must
 	// account for multiple occurrences of its directive, even
 	// if that means returning an error or overwriting settings)
 	if existing, ok := p.other[directive]; ok {
-		disp = existing
+		cont = existing
 	}
 
 	// The directive is appended as a relevant token
-	disp.tokens = append(disp.tokens, p.lexer.token)
+	cont.tokens = append(cont.tokens, p.lexer.token)
 
 	for p.next() {
 		if p.tkn() == "{" {
@@ -140,13 +140,13 @@ func (p *parser) collectTokens() error {
 		} else if p.tkn() == "}" && nesting == 0 {
 			return p.err("Syntax", "Unexpected '}' because no matching open curly brace '{'")
 		}
-		disp.tokens = append(disp.tokens, p.lexer.token)
+		cont.tokens = append(cont.tokens, p.lexer.token)
 	}
 
 	if !breakOk || nesting > 0 {
 		return p.eofErr()
 	}
 
-	p.other[directive] = disp
+	p.other[directive] = cont
 	return nil
 }