diff --git a/reader.go b/reader.go index ae18794..14fc452 100644 --- a/reader.go +++ b/reader.go @@ -3,6 +3,7 @@ package maxminddb import ( "bytes" + "embed" "errors" "fmt" "io" @@ -48,6 +49,23 @@ type Metadata struct { RecordSize uint `maxminddb:"record_size"` } +func OpenWithEmbedFS(f embed.FS, path string) (*Reader, error) { + data, err := f.ReadFile(path) + if err != nil { + return nil, err + } + + reader, err := FromBytes(data) + if err != nil { + _ = munmap(data) + return nil, err + } + + reader.hasMappedFile = true + runtime.SetFinalizer(reader, (*Reader).Close) + return reader, nil +} + // Open takes a string path to a MaxMind DB file and returns a Reader // structure or an error. The database file is opened using a memory map // on supported platforms. On platforms without memory map support, such diff --git a/reader_test.go b/reader_test.go index d6c8cf8..f88ceaa 100644 --- a/reader_test.go +++ b/reader_test.go @@ -1,6 +1,7 @@ package maxminddb import ( + "embed" "errors" "fmt" "math/big" @@ -16,6 +17,9 @@ import ( "github.com/stretchr/testify/require" ) +//go:embed test-data/test-data/* +var f embed.FS + func TestReader(t *testing.T) { for _, recordSize := range []uint{24, 28, 32} { for _, ipVersion := range []uint{4, 6} { @@ -24,7 +28,10 @@ func TestReader(t *testing.T) { ipVersion, recordSize, ) + // log.Printf("Checking %s", fileName) + t.Run(fileName, func(t *testing.T) { + // reader, err := Open(testFile(fileName)) reader, err := Open(testFile(fileName)) require.NoError(t, err, "unexpected error while opening database: %v", err) checkMetadata(t, reader, ipVersion, recordSize) @@ -35,6 +42,18 @@ func TestReader(t *testing.T) { checkIpv6(t, reader) } }) + + t.Run(fileName, func(t *testing.T) { + reader, err := OpenWithEmbedFS(f, testFile(fileName)) + require.NoError(t, err, "unexpected error while opening database: %v", err) + checkMetadata(t, reader, ipVersion, recordSize) + + if ipVersion == 4 { + checkIpv4(t, reader) + } else { + checkIpv6(t, reader) + } + }) } } }