#[cfg(feature = "graphviz")]
pub mod graphviz;
pub mod map;
mod prefix;
pub mod set;
mod trie;
use ipnet::{IpNet, Ipv4Net, Ipv6Net};
use map::*;
use set::*;
use std::num::NonZeroUsize;
pub use prefix::*;
pub type Ipv4RTrieSet = RTrieSet<Ipv4Prefix>;
pub type Ipv6RTrieSet = RTrieSet<Ipv6Prefix>;
pub type Ipv4LCTrieSet = LCTrieSet<Ipv4Prefix>;
pub type Ipv6LCTrieSet = LCTrieSet<Ipv6Prefix>;
#[derive(Clone, Default)]
pub struct IpRTrieSet {
pub ipv4: Ipv4RTrieSet,
pub ipv6: Ipv6RTrieSet,
}
pub struct IpLCTrieSet {
pub ipv4: Ipv4LCTrieSet,
pub ipv6: Ipv6LCTrieSet,
}
impl IpRTrieSet {
pub fn new() -> Self {
Self {
ipv4: Ipv4RTrieSet::new(),
ipv6: Ipv6RTrieSet::new(),
}
}
pub fn compress(self) -> IpLCTrieSet {
IpLCTrieSet {
ipv4: self.ipv4.compress(),
ipv6: self.ipv6.compress(),
}
}
pub fn shrink_to_fit(&mut self) {
self.ipv4.shrink_to_fit();
self.ipv6.shrink_to_fit();
}
pub fn len(&self) -> NonZeroUsize {
self.ipv4.len().saturating_add(self.ipv6.len().get())
}
pub fn contains(&self, ipnet: &IpNet) -> bool {
match ipnet {
IpNet::V4(net) => self.ipv4.contains(net),
IpNet::V6(net) => self.ipv6.contains(net),
}
}
pub fn get(&self, ipnet: &IpNet) -> Option<IpNet> {
match ipnet {
IpNet::V4(net) => self.ipv4.get(net).map(|ip| (*ip).into()),
IpNet::V6(net) => self.ipv6.get(net).map(|ip| (*ip).into()),
}
}
pub fn lookup(&self, ipnet: &IpNet) -> IpNet {
match ipnet {
IpNet::V4(net) => (*self.ipv4.lookup(net)).into(),
IpNet::V6(net) => (*self.ipv6.lookup(net)).into(),
}
}
pub fn insert(&mut self, ipnet: IpNet) -> bool {
match ipnet {
IpNet::V4(net) => self.ipv4.insert(net.into()),
IpNet::V6(net) => self.ipv6.insert(net.into()),
}
}
pub fn remove(&mut self, ipnet: &IpNet) -> bool {
match ipnet {
IpNet::V4(net) => self.ipv4.remove(net),
IpNet::V6(net) => self.ipv6.remove(net),
}
}
pub fn replace(&mut self, ipnet: IpNet) -> Option<IpNet> {
match ipnet {
IpNet::V4(net) => self.ipv4.replace(net.into()).map(IpNet::from),
IpNet::V6(net) => self.ipv6.replace(net.into()).map(IpNet::from),
}
}
pub fn iter(&self) -> impl Iterator<Item = IpNet> + '_ {
self.ipv4
.iter()
.map(|i| (*i).into())
.chain(self.ipv6.iter().map(|i| (*i).into()))
}
}
impl Extend<Ipv4Net> for IpRTrieSet {
fn extend<I: IntoIterator<Item = Ipv4Net>>(&mut self, iter: I) {
self.ipv4.extend(iter.into_iter().map(|i| i.into()))
}
}
impl Extend<Ipv6Net> for IpRTrieSet {
fn extend<I: IntoIterator<Item = Ipv6Net>>(&mut self, iter: I) {
self.ipv6.extend(iter.into_iter().map(|i| i.into()))
}
}
impl Extend<IpNet> for IpRTrieSet {
fn extend<I: IntoIterator<Item = IpNet>>(&mut self, iter: I) {
iter.into_iter().for_each(|item| {
self.insert(item);
})
}
}
impl FromIterator<IpNet> for IpRTrieSet {
fn from_iter<I: IntoIterator<Item = IpNet>>(iter: I) -> Self {
let mut trieset = Self::default();
trieset.extend(iter);
trieset
}
}
impl FromIterator<Ipv4Net> for IpRTrieSet {
fn from_iter<I: IntoIterator<Item = Ipv4Net>>(iter: I) -> Self {
let mut trieset = Self::default();
trieset.extend(iter);
trieset
}
}
impl FromIterator<Ipv6Net> for IpRTrieSet {
fn from_iter<I: IntoIterator<Item = Ipv6Net>>(iter: I) -> Self {
let mut trieset = Self::default();
trieset.extend(iter);
trieset
}
}
impl IpLCTrieSet {
pub fn len(&self) -> NonZeroUsize {
self.ipv4.len().saturating_add(self.ipv6.len().get())
}
pub fn contains(&self, ipnet: &IpNet) -> bool {
match ipnet {
IpNet::V4(net) => self.ipv4.contains(net),
IpNet::V6(net) => self.ipv6.contains(net),
}
}
pub fn get(&self, ipnet: &IpNet) -> Option<IpNet> {
match ipnet {
IpNet::V4(net) => self.ipv4.get(net).map(|ip| (*ip).into()),
IpNet::V6(net) => self.ipv6.get(net).map(|ip| (*ip).into()),
}
}
pub fn lookup(&self, ipnet: &IpNet) -> IpNet {
match ipnet {
IpNet::V4(net) => (*self.ipv4.lookup(net)).into(),
IpNet::V6(net) => (*self.ipv6.lookup(net)).into(),
}
}
pub fn iter(&self) -> impl Iterator<Item = IpNet> + '_ {
self.ipv4
.iter()
.map(|i| (*i).into())
.chain(self.ipv6.iter().map(|i| (*i).into()))
}
}
impl FromIterator<IpNet> for IpLCTrieSet {
fn from_iter<I: IntoIterator<Item = IpNet>>(iter: I) -> Self {
IpRTrieSet::from_iter(iter).compress()
}
}
pub type Ipv4RTrieMap<V> = RTrieMap<Ipv4Prefix, V>;
pub type Ipv6RTrieMap<V> = RTrieMap<Ipv6Prefix, V>;
pub type Ipv4LCTrieMap<V> = LCTrieMap<Ipv4Prefix, V>;
pub type Ipv6LCTrieMap<V> = LCTrieMap<Ipv6Prefix, V>;
#[derive(Clone, Default)]
pub struct IpRTrieMap<V> {
pub ipv4: Ipv4RTrieMap<V>,
pub ipv6: Ipv6RTrieMap<V>,
}
pub struct IpLCTrieMap<V> {
pub ipv4: Ipv4LCTrieMap<V>,
pub ipv6: Ipv6LCTrieMap<V>,
}
impl<V: Default> IpRTrieMap<V> {
pub fn new() -> Self {
Self {
ipv4: Ipv4RTrieMap::new(),
ipv6: Ipv6RTrieMap::new(),
}
}
}
impl<V> IpRTrieMap<V> {
pub fn with_roots(ipv4: V, ipv6: V) -> Self {
Self {
ipv4: RTrieMap::with_root(ipv4),
ipv6: RTrieMap::with_root(ipv6),
}
}
}
impl<V> IpRTrieMap<V> {
pub fn len(&self) -> NonZeroUsize {
self.ipv4.len().saturating_add(self.ipv6.len().get())
}
pub fn compress(self) -> IpLCTrieMap<V> {
IpLCTrieMap {
ipv4: self.ipv4.compress(),
ipv6: self.ipv6.compress(),
}
}
pub fn shrink_to_fit(&mut self) {
self.ipv4.shrink_to_fit();
self.ipv6.shrink_to_fit();
}
pub fn get(&self, ipnet: &IpNet) -> Option<&V> {
match ipnet {
IpNet::V4(net) => self.ipv4.get(net),
IpNet::V6(net) => self.ipv6.get(net),
}
}
pub fn get_mut(&mut self, ipnet: &IpNet) -> Option<&mut V> {
match ipnet {
IpNet::V4(net) => self.ipv4.get_mut(net),
IpNet::V6(net) => self.ipv6.get_mut(net),
}
}
pub fn lookup(&self, ipnet: &IpNet) -> (IpNet, &V) {
match ipnet {
IpNet::V4(net) => {
let (&k, v) = self.ipv4.lookup(net);
(k.into(), v)
}
IpNet::V6(net) => {
let (&k, v) = self.ipv6.lookup(net);
(k.into(), v)
}
}
}
pub fn lookup_mut(&mut self, ipnet: &IpNet) -> (IpNet, &mut V) {
match ipnet {
IpNet::V4(net) => {
let (&k, v) = self.ipv4.lookup_mut(net);
(k.into(), v)
}
IpNet::V6(net) => {
let (&k, v) = self.ipv6.lookup_mut(net);
(k.into(), v)
}
}
}
pub fn insert(&mut self, ipnet: IpNet, v: V) -> Option<V> {
match ipnet {
IpNet::V4(net) => self.ipv4.insert(net.into(), v),
IpNet::V6(net) => self.ipv6.insert(net.into(), v),
}
}
pub fn remove(&mut self, ipnet: &IpNet) -> Option<V> {
match ipnet {
IpNet::V4(net) => self.ipv4.remove(net),
IpNet::V6(net) => self.ipv6.remove(net),
}
}
pub fn iter(&self) -> impl Iterator<Item = (IpNet, &V)> + '_ {
self.ipv4
.iter()
.map(|(k, v)| ((*k).into(), v))
.chain(self.ipv6.iter().map(|(k, v)| ((*k).into(), v)))
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = (IpNet, &mut V)> + '_ {
self.ipv4
.iter_mut()
.map(|(k, v)| ((*k).into(), v))
.chain(self.ipv6.iter_mut().map(|(k, v)| ((*k).into(), v)))
}
pub fn prefixes(&self) -> IpRTrieSet {
IpRTrieSet {
ipv4: self.ipv4.prefixes(),
ipv6: self.ipv6.prefixes(),
}
}
}
impl<V> Extend<(Ipv4Net, V)> for IpRTrieMap<V> {
fn extend<I: IntoIterator<Item = (Ipv4Net, V)>>(&mut self, iter: I) {
self.ipv4
.extend(iter.into_iter().map(|(i, v)| (i.into(), v)))
}
}
impl<V> Extend<(Ipv6Net, V)> for IpRTrieMap<V> {
fn extend<I: IntoIterator<Item = (Ipv6Net, V)>>(&mut self, iter: I) {
self.ipv6
.extend(iter.into_iter().map(|(i, v)| (i.into(), v)))
}
}
impl<V> Extend<(IpNet, V)> for IpRTrieMap<V> {
fn extend<I: IntoIterator<Item = (IpNet, V)>>(&mut self, iter: I) {
iter.into_iter().for_each(|(k, v)| {
self.insert(k, v);
})
}
}
impl<V: Default> FromIterator<(IpNet, V)> for IpRTrieMap<V> {
fn from_iter<I: IntoIterator<Item = (IpNet, V)>>(iter: I) -> Self {
let mut triemap = Self::default();
triemap.extend(iter);
triemap
}
}
impl<V: Default> FromIterator<(Ipv4Net, V)> for IpRTrieMap<V> {
fn from_iter<I: IntoIterator<Item = (Ipv4Net, V)>>(iter: I) -> Self {
let mut triemap = Self::default();
triemap.extend(iter);
triemap
}
}
impl<V: Default> FromIterator<(Ipv6Net, V)> for IpRTrieMap<V> {
fn from_iter<I: IntoIterator<Item = (Ipv6Net, V)>>(iter: I) -> Self {
let mut triemap = Self::default();
triemap.extend(iter);
triemap
}
}
impl<V> IpLCTrieMap<V> {
pub fn len(&self) -> NonZeroUsize {
self.ipv4.len().saturating_add(self.ipv6.len().get())
}
pub fn get(&self, ipnet: &IpNet) -> Option<&V> {
match ipnet {
IpNet::V4(net) => self.ipv4.get(net),
IpNet::V6(net) => self.ipv6.get(net),
}
}
pub fn get_mut(&mut self, ipnet: &IpNet) -> Option<&mut V> {
match ipnet {
IpNet::V4(net) => self.ipv4.get_mut(net),
IpNet::V6(net) => self.ipv6.get_mut(net),
}
}
pub fn lookup(&self, ipnet: &IpNet) -> (IpNet, &V) {
match ipnet {
IpNet::V4(net) => {
let (&k, v) = self.ipv4.lookup(net);
(k.into(), v)
}
IpNet::V6(net) => {
let (&k, v) = self.ipv6.lookup(net);
(k.into(), v)
}
}
}
pub fn lookup_mut(&mut self, ipnet: &IpNet) -> (IpNet, &mut V) {
match ipnet {
IpNet::V4(net) => {
let (&k, v) = self.ipv4.lookup_mut(net);
(k.into(), v)
}
IpNet::V6(net) => {
let (&k, v) = self.ipv6.lookup_mut(net);
(k.into(), v)
}
}
}
pub fn iter(&self) -> impl Iterator<Item = (IpNet, &V)> + '_ {
self.ipv4
.iter()
.map(|(k, v)| ((*k).into(), v))
.chain(self.ipv6.iter().map(|(k, v)| ((*k).into(), v)))
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = (IpNet, &mut V)> + '_ {
self.ipv4
.iter_mut()
.map(|(k, v)| ((*k).into(), v))
.chain(self.ipv6.iter_mut().map(|(k, v)| ((*k).into(), v)))
}
pub fn prefixes(&self) -> IpLCTrieSet {
IpLCTrieSet {
ipv4: self.ipv4.prefixes(),
ipv6: self.ipv6.prefixes(),
}
}
}
impl<V: Default> FromIterator<(IpNet, V)> for IpLCTrieMap<V> {
fn from_iter<I: IntoIterator<Item = (IpNet, V)>>(iter: I) -> Self {
IpRTrieMap::from_iter(iter).compress()
}
}