Parse runs the associated modifier function for the provided parameters. Depending on the type of p.Value, we may recursively run this method on every element of the structure. We're using reflect _quite_ heavily for this, meaning it's kind of unsafe, it'd be great if we could find another solution
(p *ParseParams)
| 26 | // it'd be great if we could find another solution while keeping it as |
| 27 | // abstract as it is. |
| 28 | func Parse(p *ParseParams) (val interface{}, err error) { |
| 29 | kind := reflect.TypeOf(p.Value).Kind() |
| 30 | |
| 31 | // If we have a slice/array, recursively run Parse on each element. |
| 32 | if kind == reflect.Slice || kind == reflect.Array { |
| 33 | s := reflect.ValueOf(p.Value) |
| 34 | for i := 0; i < s.Len(); i++ { |
| 35 | p.Value = s.Index(i).Interface() |
| 36 | if val, err = Parse(p); err != nil { |
| 37 | return nil, err |
| 38 | } |
| 39 | s.Index(i).Set(reflect.ValueOf(val)) |
| 40 | } |
| 41 | return s.Interface(), nil |
| 42 | } |
| 43 | |
| 44 | // If we have a map, recursively run Parse on each *key* and create a new |
| 45 | // map out of the return values. |
| 46 | if kind == reflect.Map { |
| 47 | result := reflect.MakeMap(reflect.TypeOf(p.Value)) |
| 48 | for _, key := range reflect.ValueOf(p.Value).MapKeys() { |
| 49 | p.Value = key.Interface() |
| 50 | if val, err = Parse(p); err != nil { |
| 51 | return nil, err |
| 52 | } |
| 53 | result.SetMapIndex(reflect.ValueOf(val), reflect.ValueOf(true)) |
| 54 | } |
| 55 | return result.Interface(), nil |
| 56 | } |
| 57 | |
| 58 | // Not a slice nor a map. |
| 59 | switch strings.ToUpper(p.Name) { |
| 60 | case "FORMAT": |
| 61 | val, err = p.format() |
| 62 | case "UPPER": |
| 63 | val = upper(p.Value.(string)) |
| 64 | case "LOWER": |
| 65 | val = lower(p.Value.(string)) |
| 66 | case "SHA1": |
| 67 | val, err = p.hash(FindHash(p.Name)()) |
| 68 | } |
| 69 | |
| 70 | if err != nil { |
| 71 | return nil, err |
| 72 | } |
| 73 | if val == nil { |
| 74 | return nil, &ErrNotImplemented{p.Name, p.Attribute} |
| 75 | } |
| 76 | return val, nil |
| 77 | } |
| 78 | |
| 79 | // format runs the correct format function based on the provided attribute. |
| 80 | func (p *ParseParams) format() (val interface{}, err error) { |