Skip to main content

Writer

Struct Writer 

Source
pub struct Writer { /* private fields */ }
Expand description

Builds a MaxMind DB and serializes it.

Construct one with Writer::new for the common case, or Writer::builder to set options such as the IpVersion, descriptions, or a fixed RecordSize. Then add data with insert / insert_value and produce bytes with to_bytes or write_to.

use ipnet::IpNet;
use mmdb_writer::{Value, Writer};

let mut writer = Writer::new("Example-DB");
writer.insert_value(
    "192.0.2.0/24".parse::<IpNet>()?,
    Value::map([("hello", Value::from("world"))]),
)?;
let bytes = writer.to_bytes()?;
assert!(!bytes.is_empty());

Implementations§

Source§

impl Writer

Source

pub fn load_from_path(path: impl AsRef<Path>) -> Result<Self, Error>

Load an existing database from a file, ready to be extended.

The returned Writer is seeded with every network in the file and the file’s metadata (database type, languages, descriptions, IP version, record size, and build epoch). Reserved-network and aliasing options are not stored in the format, so they take their defaults.

§Errors

Returns Error::Io if the file cannot be read, or Error::Load if it is not a valid database.

Source

pub fn load(bytes: impl AsRef<[u8]>) -> Result<Self, Error>

Load an existing database from a byte buffer, ready to be extended.

See load_from_path for details.

§Errors

Returns Error::Load if bytes is not a valid database.

Source§

impl Writer

Source

pub fn builder(database_type: impl Into<String>) -> WriterBuilder

Start building a Writer with options.

database_type names the database for readers (conventionally Vendor-Dataset). Every other option has a default, so the terminal build can follow immediately.

use mmdb_writer::{IpVersion, RecordSize, Writer};

let writer = Writer::builder("Example-DB")
    .ip_version(IpVersion::V4)
    .record_size(RecordSize::Bits32)
    .languages(["en", "de"])
    .build();
Source§

impl Writer

Source

pub fn new(database_type: impl Into<String>) -> Self

Create a Writer with all default options and the given database type.

Source

pub fn insert<N: Into<IpNet>, T: Serialize + ?Sized>( &mut self, network: N, value: &T, ) -> Result<(), Error>

Insert any Serialize value at every address in network.

The value is projected onto the MMDB type system: structs and maps become MMDB maps, sequences become arrays, Option::None and unit values are dropped, and enums are serialized in serde’s externally tagged form. Later inserts win, as with insert_value.

§Errors

Returns Error::UnsupportedValue if the value uses a type MMDB cannot represent (such as i64), Error::Serialize if serialization fails, or Error::Ipv6InIpv4Tree for an IPv6 network in an IPv4 database.

use ipnet::IpNet;
use mmdb_writer::Writer;
use serde::Serialize;

#[derive(Serialize)]
struct Asn { autonomous_system_number: u32, autonomous_system_organization: String }

let mut writer = Writer::new("ASN-DB");
writer.insert(
    "192.0.2.0/24".parse::<IpNet>()?,
    &Asn { autonomous_system_number: 64_512, autonomous_system_organization: "Example".into() },
)?;
Source

pub fn insert_value<N: Into<IpNet>>( &mut self, network: N, value: Value, ) -> Result<(), Error>

Insert a Value at every address in network.

Later inserts win: a more-specific network inserted afterward overrides the covered addresses, and a less-specific one overwrites everything it covers. Host bits in network are ignored.

§Errors

Returns Error::Ipv6InIpv4Tree if network is IPv6 but the database is IpVersion::V4.

Source

pub fn insert_with<N, F>(&mut self, network: N, op: F) -> Result<(), Error>
where N: Into<IpNet>, F: FnMut(Option<&Value>) -> Option<Value>,

Insert into network by computing each covered leaf’s new value from its current one.

The operation receives the value currently covering a leaf (None where there is none) and returns the value to store, or None to clear it. Because a network can cover many existing leaves, the operation may be called more than once per insert — once per distinct value it paints over. This mirrors the Go writer’s InsertFunc.

use ipnet::IpNet;
use mmdb_writer::{Value, Writer};

let mut w = Writer::new("Counter");
let mut bump = |net: &str| {
    w.insert_with(net.parse::<IpNet>().unwrap(), |existing| {
        let n = match existing {
            Some(Value::U32(n)) => *n + 1,
            _ => 1,
        };
        Some(Value::from(n))
    })
    .unwrap();
};
bump("192.0.2.0/24");
bump("192.0.2.0/25"); // overlaps: sees the existing 1, stores 2
§Errors

Returns Error::Ipv6InIpv4Tree for an IPv6 network in an IPv4 database.

Source

pub fn insert_value_merged<N: Into<IpNet>>( &mut self, network: N, value: Value, strategy: MergeStrategy, ) -> Result<(), Error>

Insert a Value into network, combining it with any existing value per strategy.

With MergeStrategy::Replace this is insert_value; the other strategies merge maps (and, for DeepMerge, nested maps and arrays) rather than overwriting.

§Errors

Returns Error::Ipv6InIpv4Tree for an IPv6 network in an IPv4 database.

Source

pub fn insert_merged<N: Into<IpNet>, T: Serialize + ?Sized>( &mut self, network: N, value: &T, strategy: MergeStrategy, ) -> Result<(), Error>

Insert any Serialize value into network, merging per strategy.

The serde equivalent of insert_value_merged.

§Errors

As insert plus insert_value_merged.

Source

pub fn insert_range( &mut self, start: IpAddr, end: IpAddr, value: &Value, ) -> Result<(), Error>

Insert a Value at every address in the inclusive range [start, end].

The range is decomposed into the minimal set of CIDR networks and each is inserted (with insert_value semantics). Useful for data sources that express coverage as start–end pairs rather than CIDRs.

§Errors

Returns Error::InvalidRange if start and end are different IP families or start is above end, or Error::Ipv6InIpv4Tree for an IPv6 range in an IPv4 database.

Source

pub fn get(&self, ip: IpAddr) -> Option<&Value>

Look up the value currently covering ip, if any.

Reflects the most-specific matching insert, including the effect of merges and removals. Handy for tests and debugging. IPv4 aliases are not consulted (they are installed only at serialization time), so query IPv4 addresses directly.

Source

pub fn to_bytes(&self) -> Result<Vec<u8>, Error>

Serialize the database to a byte vector.

This does not consume the writer, so more data can be inserted afterward and the database re-serialized.

§Errors

Returns Error::TreeTooLarge if the tree and data section exceed what the chosen RecordSize can address.

Source

pub fn write_to<W: Write>(&self, writer: W) -> Result<(), Error>

Serialize the database, writing it to writer.

§Errors

Returns Error::TreeTooLarge as to_bytes does, or Error::Io if writing fails.

Trait Implementations§

Source§

impl Debug for Writer

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.