// 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{}{} }
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 }
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, } } }