domogeek/vendor/github.com/dolanor/caldav-go/icalendar/reflect.go

79 lines
1.8 KiB
Go

package icalendar
import (
"fmt"
"github.com/dolanor/caldav-go/icalendar/properties"
"github.com/dolanor/caldav-go/utils"
"log"
"reflect"
"strings"
)
var _ = log.Print
func isInvalidOrEmptyValue(v reflect.Value) bool {
if !v.IsValid() {
return true
}
switch v.Kind() {
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
return v.Len() == 0
case reflect.Bool:
return !v.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return v.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return v.Uint() == 0
case reflect.Float32, reflect.Float64:
return v.Float() == 0
case reflect.Interface, reflect.Ptr:
return v.IsNil()
}
return false
}
func newValue(in reflect.Value) (out reflect.Value, isArrayElement bool) {
typ := in.Type()
kind := typ.Kind()
for {
if kind == reflect.Array || kind == reflect.Slice {
isArrayElement = true
} else if kind != reflect.Ptr {
break
}
typ = typ.Elem()
kind = typ.Kind()
}
out = reflect.New(typ)
return
}
func dereferencePointerValue(v reflect.Value) reflect.Value {
for (v.Kind() == reflect.Interface || v.Kind() == reflect.Ptr) && v.Elem().IsValid() {
v = v.Elem()
}
return v
}
func extractTagFromValue(v reflect.Value) (string, error) {
vdref := dereferencePointerValue(v)
vtemp, _ := newValue(vdref)
if encoder, ok := vtemp.Interface().(properties.CanEncodeTag); ok {
if tag, err := encoder.EncodeICalTag(); err != nil {
return "", utils.NewError(extractTagFromValue, "unable to extract tag from interface", v.Interface(), err)
} else {
return strings.ToUpper(tag), nil
}
} else {
typ := vtemp.Elem().Type()
return strings.ToUpper(fmt.Sprintf("v%s", typ.Name())), nil
}
}