git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/mmdb/deserializer_test.go (about) 1 package mmdb 2 3 import ( 4 "math/big" 5 "net" 6 "testing" 7 8 "github.com/stretchr/testify/require" 9 ) 10 11 func TestDecodingToDeserializer(t *testing.T) { 12 reader, err := Open(testFile("MaxMind-DB-test-decoder.mmdb")) 13 require.NoError(t, err, "unexpected error while opening database: %v", err) 14 15 dser := testDeserializer{} 16 err = reader.Lookup(net.ParseIP("::1.1.1.0"), &dser) 17 require.NoError(t, err, "unexpected error while doing lookup: %v", err) 18 19 checkDecodingToInterface(t, dser.rv) 20 } 21 22 type stackValue struct { 23 value any 24 curNum int 25 } 26 27 type testDeserializer struct { 28 stack []*stackValue 29 rv any 30 key *string 31 } 32 33 func (*testDeserializer) ShouldSkip(_ uintptr) (bool, error) { 34 return false, nil 35 } 36 37 func (d *testDeserializer) StartSlice(size uint) error { 38 return d.add(make([]any, size)) 39 } 40 41 func (d *testDeserializer) StartMap(_ uint) error { 42 return d.add(map[string]any{}) 43 } 44 45 //nolint:unparam // This is to meet the requirements of the interface. 46 func (d *testDeserializer) End() error { 47 d.stack = d.stack[:len(d.stack)-1] 48 return nil 49 } 50 51 func (d *testDeserializer) String(v string) error { 52 return d.add(v) 53 } 54 55 func (d *testDeserializer) Float64(v float64) error { 56 return d.add(v) 57 } 58 59 func (d *testDeserializer) Bytes(v []byte) error { 60 return d.add(v) 61 } 62 63 func (d *testDeserializer) Uint16(v uint16) error { 64 return d.add(uint64(v)) 65 } 66 67 func (d *testDeserializer) Uint32(v uint32) error { 68 return d.add(uint64(v)) 69 } 70 71 func (d *testDeserializer) Int32(v int32) error { 72 return d.add(int(v)) 73 } 74 75 func (d *testDeserializer) Uint64(v uint64) error { 76 return d.add(v) 77 } 78 79 func (d *testDeserializer) Uint128(v *big.Int) error { 80 return d.add(v) 81 } 82 83 func (d *testDeserializer) Bool(v bool) error { 84 return d.add(v) 85 } 86 87 func (d *testDeserializer) Float32(v float32) error { 88 return d.add(v) 89 } 90 91 func (d *testDeserializer) add(v any) error { 92 if len(d.stack) == 0 { 93 d.rv = v 94 } else { 95 top := d.stack[len(d.stack)-1] 96 switch parent := top.value.(type) { 97 case map[string]any: 98 if d.key == nil { 99 key := v.(string) 100 d.key = &key 101 } else { 102 parent[*d.key] = v 103 d.key = nil 104 } 105 106 case []any: 107 parent[top.curNum] = v 108 top.curNum++ 109 default: 110 } 111 } 112 113 switch v := v.(type) { 114 case map[string]any, []any: 115 d.stack = append(d.stack, &stackValue{value: v}) 116 default: 117 } 118 119 return nil 120 }