func Stringify()

in cfn/encoding/stringify.go [41:113]


func Stringify(v interface{}) (interface{}, error) {
	var err error

	if v == nil {
		return nil, nil
	}

	val := reflect.ValueOf(v)

	switch val.Kind() {
	case reflect.String, reflect.Bool, reflect.Int, reflect.Float64:
		return fmt.Sprint(v), nil
	case reflect.Map:
		out := make(map[string]interface{})
		for _, key := range val.MapKeys() {
			v, err := Stringify(val.MapIndex(key).Interface())
			switch {
			case err != nil:
				return nil, err
			case v != nil:
				out[key.String()] = v
			}
		}
		return out, nil
	case reflect.Slice:
		out := make([]interface{}, val.Len())
		for i := 0; i < val.Len(); i++ {
			v, err = Stringify(val.Index(i).Interface())
			switch {
			case err != nil:
				return nil, err
			case v != nil:
				out[i] = v
			}
		}
		return out, nil
	case reflect.Struct:
		t := val.Type()

		out := reflect.New(stringifyStructType(t)).Elem()
		for i := 0; i < t.NumField(); i++ {
			f := t.Field(i)

			v := val.FieldByName(f.Name)

			if tag, ok := f.Tag.Lookup("json"); ok {
				if strings.Contains(tag, ",omitempty") {
					if v.IsZero() {
						continue
					}
				}
			}

			s, err := Stringify(v.Interface())
			switch {
			case err != nil:
				return nil, err
			case s != nil:
				out.Field(i).Set(reflect.ValueOf(s))
			}
		}

		return out.Interface(), nil
	case reflect.Ptr:
		if val.IsNil() {
			return nil, nil
		}

		return Stringify(val.Elem().Interface())
	}

	return nil, fmt.Errorf("Unsupported type: '%v'", val.Kind())
}