format
This commit is contained in:
parent
7889571c5c
commit
5d4c925130
5 changed files with 24 additions and 6 deletions
|
@ -15,10 +15,12 @@ var Formatters = map[string]Formatter{
|
||||||
|
|
||||||
func capitalize(s string) string {
|
func capitalize(s string) string {
|
||||||
words := strings.Fields(s)
|
words := strings.Fields(s)
|
||||||
|
|
||||||
for i, word := range words {
|
for i, word := range words {
|
||||||
if len(word) > 0 {
|
if len(word) > 0 {
|
||||||
words[i] = strings.ToUpper(string(word[0])) + strings.ToLower(word[1:])
|
words[i] = strings.ToUpper(string(word[0])) + strings.ToLower(word[1:])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.Join(words, " ")
|
return strings.Join(words, " ")
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,11 @@ import (
|
||||||
|
|
||||||
func FormToStruct[T any](r *http.Request) (T, error) {
|
func FormToStruct[T any](r *http.Request) (T, error) {
|
||||||
var target T
|
var target T
|
||||||
|
|
||||||
if err := r.ParseForm(); err != nil {
|
if err := r.ParseForm(); err != nil {
|
||||||
return target, fmt.Errorf("error parsing form: %v", err)
|
return target, fmt.Errorf("error parsing form: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := UrlValuesToStruct(r.Form, &target)
|
err := UrlValuesToStruct(r.Form, &target)
|
||||||
return target, err
|
return target, err
|
||||||
}
|
}
|
||||||
|
@ -26,7 +28,6 @@ func UrlValuesToStruct(form url.Values, dst any) error {
|
||||||
|
|
||||||
v = v.Elem()
|
v = v.Elem()
|
||||||
t := v.Type()
|
t := v.Type()
|
||||||
|
|
||||||
for i := 0; i < t.NumField(); i++ {
|
for i := 0; i < t.NumField(); i++ {
|
||||||
field := t.Field(i)
|
field := t.Field(i)
|
||||||
fieldValue := v.Field(i)
|
fieldValue := v.Field(i)
|
||||||
|
@ -119,24 +120,28 @@ func castStringToType(value string, kind reflect.Kind) (any, error) {
|
||||||
switch kind {
|
switch kind {
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
return value, nil
|
return value, nil
|
||||||
|
|
||||||
case reflect.Int, reflect.Int64:
|
case reflect.Int, reflect.Int64:
|
||||||
new, err := strconv.Atoi(value)
|
new, err := strconv.Atoi(value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to cast string to integer: %v", err)
|
return nil, fmt.Errorf("failed to cast string to integer: %v", err)
|
||||||
}
|
}
|
||||||
return new, nil
|
return new, nil
|
||||||
|
|
||||||
case reflect.Float32, reflect.Float64:
|
case reflect.Float32, reflect.Float64:
|
||||||
new, err := strconv.ParseFloat(value, 64)
|
new, err := strconv.ParseFloat(value, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to cast string to float64: %v", err)
|
return nil, fmt.Errorf("failed to cast string to float64: %v", err)
|
||||||
}
|
}
|
||||||
return new, nil
|
return new, nil
|
||||||
|
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
new, err := strconv.ParseBool(value)
|
new, err := strconv.ParseBool(value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to cast string to boolean: %v", err)
|
return nil, fmt.Errorf("failed to cast string to boolean: %v", err)
|
||||||
}
|
}
|
||||||
return new, nil
|
return new, nil
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unsupported kind: %s", kind)
|
return nil, fmt.Errorf("unsupported kind: %s", kind)
|
||||||
}
|
}
|
||||||
|
@ -146,13 +151,16 @@ func parseFormatters(tag string) []func(string) string {
|
||||||
if tag == "" {
|
if tag == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
parts := strings.Split(tag, ",")
|
|
||||||
var fns []func(string) string
|
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 {
|
if fn, ok := Formatters[strings.TrimSpace(p)]; ok {
|
||||||
fns = append(fns, fn)
|
fns = append(fns, fn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fns
|
return fns
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,12 +171,14 @@ func parseValidators(tag string) []struct {
|
||||||
if tag == "" {
|
if tag == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var result []struct {
|
var result []struct {
|
||||||
Name string
|
Name string
|
||||||
Param string
|
Param string
|
||||||
}
|
}
|
||||||
parts := strings.Split(tag, ",")
|
|
||||||
for _, part := range parts {
|
parts := strings.SplitSeq(tag, ",")
|
||||||
|
for part := range parts {
|
||||||
pair := strings.SplitN(part, ":", 2)
|
pair := strings.SplitN(part, ":", 2)
|
||||||
if len(pair) == 2 {
|
if len(pair) == 2 {
|
||||||
result = append(result, struct{ Name, Param string }{pair[0], pair[1]})
|
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], ""})
|
result = append(result, struct{ Name, Param string }{pair[0], ""})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@ package forms
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/mail"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"net/mail"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Validator func(fieldName string, value any, param string) error
|
type Validator func(fieldName string, value any, param string) error
|
||||||
|
|
|
@ -183,9 +183,11 @@ func (s *Auth) write(writer *multipart.Writer, contentType, content string) erro
|
||||||
partHeader := make(textproto.MIMEHeader)
|
partHeader := make(textproto.MIMEHeader)
|
||||||
partHeader.Set("Content-Type", contentType)
|
partHeader.Set("Content-Type", contentType)
|
||||||
part, err := writer.CreatePart(partHeader)
|
part, err := writer.CreatePart(partHeader)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create part: %w", err)
|
return fmt.Errorf("failed to create part: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = part.Write([]byte(content))
|
_, err = part.Write([]byte(content))
|
||||||
return err
|
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-Type", "application/octet-stream")
|
||||||
attachmentHeader.Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, filename))
|
attachmentHeader.Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, filename))
|
||||||
attachment, err := writer.CreatePart(attachmentHeader)
|
attachment, err := writer.CreatePart(attachmentHeader)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create attachment part: %w", err)
|
return fmt.Errorf("failed to create attachment part: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = attachment.Write(fileBuffer.Bytes())
|
_, err = attachment.Write(fileBuffer.Bytes())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ func Stack(xs ...Middleware) Middleware {
|
||||||
for i := len(xs) - 1; i >= 0; i-- {
|
for i := len(xs) - 1; i >= 0; i-- {
|
||||||
next = xs[i](next)
|
next = xs[i](next)
|
||||||
}
|
}
|
||||||
|
|
||||||
return next
|
return next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue