pub struct Reader<S: AsRef<[u8]>> {
pub metadata: Metadata,
/* private fields */
}Expand description
A reader for the MaxMind DB format. The lifetime 'data is tied to the
lifetime of the underlying buffer holding the contents of the database file.
The Reader supports both file-based and memory-mapped access to MaxMind
DB files, including GeoIP2 and GeoLite2 databases.
§Features
mmap: Enable memory-mapped file access for better performancesimdutf8: Use SIMD-accelerated UTF-8 validation (faster string decoding)unsafe-str-decode: Skip UTF-8 validation entirely (unsafe, but ~20% faster)
Fields§
§metadata: MetadataDatabase metadata.
Implementations§
Source§impl Reader<Vec<u8>>
impl Reader<Vec<u8>>
Sourcepub fn open_readfile<P: AsRef<Path>>(
database: P,
) -> Result<Reader<Vec<u8>>, MaxMindDbError>
pub fn open_readfile<P: AsRef<Path>>( database: P, ) -> Result<Reader<Vec<u8>>, MaxMindDbError>
Open a MaxMind DB database file by loading it into memory.
§Example
let reader = maxminddb::Reader::open_readfile(
"test-data/test-data/GeoIP2-City-Test.mmdb").unwrap();Source§impl<'de, S: AsRef<[u8]>> Reader<S>
impl<'de, S: AsRef<[u8]>> Reader<S>
Sourcepub fn from_source(buf: S) -> Result<Reader<S>, MaxMindDbError>
pub fn from_source(buf: S) -> Result<Reader<S>, MaxMindDbError>
Sourcepub fn lookup(
&'de self,
address: IpAddr,
) -> Result<LookupResult<'de, S>, MaxMindDbError>
pub fn lookup( &'de self, address: IpAddr, ) -> Result<LookupResult<'de, S>, MaxMindDbError>
Lookup an IP address in the database.
Returns a LookupResult that can be used to:
- Check if data exists with
has_data() - Get the network containing the IP with
network() - Decode the full record with
decode() - Decode a specific path with
decode_path() - Get a low-level decoder with
decoder()
§Examples
Basic city lookup:
let reader = maxminddb::Reader::open_readfile(
"test-data/test-data/GeoIP2-City-Test.mmdb")?;
let ip: IpAddr = "89.160.20.128".parse().unwrap();
let result = reader.lookup(ip)?;
if let Some(city) = result.decode::<geoip2::City>()? {
// Access nested structs directly - no Option unwrapping needed
if let Some(name) = city.city.names.english {
println!("City: {}", name);
}
} else {
println!("No data found for IP {}", ip);
}Selective field access:
let reader = Reader::open_readfile(
"test-data/test-data/GeoIP2-City-Test.mmdb")?;
let ip: IpAddr = "89.160.20.128".parse().unwrap();
let result = reader.lookup(ip)?;
let country_code: Option<String> = result.decode_path(&[
PathElement::Key("country"),
PathElement::Key("iso_code"),
])?;
println!("Country: {:?}", country_code);Sourcepub fn networks(
&'de self,
options: WithinOptions,
) -> Result<Within<'de, S>, MaxMindDbError>
pub fn networks( &'de self, options: WithinOptions, ) -> Result<Within<'de, S>, MaxMindDbError>
Iterate over all networks in the database.
This is a convenience method equivalent to calling within()
with 0.0.0.0/0 for IPv4-only databases or ::/0 for IPv6 databases.
§Arguments
options- Controls which networks are yielded. UseDefault::default()for standard behavior.
§Examples
Iterate over all networks with default options:
use maxminddb::{geoip2, Reader};
let reader = Reader::open_readfile(
"test-data/test-data/GeoIP2-City-Test.mmdb").unwrap();
let mut count = 0;
for result in reader.networks(Default::default()).unwrap() {
let lookup = result.unwrap();
count += 1;
if count >= 10 { break; }
}Sourcepub fn within(
&'de self,
cidr: IpNetwork,
options: WithinOptions,
) -> Result<Within<'de, S>, MaxMindDbError>
pub fn within( &'de self, cidr: IpNetwork, options: WithinOptions, ) -> Result<Within<'de, S>, MaxMindDbError>
Iterate over IP networks within a CIDR range.
Returns an iterator that yields LookupResult for each network in the
database that falls within the specified CIDR range.
§Arguments
cidr- The CIDR range to iterate over.options- Controls which networks are yielded. UseDefault::default()for standard behavior (skip aliases, skip networks without data, include empty values).
§Examples
Iterate over all IPv4 networks:
use ipnetwork::IpNetwork;
use maxminddb::{geoip2, Reader};
let reader = Reader::open_readfile(
"test-data/test-data/GeoIP2-City-Test.mmdb").unwrap();
let ipv4_all = IpNetwork::V4("0.0.0.0/0".parse().unwrap());
let mut count = 0;
for result in reader.within(ipv4_all, Default::default()).unwrap() {
let lookup = result.unwrap();
let network = lookup.network().unwrap();
let city: geoip2::City = lookup.decode().unwrap().unwrap();
let city_name = city.city.names.english;
println!("Network: {}, City: {:?}", network, city_name);
count += 1;
if count >= 10 { break; } // Limit output for example
}Search within a specific subnet:
use ipnetwork::IpNetwork;
use maxminddb::{geoip2, Reader};
let reader = Reader::open_readfile(
"test-data/test-data/GeoIP2-City-Test.mmdb").unwrap();
let subnet = IpNetwork::V4("192.168.0.0/16".parse().unwrap());
for result in reader.within(subnet, Default::default()).unwrap() {
match result {
Ok(lookup) => {
let network = lookup.network().unwrap();
println!("Found: {}", network);
}
Err(e) => eprintln!("Error: {}", e),
}
}Include networks without data:
use ipnetwork::IpNetwork;
use maxminddb::{Reader, WithinOptions};
let reader = Reader::open_readfile(
"test-data/test-data/MaxMind-DB-test-mixed-24.mmdb").unwrap();
let opts = WithinOptions::default().include_networks_without_data();
for result in reader.within("1.0.0.0/8".parse().unwrap(), opts).unwrap() {
let lookup = result.unwrap();
if !lookup.has_data() {
println!("Network {} has no data", lookup.network().unwrap());
}
}Sourcepub fn verify(&self) -> Result<(), MaxMindDbError>
pub fn verify(&self) -> Result<(), MaxMindDbError>
Performs comprehensive validation of the MaxMind DB file.
This method validates:
- Metadata section: format versions, required fields, and value constraints
- Search tree: traverses all networks to verify tree structure integrity
- Data section separator: validates the 16-byte separator between tree and data
- Data section: verifies all data records referenced by the search tree
The verifier is stricter than the MaxMind DB specification and may return errors on some databases that are still readable by normal operations. This method is useful for:
- Validating database files after download or generation
- Debugging database corruption issues
- Ensuring database integrity in critical applications
Note: Verification traverses the entire database and may be slow on large files. The method is thread-safe and can be called on an active Reader.
§Example
use maxminddb::Reader;
let reader = Reader::open_readfile("test-data/test-data/GeoIP2-City-Test.mmdb").unwrap();
reader.verify().expect("Database should be valid");