79 lines
1.8 KiB
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
|
||
|
}
|
||
|
|
||
|
}
|