diff options
| -rw-r--r-- | cmd/generate/main.go | 24 | ||||
| -rw-r--r-- | cmd/generate/templates.go.tmpl | 24 | ||||
| -rw-r--r-- | examples/basic.go | 25 | ||||
| -rw-r--r-- | hh.go | 17 |
4 files changed, 87 insertions, 3 deletions
diff --git a/cmd/generate/main.go b/cmd/generate/main.go index eddd4cb..f846012 100644 --- a/cmd/generate/main.go +++ b/cmd/generate/main.go @@ -39,8 +39,10 @@ type Function struct { Name string Pattern string RequestTypeDef string - RequestTypeFields []RequestTypeField DoParseForm bool + RequestTypeFields []RequestTypeField + ResponseHasError bool + ResponseHasMain bool } type RequestTypeField struct { @@ -161,7 +163,7 @@ func run() error { } } if winner == "" { - panic("Counld not find import for " + parsedField.TypeDef) + panic("Could not find import for " + parsedField.TypeDef) } parsedPackage.Imports = append( slices.DeleteFunc(parsedPackage.Imports, func(i string) bool { return i == winner }), @@ -208,6 +210,24 @@ func run() error { parsedFunction.RequestTypeFields = append(parsedFunction.RequestTypeFields, parsedField) } } + if f.Type.Results == nil { + // + } else if len(f.Type.Results.List) == 1 { + switch typ := f.Type.Results.List[0].Type.(type) { + case *ast.Ident: + if typ.Name == "error" { + parsedFunction.ResponseHasError = true + } + } + if !parsedFunction.ResponseHasError { + parsedFunction.ResponseHasMain = true + } + } else if len(f.Type.Results.List) == 2 { + parsedFunction.ResponseHasError = true + parsedFunction.ResponseHasMain = true + } else if len(f.Type.Results.List) > 2 { + return errors.New("Too many return values. Max two allowed") + } parsedPackage.Functions = append(parsedPackage.Functions, parsedFunction) } } diff --git a/cmd/generate/templates.go.tmpl b/cmd/generate/templates.go.tmpl index 3533b2b..9ee259b 100644 --- a/cmd/generate/templates.go.tmpl +++ b/cmd/generate/templates.go.tmpl @@ -66,6 +66,28 @@ func hh_{{ $fn.Name }}(w http.ResponseWriter, r *http.Request) { } } {{ end }} - {{ $fn.Name }}(parsed) + {{ if $fn.ResponseHasMain -}} + res + {{- end -}} + {{- if and $fn.ResponseHasMain $fn.ResponseHasError -}} + , + {{- end -}} + {{- if $fn.ResponseHasError -}} + err + {{- end -}} + {{- if or $fn.ResponseHasMain $fn.ResponseHasError -}} + := + {{- end -}} + {{- $fn.Name }}(parsed) + + {{ if $fn.ResponseHasError }} + if err != nil { + panic("todo: Internal server error in " + {{ $fn.Name | quote }} + ": " + err.Error()) + // return + } + {{ end }} + {{ if $fn.ResponseHasMain -}} + res.Respond(w, r) + {{- end -}} } {{ end }} diff --git a/examples/basic.go b/examples/basic.go index d8ad6d7..5986e7e 100644 --- a/examples/basic.go +++ b/examples/basic.go @@ -1,9 +1,11 @@ package main import ( + "errors" "log/slog" "net/http" + "git.0m.nu/hh" "github.com/google/uuid" ) @@ -26,6 +28,29 @@ func adminUsersForm(r struct { slog.Info("get admin users form", "search", r.search, "offset", r.offset, "next-url", r.nextURL) } +//hh:route GET /return-err +func returnErr(r struct{ raw *http.Request }) error { + _ = r + return errors.New("whoops") +} + +//hh:route GET /return-value +func returnValue(r struct{ raw *http.Request }) hh.JSONValue { + _ = r + return hh.JSON(map[string]any{"key": []string{"value", "s"}}) +} + +//hh:route GET /return-both/{which} +func returnBoth(r struct { + which string `hh:"path"` +}) (hh.JSONValue, error) { + if r.which == "error" { + return hh.JSON(nil), errors.New("whoops") + } else { + return hh.JSON(map[string]any{"key": []string{"value", "s"}}), nil + } +} + func main() { hhMountRoutes(nil) slog.Error("Error listening", "error", http.ListenAndServe(":http", nil)) @@ -1,6 +1,7 @@ package hh import ( + "encoding/json" "net/http" "strconv" @@ -42,3 +43,19 @@ func ConvertToString(value string) (string, error) { func ConvertToUuidUUID(value string) (uuid.UUID, error) { return uuid.Parse(value) } + +type ToResponse interface { + Respond(w http.ResponseWriter, r *http.Request) +} + +func JSON(a any) JSONValue { + return JSONValue{a} +} + +type JSONValue struct{ any } + +func (j JSONValue) Respond(w http.ResponseWriter, r *http.Request) { + if err := json.NewEncoder(w).Encode(j); err != nil { + panic("todo: internal server error: " + err.Error()) + } +} |
