Explorar o código

initial import

Bozhin Zafirov %!s(int64=8) %!d(string=hai) anos
pai
achega
5537c7ad54
Modificáronse 6 ficheiros con 127 adicións e 1 borrados
  1. 1 1
      LICENSE
  2. 2 0
      README.md
  3. 14 0
      constructors.go
  4. 12 0
      errors.go
  5. 43 0
      forms.go
  6. 55 0
      validate.go

+ 1 - 1
LICENSE

@@ -1,6 +1,6 @@
 BSD 2-Clause License
 
-Copyright (c) 2017, 
+Copyright (c) 2017, Bozhin Zafirov.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without

+ 2 - 0
README.md

@@ -0,0 +1,2 @@
+# forms
+A golang library for HTTP form parsing.

+ 14 - 0
constructors.go

@@ -0,0 +1,14 @@
+package form
+
+// Generate new CharField field with type text
+func NewCharField(Name, Label string, Value *string, Validators *ValidatorsList) FormField {
+	if Value == nil {
+		return FormField{Name, "text", Label, "", nil, Validators}
+	}
+	return FormField{Name, "text", Label, *Value, nil, Validators}
+}
+
+// Generate new CharField field with type password
+func NewPasswordField(Name, Label string, Validators *ValidatorsList) FormField {
+	return FormField{Name, "password", Label, "", nil, Validators}
+}

+ 12 - 0
errors.go

@@ -0,0 +1,12 @@
+package form
+
+import (
+	"errors"
+)
+
+// pre-defined form errors
+var (
+	EInvalidMethod     = errors.New("Invalid method")
+	EInvalidIntValue   = errors.New("Field value must be integer.")
+	EInvalidFloatValue = errors.New("Field value must be float.")
+)

+ 43 - 0
forms.go

@@ -0,0 +1,43 @@
+package form
+
+import (
+	"context"
+	"strconv"
+)
+
+// ValidatorFunc defines a function for FormField data validation
+type ValidatorFunc func(FormField, context.Context) error
+
+// ValidatorsList defines a list of ValidatorFunc
+type ValidatorsList []ValidatorFunc
+
+// A general purpose form  field struct
+type FormField struct {
+	Name       string
+	Type       string
+	Label      string
+	Value      string
+	Error      error
+	Validators *ValidatorsList
+}
+
+// GetString returns FormField.Value as string
+func (f FormField) GetString() string {
+	return f.Value
+}
+
+// GetInt returns FormField.Value as int
+func (f FormField) GetInt() (int, error) {
+	return strconv.Atoi(f.Value)
+}
+
+// GetFloat returns FormField.Value as float
+func (f FormField) GetFloat() (float64, error) {
+	return strconv.ParseFloat(f.Value, 64)
+}
+
+// GetBool returns boolean value for checkbox fields
+func (f FormField) GetBool() (bool, error) {
+	// placeholder
+	return false, nil
+}

+ 55 - 0
validate.go

@@ -0,0 +1,55 @@
+package form
+
+import (
+	"net/http"
+	"reflect"
+)
+
+// ValidateForm parses a POST form into pre-defined struct
+func ValidateForm(r *http.Request, p interface{}) error {
+	// only support POST methods
+	if r.Method != "POST" {
+		return EInvalidMethod
+	}
+
+	// parse POST data into form
+	if err := r.ParseForm(); err != nil {
+		return err
+	}
+
+	var FormError error
+	// Parse form data into interface
+	formStruct := reflect.ValueOf(p).Elem()
+
+	// populate FormField value
+	for HttpFormField, HttpFormValue := range r.Form {
+		for n := 0; n < formStruct.NumField(); n++ {
+			fieldt := formStruct.Type().Field(n)
+			// only proceed if field name or tag matches that of form field
+			if fieldt.Name != HttpFormField && fieldt.Tag.Get("form") != HttpFormField {
+				continue
+			}
+			// get n-th field
+			fieldn := formStruct.Field(n)
+			// set form data to field
+			// equivalent of form.Value = HttpFormValue[0]
+			fieldn.Field(3).Set(reflect.ValueOf(HttpFormValue[0]))
+		}
+	}
+
+	// run form field validators
+	for n := 0; n < formStruct.NumField(); n++ {
+		fieldn := formStruct.Field(n)
+		field := fieldn.Interface().(FormField)
+		for _, validator := range *field.Validators {
+			if err := validator(field, r.Context()); err != nil {
+				fieldn.Field(4).Set(reflect.ValueOf(err))
+				FormError = err
+				break
+			}
+		}
+	}
+
+	// return status
+	return FormError
+}