1package log
2
3import "fmt"
4
5// InterleavedKVToFields converts keyValues a la Span.LogKV() to a Field slice
6// a la Span.LogFields().
7func InterleavedKVToFields(keyValues ...interface{}) ([]Field, error) {
8	if len(keyValues)%2 != 0 {
9		return nil, fmt.Errorf("non-even keyValues len: %d", len(keyValues))
10	}
11	fields := make([]Field, len(keyValues)/2)
12	for i := 0; i*2 < len(keyValues); i++ {
13		key, ok := keyValues[i*2].(string)
14		if !ok {
15			return nil, fmt.Errorf(
16				"non-string key (pair #%d): %T",
17				i, keyValues[i*2])
18		}
19		switch typedVal := keyValues[i*2+1].(type) {
20		case bool:
21			fields[i] = Bool(key, typedVal)
22		case string:
23			fields[i] = String(key, typedVal)
24		case int:
25			fields[i] = Int(key, typedVal)
26		case int8:
27			fields[i] = Int32(key, int32(typedVal))
28		case int16:
29			fields[i] = Int32(key, int32(typedVal))
30		case int32:
31			fields[i] = Int32(key, typedVal)
32		case int64:
33			fields[i] = Int64(key, typedVal)
34		case uint:
35			fields[i] = Uint64(key, uint64(typedVal))
36		case uint64:
37			fields[i] = Uint64(key, typedVal)
38		case uint8:
39			fields[i] = Uint32(key, uint32(typedVal))
40		case uint16:
41			fields[i] = Uint32(key, uint32(typedVal))
42		case uint32:
43			fields[i] = Uint32(key, typedVal)
44		case float32:
45			fields[i] = Float32(key, typedVal)
46		case float64:
47			fields[i] = Float64(key, typedVal)
48		default:
49			// When in doubt, coerce to a string
50			fields[i] = String(key, fmt.Sprint(typedVal))
51		}
52	}
53	return fields, nil
54}
55