a package for decode form's values into struct in Go

Overview

formam

A Go package to decode HTTP form and query parameters. The only requirement is Go 1.10 or later.

Build Status GoDoc

Features

  • Infinite nesting for maps, structs and slices.
  • Support UnmarshalText() interface in values and keys of maps.
  • Supported map keys are string, int and variants, uint and variants, uintptr, float32, float64, bool, struct, custom types to one of the above types registered by function or UnmarshalText method, a pointer to one of the above types
  • A field with interface{} that has a map, struct or slice as value is accessible.
  • Decode time.Time with format 2006-01-02 by its UnmarshalText() method.
  • Decode url.URL.
  • Append to slice and array types without explicitly indicating an index.
  • Register a function for a custom type.

Performance

You can see the performance in formam-benchmark compared with ajg/form, gorilla/schema, go-playground/form and built-in/json.

Basic usage example

In form HTML

  • Use . to access a struct field (e.g. struct.field1).
  • Use [<index>] to access tje specific slice/array index (e.g. struct.array[0]). It's not necessary to add an index to append data.
  • Use [<key>] to access map keys (e.g.. struct.map[es-ES]).
<form method="POST">
  <input type="text" name="Name" value="Sony">
  <input type="text" name="Location.Country" value="Japan">
  <input type="text" name="Location.City" value="Tokyo">
  <input type="text" name="Products[0].Name" value="Playstation 4">
  <input type="text" name="Products[0].Type" value="Video games">
  <input type="text" name="Products[1].Name" value="TV Bravia 32">
  <input type="text" name="Products[1].Type" value="TVs">
  <input type="text" name="Founders[0]" value="Masaru Ibuka">
  <input type="text" name="Founders[0]" value="Akio Morita">
  <input type="text" name="Employees" value="90000">
  <input type="text" name="public" value="true">
  <input type="url" name="website" value="http://www.sony.net">
  <input type="date" name="foundation" value="1946-05-07">
  <input type="text" name="Interface.ID" value="12">
  <input type="text" name="Interface.Name" value="Go Programming Language">
  <input type="submit">
</form>

In Go

You can use the formam struct tag to ensure the form values are unmarshalled in the currect struct fields.

type InterfaceStruct struct {
    ID   int
    Name string
}

type Company struct {
  Public     bool      `formam:"public"`
  Website    url.URL   `formam:"website"`
  Foundation time.Time `formam:"foundation"`
  Name       string
  Location   struct {
    Country  string
    City     string
  }
  Products   []struct {
    Name string
    Type string
  }
  Founders   []string
  Employees  int64

  Interface interface{}
}

func MyHandler(w http.ResponseWriter, r *http.Request) error {
  r.ParseForm()

  m := Company{
      // it's is possible to access to the fields although it's an interface field!
      Interface: &InterfaceStruct{},
  }
  dec := formam.NewDecoder(&formam.DecoderOptions{TagName: "formam"})
  return dec.Decode(r.Form, &m)
}

Types

Supported types in the destination struct are:

  • string
  • bool
  • int, int8, int16, int32, int64
  • uint, uint8, uint16, uint32, uint64
  • float32, float64
  • slice, array
  • struct and struct anonymous
  • map
  • interface{}
  • time.Time
  • url.URL
  • custom types to one of the above types
  • a pointer to one of the above types

Custom Marshaling

You can umarshal data and map keys by implementing the encoding.TextUnmarshaler interface.

If the forms sends multiple values then only the first value is passed to UnmarshalText(), but if the name ends with [] then it's called for all values.

Custom Type

You can register a function for a custom type using the RegisterCustomType() method. This will work for any number of given fields or all fields with the given type.

Registered type have preference over the UnmarshalText method unless the PrefUnmarshalText option is used.

All fields

decoder.RegisterCustomType(func(vals []string) (interface{}, error) {
        return time.Parse("2006-01-02", vals[0])
}, []interface{}{time.Time{}}, nil)

Specific fields

package main

type Times struct {
    Timestamp   time.Time
    Time        time.Time
    TimeDefault time.Time
}

