github.com/bosssauce/ponzu@v0.11.1-0.20200102001432-9bc41b703131/management/editor/values.go (about)

     1  package editor
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"strings"
     7  )
     8  
     9  // TagNameFromStructField does a lookup on the `json` struct tag for a given
    10  // field of a struct
    11  func TagNameFromStructField(name string, post interface{}) string {
    12  	// sometimes elements in these environments will not have a name,
    13  	// and thus no tag name in the struct which correlates to it.
    14  	if name == "" {
    15  		return name
    16  	}
    17  
    18  	field, ok := reflect.TypeOf(post).Elem().FieldByName(name)
    19  	if !ok {
    20  		panic("Couldn't get struct field for: " + name + ". Make sure you pass the right field name to editor field elements.")
    21  	}
    22  
    23  	tag, ok := field.Tag.Lookup("json")
    24  	if !ok {
    25  		panic("Couldn't get json struct tag for: " + name + ". Struct fields for content types must have 'json' tags.")
    26  	}
    27  
    28  	return tag
    29  }
    30  
    31  // TagNameFromStructFieldMulti calls TagNameFromStructField and formats is for
    32  // use with gorilla/schema
    33  // due to the format in which gorilla/schema expects form names to be when
    34  // one is associated with multiple values, we need to output the name as such.
    35  // Ex. 'category.0', 'category.1', 'category.2' and so on.
    36  func TagNameFromStructFieldMulti(name string, i int, post interface{}) string {
    37  	tag := TagNameFromStructField(name, post)
    38  
    39  	return fmt.Sprintf("%s.%d", tag, i)
    40  }
    41  
    42  // ValueFromStructField returns the string value of a field in a struct
    43  func ValueFromStructField(name string, post interface{}) string {
    44  	field := reflect.Indirect(reflect.ValueOf(post)).FieldByName(name)
    45  
    46  	switch field.Kind() {
    47  	case reflect.String:
    48  		return field.String()
    49  
    50  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    51  		return fmt.Sprintf("%v", field.Int())
    52  
    53  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
    54  		return fmt.Sprintf("%v", field.Uint())
    55  
    56  	case reflect.Bool:
    57  		return fmt.Sprintf("%t", field.Bool())
    58  
    59  	case reflect.Complex64, reflect.Complex128:
    60  		return fmt.Sprintf("%v", field.Complex())
    61  
    62  	case reflect.Float32, reflect.Float64:
    63  		return fmt.Sprintf("%v", field.Float())
    64  
    65  	case reflect.Slice:
    66  		s := []string{}
    67  
    68  		for i := 0; i < field.Len(); i++ {
    69  			pos := field.Index(i)
    70  			s = append(s, fmt.Sprintf("%v", pos))
    71  		}
    72  
    73  		return strings.Join(s, "__ponzu")
    74  
    75  	default:
    76  		panic(fmt.Sprintf("Ponzu: Type '%s' for field '%s' not supported.", field.Type(), name))
    77  	}
    78  }