summaryrefslogtreecommitdiff
path: root/management/editor/values.go
blob: bc97f99214749a37f97ad223d45ce6cd93b8a3bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package editor

import (
	"fmt"
	"reflect"
	"strings"
)

// TagNameFromStructField does a lookup on the `json` struct tag for a given
// field of a struct
func TagNameFromStructField(name string, post interface{}) string {
	// sometimes elements in these environments will not have a name,
	// and thus no tag name in the struct which correlates to it.
	if name == "" {
		return name
	}

	field, ok := reflect.TypeOf(post).Elem().FieldByName(name)
	if !ok {
		panic("Couldn't get struct field for: " + name + ". Make sure you pass the right field name to editor field elements.")
	}

	tag, ok := field.Tag.Lookup("json")
	if !ok {
		panic("Couldn't get json struct tag for: " + name + ". Struct fields for content types must have 'json' tags.")
	}

	return tag
}

// TagNameFromStructFieldMulti calls TagNameFromStructField and formats is for
// use with gorilla/schema
// due to the format in which gorilla/schema expects form names to be when
// one is associated with multiple values, we need to output the name as such.
// Ex. 'category.0', 'category.1', 'category.2' and so on.
func TagNameFromStructFieldMulti(name string, i int, post interface{}) string {
	tag := TagNameFromStructField(name, post)

	return fmt.Sprintf("%s.%d", tag, i)
}

// ValueFromStructField returns the string value of a field in a struct
func ValueFromStructField(name string, post interface{}) string {
	field := reflect.Indirect(reflect.ValueOf(post)).FieldByName(name)

	switch field.Kind() {
	case reflect.String:
		return field.String()

	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return fmt.Sprintf("%v", field.Int())

	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return fmt.Sprintf("%v", field.Uint())

	case reflect.Bool:
		return fmt.Sprintf("%t", field.Bool())

	case reflect.Complex64, reflect.Complex128:
		return fmt.Sprintf("%v", field.Complex())

	case reflect.Float32, reflect.Float64:
		return fmt.Sprintf("%v", field.Float())

	case reflect.Slice:
		s := []string{}

		for i := 0; i < field.Len(); i++ {
			pos := field.Index(i)
			s = append(s, fmt.Sprintf("%v", pos))
		}

		return strings.Join(s, "__ponzu")

	default:
		panic(fmt.Sprintf("Ponzu: Type '%s' for field '%s' not supported.", field.Type(), name))
	}
}