Refactor to move cloud fn to top level

This commit is contained in:
Ray Miller 2023-10-08 15:05:12 +01:00
parent 28abf0e461
commit 3559ca9ec1
14 changed files with 14 additions and 13 deletions

View file

@ -0,0 +1,81 @@
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)
}
}

View file

@ -0,0 +1,52 @@
package server
import "html/template"
var home = template.Must(template.New("home").Parse(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/assets/simple.css">
<link rel="stylesheet" href="/assets/custom.css">
<script src="/assets/htmx.min.js"></script>
<title>Anagram and Word Search</title>
</head>
<body>
<header>
<h1>Anagram and Word Search</h1>
</header>
<main>
<form action="/search" method="post" hx-boost="true" hx-target="#results">
<div class="center">
<input type="text" name="pattern" required></input>
<button name="mode" value="match">Match</button>
<button name="mode" value="anagrams">Anagrams</button>
<button type="reset">Clear</button>
</div>
</form>
<div id="results">
</div>
</main>
</body>
</html>
`))
type ResultParams struct {
Preamble string
Results []string
}
var results = template.Must(template.New("results").Parse(`
{{ with .Preamble }}
<p>{{ . }}</p>
{{ end }}
<ul>
{{ range .Results }}
<li>{{.}}</li>
{{ end }}
</ul>
`))