func main() {
    var t Timestamp

    dec := NewDecoder(nil)

    // for Timestamp field
    dec.RegisterCustomType(func(vals []string) (interface{}, error) {
            return time.Parse("2006-01-02T15:04:05Z07:00", vals[0])
    }, []interface{}{time.Time{}}, []interface{}{&t.Timestamp{}}) 

    // for Time field
    dec.RegisterCustomType(func(vals []string) (interface{}, error) {
                return time.Parse("Mon, 02 Jan 2006 15:04:05 MST", vals[0])
    }, []interface{}{time.Time{}}, []interface{}{&t.Time{}}) 

    // for field that not be Time or Timestamp, e.g. in this example, TimeDefault.
    dec.RegisterCustomType(func(vals []string) (interface{}, error) {
                return time.Parse("2006-01-02", vals[0])
    }, []interface{}{time.Time{}}, nil)

    dec.Decode(url.Values{}, &t)
}

Notes

Version 2 is compatible with old syntax to access to maps (map.key), but brackets are the preferred way to access a map (map[key]).

Issues
  • Array of model problem

    Array of model problem

    First of all, I hope to make myself understood. Sometimes when I try to bind the form, the values are incomplete, sometimes I just receive 1 user, other times I receive 2 users, but with empty fields like:

    USERS-----------------------> 2
    User 1 FN-----------------------> FirstName1
    User 1 LN-----------------------> LastName1
    User 1 EA-----------------------> [email protected]
    User 2 FN-----------------------> FirstName2
    User 2 LN-----------------------> LastName2
    User 2 EA-----------------------> 
    

    I'm not really sure why this is happening. Thanks in advance.

    I have this model:

    type User struct {
        FirstName string  `form:"FirstName"`
        LastName  string  `form:"LastName"`
        Email     string  `form:"Email"`
    }
    
    type Users []User
    

    My HTML Form (or something like that):

    <form method="POST">
      <input type="text" name="User[0].FirstName" value="FirstName1">
      <input type="text" name="User[0].LastName" value="LastName1">
      <input type="text" name="User[0].Email" value="[email protected]">
      <input type="text" name="User[1].FirstName" value="FirstName2">
      <input type="text" name="User[1].LastName" value="LastName2">
      <input type="text" name="User[1].Email" value="[email protected]">
      <input type="submit">
    </form>
    

    My Handler

    func MyHandler(w http.ResponseWriter, req *http.Request) error {
    	decoder = formam.NewDecoder(&formam.DecoderOptions{
    		TagName:           "form",
    		IgnoreUnknownKeys: true,
    	})
    
    	if err := req.ParseForm(); err != nil {
    		return err
    	}
    
            u := &models.Users{}
    	if err := decoder.Decode(req.Form, u); err != nil {
    		return err
    	}
    }
    
    bug 
    opened by dmuriel 15
  • Integers are overflowed silently

    Integers are overflowed silently

    Right now this library silently overflows integers. For example, filling in 300 for an uint8 results in 44, since the maximum size is 256 and 300 - 256 = 44.

    Personally I think this behaviour is rather surprising, and would expect an error from this library.

    Thoughts?

    opened by arp242 11
  • panic on reflect

    panic on reflect

    Just updated (removed repo and did go get -u on this repo) and im getting a panic on reflection

    18:6:37 app         | 2016/05/15 18:06:37 panic: reflect: slice index out of range
    Stack trace:
    goroutine 42 [running]:
    runtime/debug.Stack(0x0, 0x0, 0x0)
        /home/david/.gvm/gos/go1.6/src/runtime/debug/stack.go:24 +0x80
    gitlab.com/dvwallin/1spot/vendor/github.com/valyala/fasthttp.(*workerPool).workerFunc.func1(0xc82018c680, 0xc820199ed0)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/valyala/fasthttp/workerpool.go:207 +0x53
    panic(0x99b7c0, 0xc820075c10)
        /home/david/.gvm/gos/go1.6/src/runtime/panic.go:426 +0x4e9
    reflect.Value.Index(0x9877a0, 0xc8200a41d0, 0x197, 0xffffffffffffffff, 0x0, 0x0, 0x0)
        /home/david/.gvm/gos/go1.6/src/reflect/value.go:854 +0x151
    gitlab.com/dvwallin/1spot/vendor/github.com/monoculum/formam.(*decoder).decode(0xc820199250, 0x0, 0x0)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/monoculum/formam/formam.go:209 +0x10ad
    gitlab.com/dvwallin/1spot/vendor/github.com/monoculum/formam.(*decoder).end(0xc820199250, 0x0, 0x0)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/monoculum/formam/formam.go:189 +0xb5
    gitlab.com/dvwallin/1spot/vendor/github.com/monoculum/formam.(*decoder).begin(0xc820199250, 0x0, 0x0)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/monoculum/formam/formam.go:132 +0x562
    gitlab.com/dvwallin/1spot/vendor/github.com/monoculum/formam.Decode(0xc820199350, 0x970ee0, 0xc8200a41b0, 0x0, 0x0)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/monoculum/formam/formam.go:68 +0x3bf
    gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris.(*Context).ReadForm(0xc820098780, 0x970ee0, 0xc8200a41b0, 0x0, 0x0)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris/context_binder.go:98 +0x26b
    gitlab.com/dvwallin/1spot/libs/handlerslib.AddEventPostHandler(0xc820098780)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/libs/handlerslib/eventsRouteHandler.go:45 +0x9b
    gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris.HandlerFunc.Serve(0xc6e788, 0xc820098780)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris/handler.go:62 +0x26
    gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris.(*Context).Next(0xc820098780)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris/context.go:154 +0x80
    main.IsLord(0xc820098780)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/main.go:37 +0x1b8
    gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris.HandlerFunc.Serve(0xc6eed0, 0xc820098780)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris/handler.go:62 +0x26
    gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris.(*Context).Next(0xc820098780)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris/context.go:154 +0x80
    main.IsLoggedIn(0xc820098780)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/main.go:19 +0x1b8
    gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris.HandlerFunc.Serve(0xc6eec8, 0xc820098780)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris/handler.go:62 +0x26
    gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris.(*Context).Next(0xc820098780)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris/context.go:154 +0x80
    gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris/middleware/pongo2.(*pongo2Middleware).Serve(0x10e2380, 0xc820098780)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris/middleware/pongo2/pongo2.go:39 +0x33
    gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris.(*Context).Do(0xc820098780)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris/context.go:144 +0x5d
    gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris.(*tree).serve(0xc820162d20, 0xc820152480, 0xc8200df380, 0x11, 0x1)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris/tree.go:140 +0x1be
    gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris.(*router).serveFunc(0xc82017e190, 0xc820152480)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris/router.go:159 +0x256
    gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris.(*router).(gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris.serveFunc)-fm(0xc820152480)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/kataras/iris/router.go:74 +0x2a
    gitlab.com/dvwallin/1spot/vendor/github.com/valyala/fasthttp.(*Server).serveConn(0xc82018a8c0, 0x7fc6450a4668, 0xc82016a2a8, 0x0, 0x0)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/valyala/fasthttp/server.go:1452 +0x767
    gitlab.com/dvwallin/1spot/vendor/github.com/valyala/fasthttp.(*Server).(gitlab.com/dvwallin/1spot/vendor/github.com/valyala/fasthttp.serveConn)-fm(0x7fc6450a4668, 0xc82016a2a8, 0x0, 0x0)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/valyala/fasthttp/server.go:1183 +0x42
    gitlab.com/dvwallin/1spot/vendor/github.com/valyala/fasthttp.(*workerPool).workerFunc(0xc82018c680, 0xc8201d65e0)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/valyala/fasthttp/workerpool.go:224 +0x11c
    gitlab.com/dvwallin/1spot/vendor/github.com/valyala/fasthttp.(*workerPool).getCh.func1(0xc82018c680, 0xc8201d65e0, 0x973220, 0xc8201d65e0)
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/valyala/fasthttp/workerpool.go:183 +0x2b
    created by gitlab.com/dvwallin/1spot/vendor/github.com/valyala/fasthttp.(*workerPool).getCh
        /home/david/.gvm/pkgsets/go1.6/global/src/gitlab.com/dvwallin/1spot/vendor/github.com/valyala/fasthttp/workerpool.go:185 +0x1e9
    
    opened by dvwallin 11
  • parse multiselect?

    parse multiselect?

    For this example, I'm unable to use a multiselect. I have not tried any other element such as checkbox or file. This is a huge show-stopper for me.

    <select multiple="multiple" name="mydata[]">

    Or

    <select multiple="multiple" name="mydata">

    Struct:

    type MyDataStruct struct {
        Data    []string   `formam:"mydata"`
    }
    
    bug 
    opened by xpbliss 10
  • Decoding a multi-checkbox fieldset

    Decoding a multi-checkbox fieldset

    Hi! Thanks for your great library.

    I have encountered an issue with decoding fieldsets:

            <fieldset>
                <legend>Select labels</legend>
                <input type="checkbox" name="labels" value="label1">label1
                <input type="checkbox" name="labels" value="label2">label2
                <input type="checkbox" name="labels" value="label3">label3
                <input type="checkbox" name="labels" value="label4">label4
            </fieldset>
    

    When selecting multiple checkboxes, the form data is sent appropriately as expected:

    INFO[2020-09-20T08:44:35+02:00] /submit/ content_type=application/x-www-form-urlencoded db=0s duration=1.374036ms form="{\"authenticity_token\":[\"MONVHBgDotwySs80XP5vV901VtmULCrk73Sxe5oYSN+hUpiIPKnGdO8DBRUlizJBmbkganMr4C6QfPNJsHnncg==\"],\"description\":[\"test\"],\"labels\":[\"label1\",\"label2\",\"label3\",\"label4\"], ...
    

    But then when decoded into a []string only the first value is unmarshalled, and the []string results in:

    BOUND ENTRY: &models.Entry{Title:"Test", Description:"Test", Labels:slices.String{"tileable"}}
    

    For extra info, I don't think it matters but just in case, I'm using gobuffalo's Bind() function and the type I unmarshal into is not directly a []string but a wrapper around it, a slices.String from gobuffalo's pop/slices package.

    opened by Ullaakut 7
  • Call UnmarshalText for every value if the name ends with []

    Call UnmarshalText for every value if the name ends with []

    I have the following problem: one of my forms has a setting with a bitmask, this all works grand, but right now there is, as far as I can find, no way to tell Formam to decode that since it always uses the first value.

    So with my form:

    <input type="checkbox" name="settings.collect[]" value="1"> One</label>
    <input type="checkbox" name="settings.collect[]" value="2"> Two</label>
    <input type="checkbox" name="settings.collect[]" value="4"> Two</label>
    

    Formam will just set the first value that is selected.

    With this change, if the name ends with "[]" it will call UnmarshalText() on all values. I think it might make sense to just always do this, but that wouldn't be backwards-compatible so this is probably better.

    opened by arp242 6
  • Ignore unknown keys in brackets

    Ignore unknown keys in brackets

    For example:

    [Foo]: bar
    Foo[bar]: foobar
    

    Previously this would error out with:

    --- FAIL: TestIgnoreBracketedKeys (0.00s)
    	--- FAIL: TestIgnoreBracketedKeys/struct (0.00s)
    		formam_test.go:753: formam: the field "" in path "His[Wife]" has a index for array but it is a struct
    	--- FAIL: TestIgnoreBracketedKeys/slice (0.00s)
    		formam_test.go:772: formam: the index of slice is not a number in the field "" of path "His[Wife]"
    

    I don't think this is the correct behaviour if IgnoreUnknownKeys is given.

    opened by arp242 6
  • How to use not indexed arrays?

    How to use not indexed arrays?

    How to use not indexed arrays?

    From your example, when I trying change:

      <input type="text" name="Founders[0]" value="Masaru Ibuka"/>
      <input type="text" name="Founders[1]" value="Akio Morita"/>
    
    

    to

      <input type="text" name="Founders[]" value="Masaru Ibuka"/>
      <input type="text" name="Founders[]" value="Akio Morita"/>
    

    I got: runtime error: slice bounds out of range

    enhancement 
    opened by mrLSD 6
  • Improve analyzePath

    Improve analyzePath

    1. In current implementation there is no support for nested brackets in key/field names

    For example:

    // pseudocode
    
    // "Map[a[b][c]d]" : "123"
    var m map[string]map[string]string
    m["a[b"]["c]d"] = "123"
    // must be m["a[b][c]d"] = "123"
    
    // Map[a[b[c[[]]]]: "321"
    var m map[string]map[string]map[string]map[string]string
    m["a[b[c[["][""][""][""] = "321"
    // must be m["a[b[c[[]]]"] = "321"
    
    // and so on
    // for more examples see tests
    
    1. Decoder panics on "array index out of bounds"
    var s struct {
      A [1]string{}
    }
    
    vals := url.Values{
      "A[2]": []string{"A"},
    }
    
    dec.Decode(vals, &s)
    // panics "array index out of bounds"
    // must return error instead
    
    1. Nested indirects (pointers/interface{})
    var m TestStruct struct {
    	PointerToPointer **string
            InterfaceStruct interface{}
    }
    m.InterfaceStruct = new(struct {
      ID int
      Name string
      Interface interface{}
    })
    
    vals := url.Values{
      "PointerToPointer": []string{"PointerToPointer"},
      "InterfaceStruct.Interface": []string{"InterfaceStruct.Interface"},
    }
    
    

    This PR fixes it: Allow unbalanced and nested brackets Allow nested indirects (pointer or interface{}) Fix panic on "array index is out of bounds" - return error

    I will check benchmark results with these changes and post it here later

    opened by darigaaz 4
  • Array indexed values need some form of length limit to prevent attack

    Array indexed values need some form of length limit to prevent attack

    The code to expand a slice based on an array index ends up calling reflect.MakeSlice with a user-controlled length value: https://github.com/monoculum/formam/blob/master/formam.go#L570

    This could be abused by a malicious user to force large memory allocations in a Go web application.

    A workaround could be to provide a default length limit (16k or similar) in the DecoderOptions and allow the user to override this.

    opened by hdm 4
  • Missmatching major version and semantic import version (SIV)

    Missmatching major version and semantic import version (SIV)

    Currently this module shows up on go.dev as having no version released https://pkg.go.dev/github.com/monoculum/formam. This is because there is no release where the major version matches the import version.

    The only change needed is to to add the suffix v3 to the module name declared in go.mod.

    module github.com/monoculum/formam/v3
    

    Of course a new minor release would be necessary too.

    An effect this will have is that from now on people would need to use SIV when importing your module.

    Cheers.

    opened by D1CED 3
  • Allow map keys with brackets

    Allow map keys with brackets

    Code:

    	var s struct {
    		MapStringString    map[string]string
    		MapStringPtrStruct map[string]struct {
    			ID string
    		}
    		MapStringMapStringString map[string]map[string]string
    	}
    
    	vals := url.Values{
    		"MapStringString[a[b][c]d]":             []string{"MapStringString[a[b][c]d]"},
    		"MapStringString[name.with.dots]":       []string{"MapStringString[name.with.dots]"},
    		"MapStringPtrStruct[k2]ID":              []string{"MapStringPtrStruct[k2]ID"},
    		"MapStringMapStringString[a[b[c]d]]q]w": []string{"MapStringMapStringString[a[b[c]d]]q]w"},
    	}
    
    	dec := formam.NewDecoder(nil)
    

    Expected: no errors, correct parsing with brakets in key's names Actual: uninformative unrelated error: error when decode formam: has an array index but it is a string

    opened by darigaaz 0
