81 lines
2.5 KiB
Go
81 lines
2.5 KiB
Go
package server
|
|
|
|
import (
|
|
"fmt"
|
|
"html/template"
|
|
"log"
|
|
"net/http"
|
|
"sort"
|
|
|
|
"github.com/ray1729/wordsearch/anagram"
|
|
"github.com/ray1729/wordsearch/match"
|
|
)
|
|
|
|
func New(assetsPath string, matchDB match.DB, anagramDB anagram.DB) http.Handler {
|
|
mux := http.NewServeMux()
|
|
mux.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir(assetsPath))))
|
|
mux.HandleFunc("/search", searchHandler(matchDB, anagramDB))
|
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
renderTemplate(w, home, nil)
|
|
})
|
|
return withRequestLogger(mux)
|
|
}
|
|
|
|
func withRequestLogger(h http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
log.Printf("%s %s %s", r.Method, r.URL.Path, r.URL.Query())
|
|
h.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
|
|
func searchHandler(matchDB match.DB, anagramDB anagram.DB) func(w http.ResponseWriter, r *http.Request) {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
if err := r.ParseForm(); err != nil {
|
|
log.Printf("error parsing form: %v", err)
|
|
http.Error(w, "error parsing form", http.StatusBadRequest)
|
|
return
|
|
}
|
|
switch r.Form.Get("mode") {
|
|
case "match":
|
|
params := matchResults(matchDB, r.Form.Get("pattern"))
|
|
renderTemplate(w, results, params)
|
|
case "anagrams":
|
|
params := anagramResults(anagramDB, r.Form.Get("pattern"))
|
|
renderTemplate(w, results, params)
|
|
default:
|
|
renderTemplate(w, results, ResultParams{})
|
|
}
|
|
}
|
|
}
|
|
|
|
func anagramResults(db anagram.DB, pattern string) ResultParams {
|
|
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 match.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) {
|
|
err := t.Execute(w, params)
|
|
if err != nil {
|
|
log.Printf("Error rendering template %s: %v", t.Name(), err)
|
|
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
|
}
|
|
}
|