diff --git a/controller.go b/controller.go
index bca9f978..4dd89a81 100644
--- a/controller.go
+++ b/controller.go
@@ -264,6 +264,10 @@ func (c *Controller) Input() url.Values {
return c.Ctx.Request.Form
}
+func (c *Controller) ParseForm(obj interface{}) error {
+ return ParseForm(c.Input(), obj)
+}
+
func (c *Controller) GetString(key string) string {
return c.Input().Get(key)
}
diff --git a/utils.go b/utils.go
index c5b27638..1adebd2e 100644
--- a/utils.go
+++ b/utils.go
@@ -3,7 +3,10 @@ package beego
import (
"fmt"
"html/template"
+ "net/url"
+ "reflect"
"regexp"
+ "strconv"
"strings"
"time"
)
@@ -170,3 +173,80 @@ func inSlice(v string, sl []string) bool {
}
return false
}
+
+// parse form values to struct via tag
+func ParseForm(form url.Values, obj interface{}) error {
+ objT := reflect.TypeOf(obj)
+ objV := reflect.ValueOf(obj)
+ if !(objT.Kind() == reflect.Ptr && objT.Elem().Kind() == reflect.Struct) {
+ return fmt.Errorf("%v must be a struct pointer", obj)
+ }
+ objT = objT.Elem()
+ objV = objV.Elem()
+
+ for i := 0; i < objT.NumField(); i++ {
+ fieldV := objV.Field(i)
+ if !fieldV.CanSet() {
+ continue
+ }
+ fieldT := objT.Field(i)
+ tag := fieldT.Tag.Get("form")
+ if len(tag) == 0 {
+ tag = fieldT.Name
+ }
+ value := form.Get(tag)
+ if len(value) == 0 {
+ continue
+ }
+
+ switch fieldT.Type.Kind() {
+ case reflect.Bool:
+ b, err := strconv.ParseBool(value)
+ if err != nil {
+ return err
+ }
+ fieldV.SetBool(b)
+ case reflect.Int:
+ fallthrough
+ case reflect.Int8:
+ fallthrough
+ case reflect.Int16:
+ fallthrough
+ case reflect.Int32:
+ fallthrough
+ case reflect.Int64:
+ x, err := strconv.ParseInt(value, 10, 64)
+ if err != nil {
+ return err
+ }
+ fieldV.SetInt(x)
+ case reflect.Uint:
+ fallthrough
+ case reflect.Uint8:
+ fallthrough
+ case reflect.Uint16:
+ fallthrough
+ case reflect.Uint32:
+ fallthrough
+ case reflect.Uint64:
+ x, err := strconv.ParseUint(value, 10, 64)
+ if err != nil {
+ return err
+ }
+ fieldV.SetUint(x)
+ case reflect.Float32:
+ fallthrough
+ case reflect.Float64:
+ x, err := strconv.ParseFloat(value, 64)
+ if err != nil {
+ return err
+ }
+ fieldV.SetFloat(x)
+ case reflect.Interface:
+ fieldV.Set(reflect.ValueOf(value))
+ case reflect.String:
+ fieldV.SetString(value)
+ }
+ }
+ return nil
+}
diff --git a/utils_test.go b/utils_test.go
new file mode 100644
index 00000000..70917a81
--- /dev/null
+++ b/utils_test.go
@@ -0,0 +1,140 @@
+package beego
+
+import (
+ "net/url"
+ "testing"
+ "time"
+)
+
+func TestWebTime(t *testing.T) {
+ ts := "Fri, 26 Jul 2013 12:27:42 CST"
+ tt, _ := time.Parse(time.RFC1123, ts)
+ if ts != webTime(tt) {
+ t.Error("should be equal")
+ }
+ if "Fri, 26 Jul 2013 04:27:42 GMT" != webTime(tt.UTC()) {
+ t.Error("should be equal")
+ }
+}
+
+func TestSubstr(t *testing.T) {
+ s := `012345`
+ if Substr(s, 0, 2) != "01" {
+ t.Error("should be equal")
+ }
+ if Substr(s, 0, 100) != "012345" {
+ t.Error("should be equal")
+ }
+}
+
+func TestHtml2str(t *testing.T) {
+ h := `<123> 123\n
+
+
+ \n`
+ if Html2str(h) != "123\\n\n\\n" {
+ t.Error("should be equal")
+ }
+}
+
+func TestDateFormat(t *testing.T) {
+ ts := "Mon, 01 Jul 2013 13:27:42 CST"
+ tt, _ := time.Parse(time.RFC1123, ts)
+ if DateFormat(tt, "2006-01-02 15:04:05") != "2013-07-01 13:27:42" {
+ t.Error("should be equal")
+ }
+}
+
+func TestDate(t *testing.T) {
+ ts := "Mon, 01 Jul 2013 13:27:42 CST"
+ tt, _ := time.Parse(time.RFC1123, ts)
+ if Date(tt, "Y-m-d H:i:s") != "2013-07-01 13:27:42" {
+ t.Error("should be equal")
+ }
+ if Date(tt, "y-n-j h:i:s A") != "13-7-1 01:27:42 PM" {
+ t.Error("should be equal")
+ }
+ if Date(tt, "D, d M Y g:i:s a") != "Mon, 01 Jul 2013 1:27:42 pm" {
+ t.Error("should be equal")
+ }
+ if Date(tt, "l, d F Y G:i:s") != "Monday, 01 July 2013 13:27:42" {
+ t.Error("should be equal")
+ }
+}
+
+func TestCompare(t *testing.T) {
+ if !Compare("abc", "abc") {
+ t.Error("should be equal")
+ }
+ if Compare("abc", "aBc") {
+ t.Error("should be not equal")
+ }
+ if !Compare("1", 1) {
+ t.Error("should be equal")
+ }
+}
+
+func TestHtmlquote(t *testing.T) {
+ h := `<' ”“&">`
+ s := `<' ”“&">`
+ if Htmlquote(s) != h {
+ t.Error("should be equal")
+ }
+}
+
+func TestHtmlunquote(t *testing.T) {
+ h := `<' ”“&">`
+ s := `<' ”“&">`
+ if Htmlunquote(h) != s {
+ t.Error("should be equal")
+ }
+}
+
+func TestInSlice(t *testing.T) {
+ sl := []string{"A", "b"}
+ if !inSlice("A", sl) {
+ t.Error("should be true")
+ }
+ if inSlice("B", sl) {
+ t.Error("should be false")
+ }
+}
+
+func TestParseForm(t *testing.T) {
+ type user struct {
+ Id int
+ tag string `form:tag`
+ Name interface{} `form:"username"`
+ Age int `form:"age"`
+ Email string
+ }
+
+ u := user{}
+ form := url.Values{
+ "tag": []string{"no"},
+ "username": []string{"test"},
+ "age": []string{"40"},
+ "Email": []string{"test@gmail.com"},
+ }
+ if err := ParseForm(form, u); err == nil {
+ t.Fatal("nothing will be changed")
+ }
+ if err := ParseForm(form, &u); err != nil {
+ t.Fatal(err)
+ }
+ if u.Id != 0 {
+ t.Error("Id should not be changed")
+ }
+ if len(u.tag) != 0 {
+ t.Error("tag should not be changed")
+ }
+ if u.Name.(string) != "test" {
+ t.Error("should be equal")
+ }
+ if u.Age != 40 {
+ t.Error("should be equal")
+ }
+ if u.Email != "test@gmail.com" {
+ t.Error("should be equal")
+ }
+}