#![cfg_attr(feature = "alloc", no_std)]
#![cfg_attr(feature = "alloc", feature(alloc))]
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "alloc")]
use core as std;
use std::marker::PhantomData;
mod tree_bitmap;
use tree_bitmap::TreeBitmap;
pub mod address;
use address::Address;
#[cfg(feature = "alloc")]
pub use address::addr::*;
pub struct IpLookupTable<A, T> {
inner: TreeBitmap<T>,
_addrtype: PhantomData<A>,
}
impl<A, T> IpLookupTable<A, T>
where
A: Address,
{
pub fn new() -> Self {
IpLookupTable {
inner: TreeBitmap::new(),
_addrtype: PhantomData,
}
}
pub fn with_capacity(n: usize) -> Self {
IpLookupTable {
inner: TreeBitmap::with_capacity(n),
_addrtype: PhantomData,
}
}
pub fn mem_usage(&self) -> (usize, usize) {
self.inner.mem_usage()
}
pub fn len(&self) -> usize {
self.inner.len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn insert(&mut self, ip: A, masklen: u32, value: T) -> Option<T> {
self.inner.insert(&ip.nibbles().as_ref(), masklen, value)
}
pub fn remove(&mut self, ip: A, masklen: u32) -> Option<T> {
self.inner.remove(&ip.nibbles().as_ref(), masklen)
}
pub fn exact_match(&self, ip: A, masklen: u32) -> Option<&T> {
self.inner.exact_match(&ip.nibbles().as_ref(), masklen)
}
pub fn longest_match(&self, ip: A) -> Option<(A, u32, &T)> {
match self.inner.longest_match(&ip.nibbles().as_ref()) {
Some((bits_matched, value)) => Some((ip.mask(bits_matched), bits_matched, value)),
None => None,
}
}
pub fn iter(&self) -> Iter<A, T> {
Iter {
inner: self.inner.iter(),
_addrtype: PhantomData,
}
}
pub fn iter_mut(&mut self) -> IterMut<A, T> {
IterMut {
inner: self.inner.iter_mut(),
_addrtype: PhantomData,
}
}
}
impl<A, T> Default for IpLookupTable<A, T>
where
A: Address,
{
fn default() -> Self {
Self::new()
}
}
impl<'a, A, T: 'a> Iterator for Iter<'a, A, T>
where
A: Address,
{
type Item = (A, u32, &'a T);
fn next(&mut self) -> Option<Self::Item> {
match self.inner.next() {
Some((nibbles, masklen, value)) => {
Some((Address::from_nibbles(&nibbles[..]), masklen, value))
}
None => None,
}
}
}
impl<'a, A, T: 'a> Iterator for IterMut<'a, A, T>
where
A: Address,
{
type Item = (A, u32, &'a mut T);
fn next(&mut self) -> Option<Self::Item> {
match self.inner.next() {
Some((nibbles, masklen, value)) => {
Some((Address::from_nibbles(&nibbles[..]), masklen, value))
}
None => None,
}
}
}
impl<'a, A, T: 'a> Iterator for IntoIter<A, T>
where
A: Address,
{
type Item = (A, u32, T);
fn next(&mut self) -> Option<Self::Item> {
match self.inner.next() {
Some((nibbles, masklen, value)) => {
Some((Address::from_nibbles(&nibbles[..]), masklen, value))
}
None => None,
}
}
}
impl<A, T> IntoIterator for IpLookupTable<A, T>
where
A: Address,
{
type Item = (A, u32, T);
type IntoIter = IntoIter<A, T>;
fn into_iter(self) -> IntoIter<A, T> {
IntoIter {
inner: self.inner.into_iter(),
_addrtype: PhantomData,
}
}
}
#[doc(hidden)]
pub struct Iter<'a, A, T: 'a> {
inner: tree_bitmap::Iter<'a, T>,
_addrtype: PhantomData<A>,
}
#[doc(hidden)]
pub struct IterMut<'a, A, T: 'a> {
inner: tree_bitmap::IterMut<'a, T>,
_addrtype: PhantomData<A>,
}
#[doc(hidden)]
pub struct IntoIter<A, T> {
inner: tree_bitmap::IntoIter<T>,
_addrtype: PhantomData<A>,
}