ipnet-trie 0.3.0

IPv4 and IPv6 network fast lookup trie.
Documentation
ipnet-trie
========

IPv4 and IPv6 network fast lookup prefix trie.

[![Rust](https://github.com/bgpkit/ipnet-trie/actions/workflows/rust.yml/badge.svg)](https://github.com/bgpkit/ipnet-trie/actions/workflows/rust.yml)
[![Documentation](https://docs.rs/ipnet-trie/badge.svg)](https://docs.rs/ipnet-trie)
[![Crates.io](https://img.shields.io/crates/v/ipnet-trie.svg)](https://crates.io/crates/ipnet-trie)
[![License](https://img.shields.io/crates/l/ipnet-trie)](https://raw.githubusercontent.com/bgpkit/ipnet-trie/master/LICENSE)

## Description

This crate provides storage and retrieval of IPv4 and IPv6 network prefixes. It uses the [`ipnet`](https://docs.rs/ipnet/latest/ipnet/) crate as the IP network data structure and [`prefix-trie`](https://github.com/tiborschneider/prefix-trie) as the backend, offering fast lookup times and a small memory footprint.

## Features

- Fast prefix lookup for both IPv4 and IPv6 networks
- Efficient storage of IP prefixes and associated data
- Support for exact match and longest prefix match operations
- Ability to iterate over all stored prefixes
- Export and import functionality (with the `export` feature flag)
- Diff operation to compare two tries

## Feature flags

- `export`: Enable export of the trie to bytes or a writer, and import from bytes or a reader.

## Usage

Add this to your `Cargo.toml`:

```toml
[dependencies]
ipnet = "2"
ipnet-trie = "0.2"
```

and then you can use it like this:

```rust
use std::net::{IpAddr, Ipv6Addr};
use ipnet::{IpNet, Ipv6Net};
use ipnet_trie::IpnetTrie;

let mut table = IpnetTrie::new();
let network = IpNet::from(Ipv6Net::new(Ipv6Addr::new(0x2001, 0xdb8, 0xdead, 0xbeef, 0, 0, 0, 0), 64).unwrap());
let ip_address = Ipv6Addr::new(0x2001, 0xdb8, 0xdead, 0xbeef, 0, 0, 0, 0x1);

assert_eq!(table.insert(network, "foo"), None);
// Get value for network from table
assert_eq!(table.longest_match(ip_address), Some((network, &"foo")));
```

### Insertion and Retrieval

```rust
// Insert a network
table.insert(network, value);

// Exact match
let value = table.exact_match(network);

// Longest prefix match
let (matched_network, value) = table.longest_match(&ip_address);
```

### Iteration

```rust
// Iterate over all networks
for (network, value) in table.iter() {
    // ...
}
```

### IP Count

```rust
// Get the total number of unique IPv4 and IPv6 addresses in the trie
let (ipv4_count, ipv6_count) = table.ip_count();
```

### Diff Operation

```rust
// Compare two tries
let (added, removed) = trie1.diff(&trie2);
```

### Export and Import (with `export` feature)

```rust
// Export to bytes
let bytes = table.export_to_bytes();

// Import from bytes
table.import_from_bytes(&bytes);

// Export to writer
table.export_to_writer(&mut writer)?;

// Import from reader
table.import_from_reader(&mut reader)?;
```