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  }