func unmarshal(arg UnionSassValue, v interface{}) error { //Get the underlying value of v and its kind f := reflect.ValueOf(v) if f.Kind() == reflect.Ptr { f = f.Elem() } k := f.Kind() t := f.Type() if k == reflect.Interface { switch { default: return errors.New("Uncovertable interface value. Specify type desired.") case bool(C.sass_value_is_null(arg)): f.Set(reflect.ValueOf("<nil>")) return nil case bool(C.sass_value_is_string(arg)): k = reflect.String case bool(C.sass_value_is_boolean(arg)): k = reflect.Bool case bool(C.sass_value_is_color(arg)) || bool(C.sass_value_is_number(arg)): k = reflect.Struct case bool(C.sass_value_is_list(arg)): k = reflect.Slice t = reflect.SliceOf(t) case bool(C.sass_value_is_error(arg)): // This should get implemented as type error k = reflect.String } } switch k { default: return errors.New("Unsupported SassValue") case reflect.Invalid: return errors.New("Invalid SASS Value - Taylor Swift") case reflect.String: if C.sass_value_is_string(arg) || C.sass_value_is_error(arg) { c := C.sass_string_get_value(arg) gc := C.GoString(c) //drop quotes if t, err := strconv.Unquote(gc); err == nil { gc = t } if strings.HasPrefix(gc, "'") && strings.HasSuffix(gc, "'") { gc = gc[1 : len(gc)-1] } if !f.CanSet() { return errors.New("Can not set string") } switch t := f.Kind(); t { case reflect.String: f.SetString(gc) case reflect.Interface: f.Set(reflect.ValueOf(gc)) } } else { return throwMisMatchTypeError(arg, "string") } case reflect.Bool: if C.sass_value_is_boolean(arg) { b := bool(C.sass_boolean_get_value(arg)) f.Set(reflect.ValueOf(b)) } else { return throwMisMatchTypeError(arg, "bool") } case reflect.Struct: //Check for color if C.sass_value_is_color(arg) { col := color.RGBA{ R: uint8(C.sass_color_get_r(arg)), G: uint8(C.sass_color_get_g(arg)), B: uint8(C.sass_color_get_b(arg)), A: uint8(C.sass_color_get_a(arg)), } f.Set(reflect.ValueOf(col)) } else if C.sass_value_is_number(arg) { u, err := getSassNumberUnit(arg) if err != nil { return err } sn := SassNumber{ Value: float64(C.sass_number_get_value(arg)), Unit: u, } f.Set(reflect.ValueOf(sn)) } else { return throwMisMatchTypeError(arg, "color.RGBA or SassNumber") } case reflect.Slice: if C.sass_value_is_list(arg) { newv := reflect.MakeSlice(t, int(C.sass_list_get_length(arg)), int(C.sass_list_get_length(arg))) l := make([]interface{}, C.sass_list_get_length(arg)) for i := range l { err := unmarshal(C.sass_list_get_value(arg, C.size_t(i)), &l[i]) if err != nil { return err } newv.Index(i).Set(reflect.ValueOf(l[i])) } f.Set(newv) } else { return throwMisMatchTypeError(arg, "slice") } } return nil }
func IsNil(usv UnionSassValue) bool { return bool(C.sass_value_is_null(usv)) }