Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 39 additions & 19 deletions src/ipv4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,34 +67,50 @@ impl Ipv4Network {
///
/// If the prefix is larger than 32 this will return an `IpNetworkError::InvalidPrefix`.
pub const fn new(addr: Ipv4Addr, prefix: u8) -> Result<Ipv4Network, IpNetworkError> {
if prefix > IPV4_BITS {
Err(IpNetworkError::InvalidPrefix)
} else {
Ok(Ipv4Network { addr, prefix })
match Ipv4Network::new_checked(addr, prefix) {
Some(a) => Ok(a),
None => Err(IpNetworkError::InvalidPrefix),
}
}

/// Constructs without checking prefix a new `Ipv4Network` from any `Ipv4Addr,
/// and a prefix denoting the network size.
/// Constructs a new `Ipv4Network` from any `Ipv4Addr`, and a prefix denoting the network size.
///
/// # Safety
///
/// The caller must ensure that the prefix is less than or equal to 32.
/// If the prefix is larger than 32 this will return `None`. This is useful in const contexts,
/// where [`Option::unwrap`] may be called to trigger a compile-time error in case the prefix
/// is an unexpected value.
///
/// # Examples
///
/// ```
/// use std::net::Ipv4Addr;
/// use ipnetwork::Ipv4Network;
///
/// let prefix = 24;
/// let addr = Ipv4Addr::new(192, 168, 1, 1);
/// const PREFIX: u8 = 24;
/// const ADDR: Ipv4Addr = Ipv4Addr::new(192, 168, 1, 1);
///
/// debug_assert!(prefix <= 32);
/// let network = unsafe { Ipv4Network::new_unchecked(addr, prefix) };
/// // Okay!
/// const NETWORK: Ipv4Network = Ipv4Network::new_checked(ADDR, PREFIX).unwrap();
/// assert_eq!(NETWORK.prefix(), PREFIX);
/// ```
pub const unsafe fn new_unchecked(addr: Ipv4Addr, prefix: u8) -> Ipv4Network {
Ipv4Network { addr, prefix }
///
/// ```should_panic
/// use std::net::Ipv4Addr;
/// use ipnetwork::Ipv4Network;
///
/// // Prefix is greater than 32.
/// const PREFIX: u8 = 32 + 1;
/// const ADDR: Ipv4Addr = Ipv4Addr::new(192, 168, 1, 1);
///
/// // This fails!
/// const NETWORK: Option<Ipv4Network> = Ipv4Network::new_checked(ADDR, PREFIX);
/// assert_eq!(NETWORK.unwrap().prefix(), PREFIX);
/// ```
pub const fn new_checked(addr: Ipv4Addr, prefix: u8) -> Option<Ipv4Network> {
if prefix > IPV4_BITS {
None
} else {
Some(Ipv4Network { addr, prefix })
}
}

/// Constructs a new `Ipv4Network` from a network address and a network mask.
Expand Down Expand Up @@ -396,11 +412,15 @@ mod test {
}

#[test]
fn create_unchecked_v4() {
let cidr = unsafe { Ipv4Network::new_unchecked(Ipv4Addr::new(77, 88, 21, 11), 24) };
fn create_checked_v4() {
let cidr = Ipv4Network::new_checked(Ipv4Addr::new(77, 88, 21, 11), 24).unwrap();
assert_eq!(cidr.prefix(), 24);
let cidr = unsafe { Ipv4Network::new_unchecked(Ipv4Addr::new(0, 0, 0, 0), 33) };
assert_eq!(cidr.prefix(), 33);
}

#[test]
#[should_panic]
fn try_create_invalid_checked_v4() {
Ipv4Network::new_checked(Ipv4Addr::new(0, 0, 0, 0), 33).unwrap();
}

#[test]
Expand Down
59 changes: 39 additions & 20 deletions src/ipv6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,34 +78,50 @@ impl Ipv6Network {
///
/// If the prefix is larger than 128 this will return an `IpNetworkError::InvalidPrefix`.
pub const fn new(addr: Ipv6Addr, prefix: u8) -> Result<Ipv6Network, IpNetworkError> {
if prefix > IPV6_BITS {
Err(IpNetworkError::InvalidPrefix)
} else {
Ok(Ipv6Network { addr, prefix })
match Ipv6Network::new_checked(addr, prefix) {
Some(a) => Ok(a),
None => Err(IpNetworkError::InvalidPrefix),
}
}

/// Constructs without checking prefix a new `Ipv6Network` from any `Ipv6Addr,
/// and a prefix denoting the network size.
/// Constructs a new `Ipv6Network` from any `Ipv6Addr`, and a prefix denoting the network size.
///
/// # Safety
///
/// The caller must ensure that the prefix is less than or equal to 128.
/// If the prefix is larger than 128 this will return `None`. This is useful in const contexts,
/// where [`Option::unwrap`] may be called to trigger a compile-time error in case the prefix
/// is an unexpected value.
///
/// # Examples
///
/// ```
/// use std::net::Ipv6Addr;
/// use ipnetwork::Ipv6Network;
///
/// let prefix = 64;
/// let addr = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0);
/// const PREFIX: u8 = 64;
/// const ADDR: Ipv6Addr = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0);
///
/// debug_assert!(prefix <= 128);
/// let net = unsafe { Ipv6Network::new_unchecked(addr, prefix) };
/// // Okay!
/// const NETWORK: Ipv6Network = Ipv6Network::new_checked(ADDR, PREFIX).unwrap();
/// assert_eq!(NETWORK.prefix(), PREFIX);
/// ```
pub const unsafe fn new_unchecked(addr: Ipv6Addr, prefix: u8) -> Ipv6Network {
Ipv6Network { addr, prefix }
///
/// ```should_panic
/// use std::net::Ipv6Addr;
/// use ipnetwork::Ipv6Network;
///
/// // Prefix is greater than 128.
/// const PREFIX: u8 = 128 + 1;
/// const ADDR: Ipv6Addr = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0);
///
/// // This fails!
/// const NETWORK: Option<Ipv6Network> = Ipv6Network::new_checked(ADDR, PREFIX);
/// assert_eq!(NETWORK.unwrap().prefix(), PREFIX);
/// ```
pub const fn new_checked(addr: Ipv6Addr, prefix: u8) -> Option<Ipv6Network> {
if prefix > IPV6_BITS {
None
} else {
Some(Ipv6Network { addr, prefix })
}
}

/// Constructs a new `Ipv6Network` from a network address and a network mask.
Expand Down Expand Up @@ -427,12 +443,15 @@ mod test {
}

#[test]
fn create_unchecked_v6() {
let cidr = unsafe { Ipv6Network::new_unchecked(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 24) };
fn create_checked_v6() {
let cidr = Ipv6Network::new_checked(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 24).unwrap();
assert_eq!(cidr.prefix(), 24);
let cidr =
unsafe { Ipv6Network::new_unchecked(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 129) };
assert_eq!(cidr.prefix(), 129);
}

#[test]
#[should_panic]
fn try_create_invalid_checked_v6() {
Ipv6Network::new_checked(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 129).unwrap();
}

#[test]
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#![crate_type = "lib"]
#![deny(
missing_debug_implementations,
unsafe_code,
unused_extern_crates,
unused_import_braces
)]
Expand Down
Loading