package snap import ( "fmt" "net/url" "strconv" "strings" "time" ) type OptionsProvider interface { Get(key string) (string, bool) } type Options struct { kv OptionsProvider } // FormValueProvider we only care about something that can provide us the K/V lookup type FormValueProvider interface { FormValue(string) string } // Form wraps utility functions around HTTP Form values type Form struct { r FormValueProvider } func (f *Form) Get(k string) (string, bool) { v := f.r.FormValue(k) if v == "" { return v, false } return v, true } type Vars struct { vars map[string]string } func (c Vars) Get(k string) (string, bool) { v, ok := c.vars[k] return v, ok } type Query struct { Values url.Values } func (q *Query) Get(key string) (string, bool) { value, ok := q.Values[key] if ok { return value[0], true } return "", false } func (o *Options) GetVar(k string) (string, bool) { return o.kv.Get(k) } func (o *Options) GetVarDefault(k string, def string) string { v, ok := o.kv.Get(k) if !ok { return def } return v } func (o *Options) GetVarAsSlice(k string, delim string, def []string) []string { v, ok := o.kv.Get(k) if !ok { return def } r := strings.Split(v, delim) if len(r) == 1 && r[0] == "" { return def } return r } // StringValue returns form value as a string func (o *Options) StringValue(k string) (string, bool) { return o.kv.Get(k) } // Uint64Value returns the first value in a set as uint64 func (o *Options) Uint64Value(k string) (uint64, bool) { str, ok := o.kv.Get(k) if !ok { return 0, ok } val, err := strconv.ParseUint(str, 10, 64) if err != nil { return 0, false } return val, true } // StringSlice returns multiple values assigned to the same key as a string slice func (o *Options) StringSlice(k string, delim string) ([]string, bool) { str, ok := o.kv.Get(k) if !ok { return nil, ok } r := strings.Split(str, delim) if len(r) == 1 && r[0] == "" { return nil, false } return r, true } // TimeValue returns a parsed time value for the specified key, // // if the key does not exist the but defaultValue was set it will return the defaultValue // otherwise it will return the passed in time or an error if parsing failed func (o *Options) TimeValue(key, timeFormat string, defaultValue *time.Time) time.Time { str, ok := o.kv.Get(key) if !ok { if defaultValue != nil { return *defaultValue } return time.Time{} } t, err := time.Parse(timeFormat, str) if err != nil { fmt.Printf("Err: %v", err) return time.Time{} } return t } type CompoundOptions struct { kvs []OptionsProvider } func (c *CompoundOptions) Get(key string) (string, bool) { for _, kv := range c.kvs { if v, ok := kv.Get(key); ok { return v, true } } return "", false }