Refactor handlers

This commit is contained in:
Ray Miller 2023-10-07 18:05:05 +01:00
parent 334eb5f4d0
commit 794b873ddd
3 changed files with 46 additions and 32 deletions

View file

@ -1,3 +1,12 @@
div.center { div.center {
text-align: center; text-align: center;
} }
div#results {
overflow-y: auto;
max-height: 70dvh;
}
div#results > ul {
list-style-type: none;
}

View file

@ -5,6 +5,7 @@ import (
"html/template" "html/template"
"log" "log"
"net/http" "net/http"
"sort"
"github.com/ray1729/puzzle-solver/anagram" "github.com/ray1729/puzzle-solver/anagram"
"github.com/ray1729/puzzle-solver/grep" "github.com/ray1729/puzzle-solver/grep"
@ -13,8 +14,7 @@ import (
func New(assetsPath string, grepDB grep.DB, anagramDB anagram.DB) http.Handler { func New(assetsPath string, grepDB grep.DB, anagramDB anagram.DB) http.Handler {
mux := http.NewServeMux() mux := http.NewServeMux()
mux.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir(assetsPath)))) mux.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir(assetsPath))))
mux.HandleFunc("/", getHomePage) mux.HandleFunc("/", handler(grepDB, anagramDB))
mux.HandleFunc("/search", getResults(grepDB, anagramDB))
return withRequestLogger(mux) return withRequestLogger(mux)
} }
@ -25,47 +25,48 @@ func withRequestLogger(h http.Handler) http.Handler {
}) })
} }
func getResults(grepDB grep.DB, anagramDB anagram.DB) func(w http.ResponseWriter, r *http.Request) { func handler(grepDB grep.DB, anagramDB anagram.DB) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil { if err := r.ParseForm(); err != nil {
log.Printf("error parsing form: %v", err) log.Printf("error parsing form: %v", err)
http.Error(w, "error parsing form", http.StatusBadRequest) http.Error(w, "error parsing form", http.StatusBadRequest)
return return
} }
mode := r.Form.Get("mode") switch r.Form.Get("mode") {
pattern := r.Form.Get("pattern")
templateParams := struct {
Preamble string
Results []string
}{}
switch mode {
case "match": case "match":
templateParams.Results = grepDB.FindMatches(pattern) params := matchResults(grepDB, r.Form.Get("pattern"))
if len(templateParams.Results) > 0 { renderTemplate(w, results, params)
templateParams.Preamble = fmt.Sprintf("Matches for %q:", pattern)
} else {
templateParams.Preamble = fmt.Sprintf("Found no matches for %q", pattern)
}
case "anagrams": case "anagrams":
templateParams.Results = anagramDB.FindAnagrams(pattern) params := anagramResults(anagramDB, r.Form.Get("pattern"))
if len(templateParams.Results) > 0 { renderTemplate(w, results, params)
templateParams.Preamble = fmt.Sprintf("Anagrams of %q:", pattern)
} else {
templateParams.Preamble = fmt.Sprintf("Found no anagrams of %q", pattern)
}
case "clear":
// pass
default: default:
log.Printf("invalid mode: %s", mode) renderTemplate(w, home, nil)
http.Error(w, "invalid mode", http.StatusBadRequest)
return
} }
renderTemplate(w, results, templateParams)
} }
} }
func getHomePage(w http.ResponseWriter, r *http.Request) { func anagramResults(db anagram.DB, pattern string) ResultParams {
renderTemplate(w, home, nil) var params ResultParams
params.Results = db.FindAnagrams(pattern)
if len(params.Results) > 0 {
params.Preamble = fmt.Sprintf("Anagrams of %q:", pattern)
} else {
params.Preamble = fmt.Sprintf("Found no anagrams of %q", pattern)
}
sort.Slice(params.Results, func(i, j int) bool { return params.Results[i] < params.Results[j] })
return params
}
func matchResults(db grep.DB, pattern string) ResultParams {
var params ResultParams
params.Results = db.FindMatches(pattern)
if len(params.Results) > 0 {
params.Preamble = fmt.Sprintf("Matches for %q:", pattern)
} else {
params.Preamble = fmt.Sprintf("Found no matches for %q", pattern)
}
sort.Slice(params.Results, func(i, j int) bool { return params.Results[i] < params.Results[j] })
return params
} }
func renderTemplate(w http.ResponseWriter, t *template.Template, params any) { func renderTemplate(w http.ResponseWriter, t *template.Template, params any) {

View file

@ -19,12 +19,11 @@ var home = template.Must(template.New("home").Parse(`
</header> </header>
<main> <main>
<form action="/search" method="get" hx-boost="true" hx-target="#results" hx-replace="outerHTML" hx-on::after-request="this.reset()"> <form action="/" method="get" hx-boost="true" hx-target="#results" hx-replace="innerHTML" hx-on::after-request="this.reset()">
<div class="center"> <div class="center">
<input type="text" name="pattern" required></input> <input type="text" name="pattern" required></input>
<button name="mode" value="match">Match</button> <button name="mode" value="match">Match</button>
<button name="mode" value="anagrams">Anagrams</button> <button name="mode" value="anagrams">Anagrams</button>
<button name="mode" value="clear">Clear</button>
</div> </div>
</form> </form>
<div id="results"> <div id="results">
@ -35,6 +34,11 @@ var home = template.Must(template.New("home").Parse(`
</html> </html>
`)) `))
type ResultParams struct {
Preamble string
Results []string
}
var results = template.Must(template.New("results").Parse(` var results = template.Must(template.New("results").Parse(`
{{ with .Preamble }} {{ with .Preamble }}
<p>{{ . }}</p> <p>{{ . }}</p>