Skip to content

Commit 7fc4929

Browse files
committed
Update UnmarshalMaxMindDB docs
And make them more accurate.
1 parent 6579ca5 commit 7fc4929

File tree

4 files changed

+42
-32
lines changed

4 files changed

+42
-32
lines changed

example_test.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"net/netip"
77

88
"github.com/oschwald/maxminddb-golang/v2"
9+
"github.com/oschwald/maxminddb-golang/v2/mmdbdata"
910
)
1011

1112
// This example shows how to decode to a struct.
@@ -139,16 +140,16 @@ func ExampleReader_NetworksWithin() {
139140
}
140141

141142
// CustomCity represents a simplified city record with custom unmarshaling.
142-
// This demonstrates the Unmarshaler interface for high-performance decoding.
143+
// This demonstrates the Unmarshaler interface for custom decoding.
143144
type CustomCity struct {
144145
Names map[string]string
145146
GeoNameID uint
146147
}
147148

148-
// UnmarshalMaxMindDB implements the maxminddb.Unmarshaler interface.
149-
// This provides significant performance improvements over reflection-based decoding
150-
// by allowing custom, optimized decoding logic for performance-critical applications.
151-
func (c *CustomCity) UnmarshalMaxMindDB(d *maxminddb.Decoder) error {
149+
// UnmarshalMaxMindDB implements the mmdbdata.Unmarshaler interface.
150+
// This provides custom decoding logic, similar to how json.Unmarshaler works
151+
// with encoding/json, allowing fine-grained control over data processing.
152+
func (c *CustomCity) UnmarshalMaxMindDB(d *mmdbdata.Decoder) error {
152153
for key, err := range d.ReadMap() {
153154
if err != nil {
154155
return err
@@ -198,9 +199,9 @@ func (c *CustomCity) UnmarshalMaxMindDB(d *maxminddb.Decoder) error {
198199
return nil
199200
}
200201

201-
// This example demonstrates how to use the Unmarshaler interface for high-performance
202-
// custom decoding. Types implementing Unmarshaler automatically use custom decoding
203-
// logic instead of reflection, providing better performance for critical applications.
202+
// This example demonstrates how to use the Unmarshaler interface for custom decoding.
203+
// Types implementing Unmarshaler automatically use custom decoding logic instead of
204+
// reflection, similar to how json.Unmarshaler works with encoding/json.
204205
func ExampleUnmarshaler() {
205206
db, err := maxminddb.Open("test-data/test-data/GeoIP2-City-Test.mmdb")
206207
if err != nil {
Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
1-
package maxminddb
2-
3-
import "github.com/oschwald/maxminddb-golang/v2/mmdbdata"
4-
5-
// Decoder provides methods for decoding MaxMind DB data values.
6-
// This interface is passed to UnmarshalMaxMindDB methods to allow
7-
// custom decoding logic that avoids reflection for performance-critical applications.
1+
// Package mmdbdata provides low-level types and interfaces for custom MaxMind DB decoding.
82
//
9-
// Types implementing Unmarshaler will automatically use custom decoding logic
10-
// instead of reflection when used with Reader.Lookup, providing better performance
11-
// for performance-critical applications.
3+
// This package allows custom decoding logic for applications that need fine-grained
4+
// control over how MaxMind DB data is processed. For most use cases, the high-level
5+
// maxminddb.Reader API is recommended instead.
6+
//
7+
// # Manual Decoding Example
128
//
13-
// Example:
9+
// Custom types can implement the Unmarshaler interface for custom decoding:
1410
//
1511
// type City struct {
1612
// Names map[string]string `maxminddb:"names"`
1713
// GeoNameID uint `maxminddb:"geoname_id"`
1814
// }
1915
//
20-
// func (c *City) UnmarshalMaxMindDB(d *maxminddb.Decoder) error {
16+
// func (c *City) UnmarshalMaxMindDB(d *mmdbdata.Decoder) error {
2117
// for key, err := range d.ReadMap() {
2218
// if err != nil { return err }
2319
// switch string(key) {
@@ -40,8 +36,18 @@ import "github.com/oschwald/maxminddb-golang/v2/mmdbdata"
4036
// }
4137
// return nil
4238
// }
43-
type Decoder = mmdbdata.Decoder
44-
45-
// Unmarshaler is implemented by types that can unmarshal MaxMind DB data.
46-
// This follows the same pattern as json.Unmarshaler and other Go standard library interfaces.
47-
type Unmarshaler = mmdbdata.Unmarshaler
39+
//
40+
// Types implementing Unmarshaler will automatically use custom decoding logic
41+
// instead of reflection when used with maxminddb.Reader.Lookup, similar to how
42+
// json.Unmarshaler works with encoding/json.
43+
//
44+
// # Direct Decoder Usage
45+
//
46+
// For even more control, you can use the Decoder directly:
47+
//
48+
// decoder := mmdbdata.NewDecoder(buffer, offset)
49+
// value, err := decoder.ReadString()
50+
// if err != nil {
51+
// return err
52+
// }
53+
package mmdbdata

reader.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,22 +55,24 @@
5555
// For maximum performance in high-throughput applications, consider:
5656
//
5757
// 1. Using custom struct types that only include the fields you need
58-
// 2. Implementing the Unmarshaler interface for zero-allocation decoding
58+
// 2. Implementing the Unmarshaler interface for custom decoding
5959
// 3. Reusing the Reader instance across multiple goroutines (it's thread-safe)
6060
//
6161
// # Custom Unmarshaling
6262
//
63-
// For performance-critical applications, you can implement the Unmarshaler
64-
// interface to avoid reflection overhead:
63+
// For custom decoding logic, you can implement the mmdbdata.Unmarshaler interface,
64+
// similar to how encoding/json's json.Unmarshaler works. Types implementing this
65+
// interface will automatically use custom decoding logic when used with Reader.Lookup:
6566
//
6667
// type FastCity struct {
6768
// CountryISO string
6869
// CityName string
6970
// }
7071
//
71-
// func (c *FastCity) UnmarshalMaxMindDB(d *maxminddb.Decoder) error {
72+
// func (c *FastCity) UnmarshalMaxMindDB(d *mmdbdata.Decoder) error {
7273
// // Custom decoding logic using d.ReadMap(), d.ReadString(), etc.
73-
// // See ExampleUnmarshaler for a complete implementation
74+
// // Allows fine-grained control over how MaxMind DB data is decoded
75+
// // See mmdbdata package documentation and ExampleUnmarshaler for complete examples
7476
// }
7577
//
7678
// # Network Iteration

reader_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/stretchr/testify/require"
1717

1818
"github.com/oschwald/maxminddb-golang/v2/internal/mmdberrors"
19+
"github.com/oschwald/maxminddb-golang/v2/mmdbdata"
1920
)
2021

2122
func TestReader(t *testing.T) {
@@ -1061,7 +1062,7 @@ type TestCity struct {
10611062

10621063
// UnmarshalMaxMindDB implements the Unmarshaler interface for TestCity.
10631064
// This demonstrates custom decoding that avoids reflection for better performance.
1064-
func (c *TestCity) UnmarshalMaxMindDB(d *Decoder) error {
1065+
func (c *TestCity) UnmarshalMaxMindDB(d *mmdbdata.Decoder) error {
10651066
for key, err := range d.ReadMap() {
10661067
if err != nil {
10671068
return err
@@ -1105,7 +1106,7 @@ type TestASN struct {
11051106
}
11061107

11071108
// UnmarshalMaxMindDB implements the Unmarshaler interface for TestASN.
1108-
func (a *TestASN) UnmarshalMaxMindDB(d *Decoder) error {
1109+
func (a *TestASN) UnmarshalMaxMindDB(d *mmdbdata.Decoder) error {
11091110
for key, err := range d.ReadMap() {
11101111
if err != nil {
11111112
return err

0 commit comments

Comments
 (0)