func (a *Article) add(key string, value string, begin bool) error { var err error switch strings.ToLower(key) { case idKey: err = input.Parse(value, &a.Id) case titleKey: if begin { a.Titles = append([]string{value}, a.Titles...) } else { a.Titles = append(a.Titles, value) } case slugKey: if begin { a.Slugs = append([]string{value}, a.Slugs...) } else { a.Slugs = append(a.Slugs, value) } case synopsisKey: a.Synopsis = value case updatedKey: var t time.Time switch strings.ToLower(value) { case "now": t = time.Now().UTC() case "today": t = time.Now().UTC().Truncate(24 * time.Hour) default: for _, v := range timeFormats { t, err = time.Parse(v, value) if err == nil { break } } } if err == nil { if begin { a.Updated = append([]time.Time{t}, a.Updated...) } else { a.Updated = append(a.Updated, t) } } case priorityKey: err = input.Parse(value, &a.Priority) default: if a.Properties == nil { a.Properties = make(map[string][]string) } a.Properties[key] = append(a.Properties[key], value) } return err }
func (c *Context) parseTypedValue(idx int, name string, val string, found bool, arg interface{}) error { if !found { return &MissingParameterError{Index: idx, Name: name} } if err := input.Parse(val, arg); err != nil { if err == types.ErrCantSet { // Programming error, user did not pass a pointer panic(err) } return &InvalidParameterError{ Index: idx, Name: name, Type: reflect.TypeOf(arg), Err: err, } } return nil }
func (o *Orm) setFieldsDefaults(f *driver.Fields) error { defaults := make(map[int]reflect.Value) for ii, v := range f.Tags { def := v.Value("default") if def == "" { continue } if driver.IsFunc(def) { // Currently we only support two hardcoded functions, now() and today() fname, _ := driver.SplitFuncArgs(def) fn, ok := ormFuncs[fname] if !ok { return fmt.Errorf("unknown orm function %s()", fname) } retType := fn.Type().Out(0) if retType != f.Types[ii] { return fmt.Errorf("type mismatch: orm function %s() returns %s, but field %s in %s is of type %s", fname, retType, f.QNames[ii], f.Type, f.Types[ii]) } if o.driver.Capabilities()&driver.CAP_DEFAULTS == 0 || !o.driver.HasFunc(fname, retType) { defaults[ii] = fn } } else { // Raw value, only to be stored in defaults if the driver // does not support CAP_DEFAULTS or it's a TEXT value and // the driver lacks CAP_DEFAULTS_TEXT caps := o.driver.Capabilities() if caps&driver.CAP_DEFAULTS != 0 && (caps&driver.CAP_DEFAULTS_TEXT != 0 || !isText(f, ii)) { continue } // Try to parse it ftyp := f.Types[ii] indirs := 0 for ftyp.Kind() == reflect.Ptr { indirs++ ftyp = ftyp.Elem() } val := reflect.New(ftyp) if err := input.Parse(def, val.Interface()); err != nil { return fmt.Errorf("invalid default value %q for field %s of type %s in %s: %s", def, f.QNames[ii], f.Types[ii], f.Type, err) } if indirs == 0 { defaults[ii] = val.Elem() } else { // Pointer, need to allocate a new value each time typ := f.Types[ii].Elem() defVal := val.Elem() f := func() reflect.Value { v := reflect.New(typ).Elem() for v.Kind() == reflect.Ptr { v.Set(reflect.New(v.Type().Elem())) v = v.Elem() } v.Set(defVal) return v } defaults[ii] = reflect.ValueOf(f) } } } if len(defaults) > 0 { f.Defaults = defaults } return nil }
func parseValue(v reflect.Value, raw string) error { switch v.Type().Kind() { case reflect.Bool: value, err := strconv.ParseBool(raw) if err != nil { return err } v.SetBool(value) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: value, err := strconv.ParseInt(raw, 10, 64) if err != nil { return err } v.SetInt(int64(value)) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: value, err := strconv.ParseUint(raw, 10, 64) if err != nil { return err } v.SetUint(uint64(value)) case reflect.Float32, reflect.Float64: value, err := strconv.ParseFloat(raw, 64) if err != nil { return err } v.SetFloat(value) case reflect.String: v.SetString(raw) case reflect.Slice: fields, err := stringutil.SplitFields(raw, ",") if err != nil { return fmt.Errorf("error splitting values: %s", err) } count := len(fields) v.Set(reflect.MakeSlice(v.Type(), count, count)) for ii, f := range fields { if err := input.Parse(f, v.Index(ii).Addr().Interface()); err != nil { return fmt.Errorf("error parsing field at index %d: %s", ii, err) } } case reflect.Map: fields, err := stringutil.SplitFields(raw, ",") if err != nil { return fmt.Errorf("error splitting values: %s", err) } v.Set(reflect.MakeMap(v.Type())) ktyp := v.Type().Key() etyp := v.Type().Elem() for ii, field := range fields { subFields, err := stringutil.SplitFields(field, "=") if err != nil { return fmt.Errorf("error splitting key-value %q: %s", field, err) } k := reflect.New(ktyp) if err := input.Parse(subFields[0], k.Interface()); err != nil { return fmt.Errorf("error parsing key at index %d: %s", ii, err) } elem := reflect.New(etyp) if len(subFields) < 2 { return fmt.Errorf("invalid map field %q", field) } if err := input.Parse(subFields[1], elem.Interface()); err != nil { return fmt.Errorf("error parsing value at index %d: %s", ii, err) } v.SetMapIndex(k.Elem(), elem.Elem()) } default: parser, ok := v.Interface().(input.Parser) if !ok { return fmt.Errorf("can't parse value of type %s", v.Type()) } if v.Kind() == reflect.Ptr && !v.Elem().IsValid() { v.Set(reflect.New(v.Type().Elem())) parser = v.Interface().(input.Parser) } return parser.Parse(raw) } return nil }