diff options
| author | Shulhan <ms@kilabit.info> | 2022-06-08 22:19:42 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2022-06-08 23:16:00 +0700 |
| commit | 5ea6ee2f5beb2bacf0d74ce6da17a1f9a391a101 (patch) | |
| tree | 81b3ebe25b6a2445cf5f6de255bd3516c20764e4 /lib/http/form_example_test.go | |
| parent | 78bcc4bd3556b89f76ac75bf12082ee1c2b4c422 (diff) | |
| download | pakakeh.go-5ea6ee2f5beb2bacf0d74ce6da17a1f9a391a101.tar.xz | |
lib/http: add function to unmarshal url.Values using tag `form:`
UnmarshalForm read struct fields tagged with `form:` from out as key and
set its using the value from url.Values based on that key.
If the field does not have `form:` tag but it is exported, then it will
use the field name, in case insensitive.
Only the following types are supported: bool, int/intX, uint/uintX,
floatX, string, []byte, or type that implement BinaryUnmarshaler
(UnmarshalBinary), json.Unmarshaler (UnmarshalJSON), or TextUnmarshaler
(UnmarshalText).
A bool type can be set to true using the following string value: "true",
"yes", or "1".
If the input contains multiple values but the field type is not slice,
the field will be set using the first value.
It will return an error if the out variable is not set-able (the type is
not a pointer to a struct).
It will not return an error if one of the input value is not match with
field type.
Diffstat (limited to 'lib/http/form_example_test.go')
| -rw-r--r-- | lib/http/form_example_test.go | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/lib/http/form_example_test.go b/lib/http/form_example_test.go new file mode 100644 index 00000000..3482be72 --- /dev/null +++ b/lib/http/form_example_test.go @@ -0,0 +1,198 @@ +package http + +import ( + "fmt" + "math/big" + "net/url" +) + +func ExampleUnmarshalForm() { + type T struct { + Rat *big.Rat `form:"big.Rat"` + String string `form:"string"` + Bytes []byte `form:"bytes"` + Int int `form:""` // With empty tag. + F64 float64 `form:"f64"` + F32 float32 `form:"f32"` + NotSet int16 `form:"notset"` + Uint8 uint8 `form:" uint8 "` + Bool bool // Without tag. + } + var ( + in = url.Values{} + + out T + ptrOut *T + err error + ) + + in.Set("big.Rat", "1.2345") + in.Set("string", "a_string") + in.Set("bytes", "bytes") + in.Set("int", "1") + in.Set("f64", "6.4") + in.Set("f32", "3.2") + in.Set("uint8", "2") + in.Set("bool", "true") + + err = UnmarshalForm(in, &out) + if err != nil { + fmt.Println(err) + } else { + fmt.Printf("%+v\n", out) + } + + // Set the struct without initialized. + err = UnmarshalForm(in, &ptrOut) + if err != nil { + fmt.Println(err) + } else { + fmt.Printf("%+v\n", ptrOut) + } + + //Output: + //{Rat:2469/2000 String:a_string Bytes:[98 121 116 101 115] Int:1 F64:6.4 F32:3.2 NotSet:0 Uint8:2 Bool:true} + //&{Rat:2469/2000 String:a_string Bytes:[98 121 116 101 115] Int:1 F64:6.4 F32:3.2 NotSet:0 Uint8:2 Bool:true} +} + +func ExampleUnmarshalForm_error() { + type T struct { + Int int + } + + var ( + in = url.Values{} + + out T + ptrOut *T + err error + ) + + // Passing out as unsetable by function. + err = UnmarshalForm(in, out) + if err != nil { + fmt.Println(err) + } else { + fmt.Println(out) + } + + // Passing out as un-initialized pointer. + err = UnmarshalForm(in, ptrOut) + if err != nil { + fmt.Println(err) + } else { + fmt.Println(out) + } + + // Set the field with invalid type. + in.Set("int", "a") + err = UnmarshalForm(in, &out) + if err != nil { + fmt.Println(err) + } else { + fmt.Println(out) + } + + //Output: + //UnmarshalForm: expecting *T got http.T + //UnmarshalForm: *http.T is not initialized + //{0} + +} + +func ExampleUnmarshalForm_slice() { + type SliceT struct { + NotSlice string `form:"multi_value"` + SliceString []string `form:"slice_string"` + SliceInt []int `form:"slice_int"` + } + + var ( + in = url.Values{} + + sliceOut SliceT + ptrSliceOut *SliceT + err error + ) + + in.Add("multi_value", "first") + in.Add("multi_value", "second") + in.Add("slice_string", "multi") + in.Add("slice_string", "value") + in.Add("slice_int", "123") + in.Add("slice_int", "456") + + err = UnmarshalForm(in, &sliceOut) + if err != nil { + fmt.Println(err) + } else { + fmt.Printf("%+v\n", sliceOut) + } + + err = UnmarshalForm(in, &ptrSliceOut) + if err != nil { + fmt.Println(err) + } else { + fmt.Printf("%+v\n", ptrSliceOut) + } + + //Output: + //{NotSlice:first SliceString:[multi value] SliceInt:[123 456]} + //&{NotSlice:first SliceString:[multi value] SliceInt:[123 456]} +} + +func ExampleUnmarshalForm_zero() { + type T struct { + Rat *big.Rat `form:"big.Rat"` + String string `form:"string"` + Bytes []byte `form:"bytes"` + Int int `form:""` // With empty tag. + F64 float64 `form:"f64"` + F32 float32 `form:"f32"` + NotSet int16 `form:"notset"` + Uint8 uint8 `form:" uint8 "` + Bool bool // Without tag. + } + var ( + in = url.Values{} + + out T + err error + ) + + in.Set("big.Rat", "1.2345") + in.Set("string", "a_string") + in.Set("bytes", "bytes") + in.Set("int", "1") + in.Set("f64", "6.4") + in.Set("f32", "3.2") + in.Set("uint8", "2") + in.Set("bool", "true") + + err = UnmarshalForm(in, &out) + if err != nil { + fmt.Println(err) + } else { + fmt.Printf("%+v\n", out) + } + + in.Set("bool", "") + in.Set("int", "") + in.Set("uint8", "") + in.Set("f32", "") + in.Set("f64", "") + in.Set("string", "") + in.Set("bytes", "") + in.Set("big.Rat", "") + + err = UnmarshalForm(in, &out) + if err != nil { + fmt.Println(err) + } else { + fmt.Printf("%+v\n", out) + } + + //Output: + //{Rat:2469/2000 String:a_string Bytes:[98 121 116 101 115] Int:1 F64:6.4 F32:3.2 NotSet:0 Uint8:2 Bool:true} + //{Rat:0/1 String: Bytes:[] Int:0 F64:0 F32:0 NotSet:0 Uint8:0 Bool:false} +} |