Releases(v3.6.0)
  • v3.6.0(Oct 2, 2021)

    • feature: Call UnmarshalText for every value if the name ends with [] #38
    • fixbug: Check array length when traversing array #40
    • fixbug: Error "unsupported type; ..." with map[string]*struct #42
    • fixbug: Decoding to struct with multiple embedded types with IgnoreUnknownKeys #46
    Source code(tar.gz)
    Source code(zip)
  • v3.5.0(Sep 23, 2020)

    • Disable UnmarshalText interface by the DecoderOptions struct. #34
    • Fixed a bug when the traverse function fails and the current index/key was not flushed #35
    Source code(tar.gz)
    Source code(zip)
  • v3.4.0(Sep 5, 2020)

    • Limit the array size to 16,000 by default to prevent people sending [9999999]key to starve a machine of memory. This can be configured with MaxSize in DecoderOptions. #32
    Source code(tar.gz)
    Source code(zip)
Owner
Monoculum
Monoculum
HTML forms for Golang

HTML forms for Golang Installation: go get github.com/vmihailenco/gforms Example Example: package blog import ( "net/http" "github.com/vmih

Vladimir Mihailenco 39 Apr 3, 2020
Golang Forms made easy.

Go-FORM-it Description go-form-it makes form creation and handling easy. It allows the creation of form without having to write HTML code or bother to

Alessandro Frossi 68 Jun 3, 2021
Go library for parsing and submitting HTML forms

gosubmit Description Docs are available here: https://godoc.org/github.com/jeremija/gosubmit Helps filling out plain html forms during testing. Will a

Jerko Steiner 18 Mar 3, 2022
Trims, sanitizes & scrubs data based on struct tags (go, golang)

Conform- keep user input in check (go, golang) Trim, sanitize, and modify struct string fields in place, based on tags. Update Jan 12, 2016 -- Now als

Lee Benson 261 Jun 4, 2022
Go module for encoding structs into URL query parameters

qs Package sonh/qs encodes structs into url.Values. Installation go get github.com/sonh/qs Usage import ( "github.com/sonh/qs" ) Package qs export

Son Huynh 62 Jun 12, 2022
A Form Encoding & Decoding Package for Go

form A Form Encoding & Decoding Package for Go, written by Alvaro J. Genial. Synopsis This library is designed to allow seamless, high-fidelity encodi

Alvaro J. Genial 225 Apr 18, 2022
:steam_locomotive: Decodes url.Values into Go value(s) and Encodes Go value(s) into url.Values. Dual Array and Full map support.

Package form Package form Decodes url.Values into Go value(s) and Encodes Go value(s) into url.Values. It has the following features: Supports map of

Go Playgound 533 Jun 22, 2022
Go generator to copy values from type to type and fields from struct to struct. Copier without reflection.

Copygen is a command-line code generator that generates type-to-type and field-to-field struct code without adding any reflection or dependenc

SwitchUpCB 146 Jun 28, 2022
Decode / encode XML to/from map[string]interface{} (or JSON); extract values with dot-notation paths and wildcards. Replaces x2j and j2x packages.

mxj - to/from maps, XML and JSON Decode/encode XML to/from map[string]interface{} (or JSON) values, and extract/modify values from maps by key or key-

Charles Banning 521 Jun 28, 2022
Decode / encode XML to/from map[string]interface{} (or JSON); extract values with dot-notation paths and wildcards. Replaces x2j and j2x packages.

mxj - to/from maps, XML and JSON Decode/encode XML to/from map[string]interface{} (or JSON) values, and extract/modify values from maps by key or key-

Charles Banning 520 Jun 19, 2022
☄ The golang convenient converter supports Database to Struct, SQL to Struct, and JSON to Struct.

Gormat - Cross platform gopher tool The golang convenient converter supports Database to Struct, SQL to Struct, and JSON to Struct. 中文说明 Features Data

永林 271 Jun 21, 2022
Encode and decode Go (golang) struct types via protocol buffers.

protostructure protostructure is a Go library for encoding and decoding a struct type over the wire. This library is useful when you want to send arbi

Mitchell Hashimoto 171 Mar 24, 2022
Match regex group into go struct using struct tags and automatic parsing

regroup Simple library to match regex expression named groups into go struct using struct tags and automatic parsing Installing go get github.com/oris

Ori Seri 111 Jun 24, 2022
library for working amorphous data (as when you decode json into an interface{})

Introduction Decoding json into an interface{} produces an hierarchical arrangement of four data types: float64, string are 'primative types' and form

Chuck Luciano 9 Jul 5, 2021
golibwireshark - Package use libwireshark library to decode pcap file and analyse dissection data.

golibwireshark Package golibwireshark use libwireshark library to decode pcap file and analyse dissection data. This package can only be used in OS li

Xiaoguang Wang 24 Mar 2, 2022
HTML forms for Golang

HTML forms for Golang Installation: go get github.com/vmihailenco/gforms Example Example: package blog import ( "net/http" "github.com/vmih

Vladimir Mihailenco 39 Apr 3, 2020
Golang Forms made easy.

Go-FORM-it Description go-form-it makes form creation and handling easy. It allows the creation of form without having to write HTML code or bother to

Alessandro Frossi 68 Jun 3, 2021
Go library for parsing and submitting HTML forms

gosubmit Description Docs are available here: https://godoc.org/github.com/jeremija/gosubmit Helps filling out plain html forms during testing. Will a

Jerko Steiner 18 Mar 3, 2022
Forms is a fast, powerful, flexible, sortable web form rendering library written in golang.

forms Description forms makes form creation and handling easy. It allows the creation of form without having to write HTML code or bother to make the

coscms 21 Jun 15, 2022
It's so many regular expression forms are difficult to understand, such as perl, python, grep awk

Introduction Jamie Zawinski: Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems. It

aceking 0 Mar 31, 2022
DeepCopy a portable app that allows you to copy all forms of specified file types from your entire file system of the computer

DeepCopy a portable app that allows you to copy all forms of specified file types from your entire file system of the computer

subrahmanya  s hegade 1 Dec 20, 2021
Go-httpheaders - Canonicalized forms of common HTTP headers for Go

Go-httpheaders - Canonicalized forms of common HTTP headers for Go

Matt Robenolt 6 Mar 20, 2022
goconfig uses a struct as input and populates the fields of this struct with parameters from command line, environment variables and configuration file.

goconfig goconfig uses a struct as input and populates the fields of this struct with parameters from command line, environment variables and configur

Go Sidekick 0 May 30, 2022
Pagser is a simple, extensible, configurable parse and deserialize html page to struct based on goquery and struct tags for golang crawler

Pagser Pagser inspired by page parser。 Pagser is a simple, extensible, configurable parse and deserialize html page to struct based on goquery and str

foolin 62 Jun 13, 2022
:100:Go Struct and Field validation, including Cross Field, Cross Struct, Map, Slice and Array diving

Package validator Package validator implements value validations for structs and individual fields based on tags. It has the following unique features

Go Playgound 10.7k Jun 26, 2022
Copier for golang, copy value from struct to struct and more

Copier I am a copier, I copy everything from one to another Features Copy from field to field with same name Copy from method to field with same name

Jinzhu 3.2k Jun 25, 2022
💯 Go Struct and Field validation, including Cross Field, Cross Struct, Map, Slice and Array diving

Package validator implements value validations for structs and individual fields based on tags.

Flamego 12 Feb 16, 2022
Go library for decoding generic map values into native Go structures and vice versa.

mapstructure mapstructure is a Go library for decoding generic map values to structures and vice versa, while providing helpful error handling. This l

Mitchell Hashimoto 5.8k Jun 26, 2022
Go library for decoding generic map values into native Go structures and vice versa.

mapstructure mapstructure is a Go library for decoding generic map values to structures and vice versa, while providing helpful error handling. This l

Mitchell Hashimoto 5.8k Jun 23, 2022