Documentation
¶
Overview ¶
Package urlvalues unmarshals URL values as defined by net/url into struct values.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrInvalidStruct = errors.New("urlvalues: target must be a struct pointer")
ErrInvalidStruct indicates that the Unmarshal target is not of correct type.
Functions ¶
func Unmarshal ¶
func Unmarshal(data url.Values, v any, setParseOpts ...SetParseOptionFunc) error
Unmarshal unmarshals data into the value pointed to by v. If v is nil or not a struct pointer, Unmarshal returns an ErrInvalidStruct error. If data is nil, Unmarshal returns without updating v's fields.
Slices are decoded by splitting URL values by a delimiter and parsing each item individually. The delimiter defaults to semicolon (;), but can by customized by passing the WithDelimiter SetParseOptionFunc. Key-value pairs of maps are split using the same delimiter. Keys and their values are separated by a colon (:), with the key to the left and the value to the right of the colon.
Fields with types implementing encoding.TextUnmarshaller and/or encoding.BinaryUnmarshaller will be decoded using those interfaces, respectively. If a type implements both interfaces, the encoding.TextUnmarshaller interface is used to decode the URL value.
The decoding of each struct field can be customized by the name string stored under the "urlvalue" key in the struct field's tag. The name string acts as a key into data, possibly followed by a comma-separated list of options. The name may be empty, in which case the field name of the struct will act as as key into data in its stead.
The "default" option allows for setting a default value on a field in case corresponding URL value is not present in data, or if the value is the zero value for the field's type.
The "layout" option only applies to fields of type time.Time and allows for customizing how URL values should be parsed by providing layouts understood by time.Parse.
As a special case, if the field tag is "-", the field is always omitted. Note that a field with name "-" can still be generated using the tag "-,".
Examples of struct field tags and their meanings:
// Field defaults to 42. Field int `urlvalue:"myName,default:42"` // Field is parsed using the RFC850 layout. Field time.Time `urlvalue:"myName,layout:RFC850"` // Field is ignored by this package. Field int `urlvalue:"-"` // Field appears in URL values with key "-". Field int `urlvalue:"-,"` // Field is decoded as time.Now().AddDate(3, -4, 9). Field time.Time `urlvalue:"myName,default:now+3y-4m+9d"`
The parsing of time.Time fields is extended to support a "now" based parsing. It parses the URL value "now" to time.Now(). Furthermore, it extends this syntax by allowing the consumer to subtract or add days (d), months (m) and years (y) to "now". This is done by prepending the date identifiers (d,m,y) with a minus (-) or plus (+) sign.
Any error that occurs while processing struct fields results in a FieldError. ParseError wraps around FieldError and is returned if any error occurs while parsing the data that was passed into Unmarshal. ParseError is never returned from errors occuring while parsing default values.
Example ¶
package main import ( "fmt" "net/http" "strings" "time" "github.com/nahojer/urlvalues" ) func main() { req, err := http.NewRequest(http.MethodGet, "http://localhost?since=now-3m&directors=Quentin%20Tarantino&directors=Christopher%20Nolan", nil) if err != nil { panic(err) } var params struct { Since time.Time `urlvalue:"since,default:now-3m,layout=2006-01-02"` Until time.Time `urlvalue:"until,default:now,layout=2006-01-02"` Genres []string `urlvalue:"genres,default:action;drama"` Directors []string `urlvalue:"directors"` } if err := urlvalues.Unmarshal(req.URL.Query(), ¶ms); err != nil { panic(err) } fmt.Printf("Genres: %s\n", strings.Join(params.Genres, ", ")) fmt.Printf("Directors: %s\n", strings.Join(params.Directors, ", ")) }
Output: Genres: action, drama Directors: Quentin Tarantino, Christopher Nolan
Types ¶
type FieldError ¶
type FieldError struct {
// contains filtered or unexported fields
}
FieldError occurs when a URL value failed to be decoded into a struct field.
func (*FieldError) Error ¶
func (err *FieldError) Error() string
type ParseError ¶
type ParseError struct { // Name of struct field. FieldName string // Key into URL values. Key string // contains filtered or unexported fields }
ParseError occurs when a URL value failed to be parsed into a struct field's type. It exposes the field name and the key used to extract the URL value. Internally, it holds the FieldError, which can be accessed by unwrapping the error.
func (*ParseError) Error ¶
func (e *ParseError) Error() string
func (*ParseError) Unwrap ¶
func (e *ParseError) Unwrap() error
Unwrap returns the underlying FieldError.
type ParseOptions ¶
type ParseOptions struct {
// contains filtered or unexported fields
}
ParseOptions holds all the options that allows for customizing the parsing behaviour when unmarshalling URL values.
func (*ParseOptions) Delim ¶
func (o *ParseOptions) Delim() string
Delim returns the delimiter used to convert slices and maps from and into their string representation. Defaults to semicolon (;) if not set or set to the empty string.
type SetParseOptionFunc ¶
type SetParseOptionFunc func(*ParseOptions)
SetParseOptionFunc allows for overriding parsing behaviour when unmarshalling URL values.
func WithDelimiter ¶
func WithDelimiter(s string) SetParseOptionFunc
WithDelimiter returns a SetParseOptionFunc that sets the delimiter used to convert slices and maps from and into their string representation.