Example #1
0
// Convert an opt args struct to a map.
func optArgsToMap(optArgs OptArgs) map[string]interface{} {
	data, err := encoding.Encode(optArgs)

	if err == nil && data != nil {
		if m, ok := data.(map[string]interface{}); ok {
			return m
		}
	}

	return map[string]interface{}{}
}
Example #2
0
func encode(data interface{}) (interface{}, error) {
	if _, ok := data.(Term); ok {
		return data, nil
	}

	v, err := encoding.Encode(data)
	if err != nil {
		return nil, err
	}

	return v, nil
}
Example #3
0
func expr(value interface{}, depth int) RqlTerm {
	if depth <= 0 {
		panic("Maximum nesting depth limit exceeded")
	}

	switch val := value.(type) {
	case RqlTerm:
		return val
	case time.Time:
		return EpochTime(val.Unix())
	case []interface{}:
		vals := []RqlTerm{}
		for _, v := range val {
			vals = append(vals, expr(v, depth))
		}

		return makeArray(vals)
	case map[string]interface{}:
		vals := map[string]RqlTerm{}
		for k, v := range val {
			vals[k] = expr(v, depth)
		}

		return makeObject(vals)
	default:
		// Use reflection to check for other types
		typ := reflect.TypeOf(val)

		if typ.Kind() == reflect.Func {
			return makeFunc(val)
		}
		if typ.Kind() == reflect.Struct {
			data, err := encoding.Encode(val)

			if err != nil || data == nil {
				return RqlTerm{
					termType: p.Term_DATUM,
					data:     nil,
				}
			}

			return expr(data, depth-1)
		}

		// If no other match was found then return a datum value
		return RqlTerm{
			termType: p.Term_DATUM,
			data:     val,
		}
	}
}
func expr(value interface{}, depth int) Term {
	if depth <= 0 {
		panic("Maximum nesting depth limit exceeded")
	}

	if value == nil {
		return Term{
			termType: p.Term_DATUM,
			data:     nil,
		}
	}

	switch val := value.(type) {
	case Term:
		return val
	case time.Time:
		return EpochTime(val.Unix())
	case []interface{}:
		vals := []Term{}
		for _, v := range val {
			vals = append(vals, expr(v, depth))
		}

		return makeArray(vals)
	case map[string]interface{}:
		vals := map[string]Term{}
		for k, v := range val {
			vals[k] = expr(v, depth)
		}

		return makeObject(vals)
	default:
		// Use reflection to check for other types
		typ := reflect.TypeOf(val)
		rval := reflect.ValueOf(val)

		if typ.Kind() == reflect.Ptr || typ.Kind() == reflect.Interface {
			v := reflect.ValueOf(val)

			if v.IsNil() {
				return Term{
					termType: p.Term_DATUM,
					data:     nil,
				}
			}

			val = v.Elem().Interface()
			typ = reflect.TypeOf(val)
		}

		if typ.Kind() == reflect.Func {
			return makeFunc(val)
		}
		if typ.Kind() == reflect.Struct {
			data, err := encoding.Encode(val)

			if err != nil || data == nil {
				return Term{
					termType: p.Term_DATUM,
					data:     nil,
				}
			}

			return expr(data, depth-1)
		}
		if typ.Kind() == reflect.Slice || typ.Kind() == reflect.Array {
			vals := []Term{}
			for i := 0; i < rval.Len(); i++ {
				vals = append(vals, expr(rval.Index(i).Interface(), depth))
			}

			return makeArray(vals)
		}
		if typ.Kind() == reflect.Map {
			vals := map[string]Term{}
			for _, k := range rval.MapKeys() {
				vals[k.String()] = expr(rval.MapIndex(k).Interface(), depth)
			}

			return makeObject(vals)
		}

		// If no other match was found then return a datum value
		return Term{
			termType: p.Term_DATUM,
			data:     val,
		}
	}
}