1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
//! IP Prefixes types and utilities
//!
mod slot;
mod ipv6trunc;
mod ipstd;
mod cover;
#[cfg(test)] mod tests;
use std::error::Error;
pub use slot::*;
pub use ipv6trunc::*;
pub use ipstd::*;
pub use cover::*;
use std::fmt;
use std::fmt::{Debug, Display};
use std::hash::Hash;
use std::net::{Ipv4Addr, Ipv6Addr};
use std::str::FromStr;
use ipnet::{Ipv4Net, Ipv6Net};
/// Bit prefix
#[allow(clippy::len_without_is_empty)]
pub trait IpPrefix: Debug+Clone+Copy
{
/// The slot manipulated inside this prefix
type Slot: BitSlot;
/// Root prefix has a length of 0
fn root() -> Self; // root prefix, of len =0
/// The inner slot _as is_
///
/// Depending of the implementation, there is no warranty that
/// the masked bits (i.e. with position greater than the length)
/// are set to 0.
///
/// For a version of a slot with masked bits set to 0,
/// see [`Self::bitslot_trunc`].
fn bitslot(&self) -> Self::Slot;
/// The inner slot with all the masked bits set to 0.
///
/// The result always equals `self.bitslot() & self.bitmask()`
/// but it is usually faster to compute (depending on the prefix structure)
fn bitslot_trunc(&self) -> Self::Slot;
/// Length of the prefix.
///
/// This is the number of significant first bits.
/// Others should be considered as 0 (event if not)
fn len(&self) -> u8;
/// Mask of the prefix.
///
/// The n (prefix length) first bits are set to 1 and the last ones are set to 0.
#[inline]
fn bitmask(&self) -> Self::Slot { <Self::Slot as BitSlot>::bitmask(self.len()) }
/// The maximum allowed length for this prefix
const MAX_LEN: u8;
/// The underlying ip address (usually Ipv4Addr or Ipv6Addr)
type Addr: Display+Clone+Copy+Eq+Hash;
/// The address of the network defined by the prefixv
///
/// All the bits greater than the prefix length are set to `0`
fn network(&self) -> Self::Addr;
}
/// Error generated when building an Ip prefix
#[derive(Debug,PartialEq,Eq,Copy, Clone)]
pub enum IpPrefixError {
/// The specified length of the prefix is not valid.
///
/// For Ipv4, this error is generated if the specified length
/// is greater than 32 for an [`Ipv4Prefix`] or [`Ipv4Net`].
///
/// For Ipv6, this error is generated if the specified length
/// is greater than 128 for an [`Ipv6Prefix`] or [`Ipv6Net`]
/// or greater than 120 for an [`Ipv6Prefix120`]
/// or greater than 56 for an [`Ipv6Prefix56`].
PrefixLenError,
/// The parsed string does not contains a valid Ip address.
///
/// It occurs also if when parsing an Ipv4 (resp. Ipv6) address on a string
/// which contains an Ipv6 (resp. Ipv4) syntax.
AddrParseError,
}
impl Display for IpPrefixError
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self {
IpPrefixError::PrefixLenError => {
fmt.write_str("invalid IP prefix length")
}
IpPrefixError::AddrParseError => {
fmt.write_str("invalid IP address syntax")
}
}
}
}
impl Error for IpPrefixError {}
impl From<ipnet::AddrParseError> for IpPrefixError {
fn from(_: ipnet::AddrParseError) -> Self {
IpPrefixError::AddrParseError
}
}
impl From<std::net::AddrParseError> for IpPrefixError {
fn from(_: std::net::AddrParseError) -> Self {
IpPrefixError::AddrParseError
}
}
impl From<ipnet::PrefixLenError> for IpPrefixError {
fn from(_: ipnet::PrefixLenError) -> Self {
IpPrefixError::PrefixLenError
}
}