Ejemplo n.º 1
0
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
}
Ejemplo n.º 2
0
func IsBool(usv UnionSassValue) bool {
	return bool(C.sass_value_is_boolean(usv))
}