diff --git a/forms/formatters.go b/forms/formatters.go index 580d4f3..5d86551 100644 --- a/forms/formatters.go +++ b/forms/formatters.go @@ -15,10 +15,12 @@ var Formatters = map[string]Formatter{ func capitalize(s string) string { words := strings.Fields(s) + for i, word := range words { if len(word) > 0 { words[i] = strings.ToUpper(string(word[0])) + strings.ToLower(word[1:]) } } + return strings.Join(words, " ") } diff --git a/forms/forms.go b/forms/forms.go index 72036de..a48fbc1 100644 --- a/forms/forms.go +++ b/forms/forms.go @@ -11,9 +11,11 @@ import ( func FormToStruct[T any](r *http.Request) (T, error) { var target T + if err := r.ParseForm(); err != nil { return target, fmt.Errorf("error parsing form: %v", err) } + err := UrlValuesToStruct(r.Form, &target) return target, err } @@ -26,7 +28,6 @@ func UrlValuesToStruct(form url.Values, dst any) error { v = v.Elem() t := v.Type() - for i := 0; i < t.NumField(); i++ { field := t.Field(i) fieldValue := v.Field(i) @@ -119,24 +120,28 @@ func castStringToType(value string, kind reflect.Kind) (any, error) { switch kind { case reflect.String: return value, nil + case reflect.Int, reflect.Int64: new, err := strconv.Atoi(value) if err != nil { return nil, fmt.Errorf("failed to cast string to integer: %v", err) } return new, nil + case reflect.Float32, reflect.Float64: new, err := strconv.ParseFloat(value, 64) if err != nil { return nil, fmt.Errorf("failed to cast string to float64: %v", err) } return new, nil + case reflect.Bool: new, err := strconv.ParseBool(value) if err != nil { return nil, fmt.Errorf("failed to cast string to boolean: %v", err) } return new, nil + default: return nil, fmt.Errorf("unsupported kind: %s", kind) } @@ -146,13 +151,16 @@ func parseFormatters(tag string) []func(string) string { if tag == "" { return nil } - parts := strings.Split(tag, ",") + var fns []func(string) string - for _, p := range parts { + + parts := strings.SplitSeq(tag, ",") + for p := range parts { if fn, ok := Formatters[strings.TrimSpace(p)]; ok { fns = append(fns, fn) } } + return fns } @@ -163,12 +171,14 @@ func parseValidators(tag string) []struct { if tag == "" { return nil } + var result []struct { Name string Param string } - parts := strings.Split(tag, ",") - for _, part := range parts { + + parts := strings.SplitSeq(tag, ",") + for part := range parts { pair := strings.SplitN(part, ":", 2) if len(pair) == 2 { result = append(result, struct{ Name, Param string }{pair[0], pair[1]}) @@ -176,5 +186,6 @@ func parseValidators(tag string) []struct { result = append(result, struct{ Name, Param string }{pair[0], ""}) } } + return result } diff --git a/forms/validators.go b/forms/validators.go index 1615233..8c822b2 100644 --- a/forms/validators.go +++ b/forms/validators.go @@ -2,9 +2,9 @@ package forms import ( "fmt" + "net/mail" "reflect" "strconv" - "net/mail" ) type Validator func(fieldName string, value any, param string) error diff --git a/mail/smtp.go b/mail/smtp.go index c494eb1..d4692db 100644 --- a/mail/smtp.go +++ b/mail/smtp.go @@ -183,9 +183,11 @@ func (s *Auth) write(writer *multipart.Writer, contentType, content string) erro partHeader := make(textproto.MIMEHeader) partHeader.Set("Content-Type", contentType) part, err := writer.CreatePart(partHeader) + if err != nil { return fmt.Errorf("failed to create part: %w", err) } + _, err = part.Write([]byte(content)) return err } @@ -195,9 +197,11 @@ func (s *Auth) attach(writer *multipart.Writer, filename string, fileBuffer *byt attachmentHeader.Set("Content-Type", "application/octet-stream") attachmentHeader.Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, filename)) attachment, err := writer.CreatePart(attachmentHeader) + if err != nil { return fmt.Errorf("failed to create attachment part: %w", err) } + _, err = attachment.Write(fileBuffer.Bytes()) return err } diff --git a/middleware/middleware.go b/middleware/middleware.go index bcb5a96..961914d 100644 --- a/middleware/middleware.go +++ b/middleware/middleware.go @@ -9,6 +9,7 @@ func Stack(xs ...Middleware) Middleware { for i := len(xs) - 1; i >= 0; i-- { next = xs[i](next) } + return next } }