Skip to content

Commit

Permalink
Add no_std support on nightly
Browse files Browse the repository at this point in the history
  • Loading branch information
domenukk committed May 10, 2023
1 parent 9f75154 commit 94c3bd2
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 30 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ documentation = "https://docs.rs/ipnet"
edition = "2018"

[features]
default = []
default = ["std"]
std = []
# Implements "schemars::JsonSchema". Also implies "serde".
json = ["serde", "schemars"]

Expand Down
61 changes: 46 additions & 15 deletions src/ipext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
//! the `Ipv4Addr` and `Ipv6Addr` types with methods to perform these
//! operations.

use std::cmp::Ordering::{Less, Equal};
use std::iter::{FusedIterator, DoubleEndedIterator};
use std::mem;
use core::cmp::Ordering::{Less, Equal};
use core::iter::{FusedIterator, DoubleEndedIterator};
use core::mem;
#[cfg(not(feature = "std"))]
use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};
#[cfg(feature = "std")]
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};

/// Provides a `saturating_add()` method for `Ipv4Addr` and `Ipv6Addr`.
Expand All @@ -18,6 +21,10 @@ use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
/// # Examples
///
/// ```
/// # #![cfg_attr(not(feature = "std"), feature(ip_in_core))]
/// #[cfg(not(feature = "std"))]
/// # use core::net::{Ipv4Addr, Ipv6Addr};
/// # #[cfg(feature = "std")]
/// use std::net::{Ipv4Addr, Ipv6Addr};
/// use ipnet::IpAdd;
///
Expand Down Expand Up @@ -58,6 +65,10 @@ pub trait IpAdd<RHS = Self> {
/// # Examples
///
/// ```
/// # #![cfg_attr(not(feature = "std"), feature(ip_in_core))]
/// #[cfg(not(feature = "std"))]
/// # use core::net::{Ipv4Addr, Ipv6Addr};
/// # #[cfg(feature = "std")]
/// use std::net::{Ipv4Addr, Ipv6Addr};
/// use ipnet::IpSub;
///
Expand Down Expand Up @@ -89,6 +100,10 @@ pub trait IpSub<RHS = Self> {
/// # Examples
///
/// ```
/// # #![cfg_attr(not(feature = "std"), feature(ip_in_core))]
/// #[cfg(not(feature = "std"))]
/// # use core::net::{Ipv4Addr, Ipv6Addr};
/// # #[cfg(feature = "std")]
/// use std::net::{Ipv4Addr, Ipv6Addr};
/// use ipnet::IpBitAnd;
///
Expand Down Expand Up @@ -116,6 +131,10 @@ pub trait IpBitAnd<RHS = Self> {
/// # Examples
///
/// ```
/// # #![cfg_attr(not(feature = "std"), feature(ip_in_core))]
/// #[cfg(not(feature = "std"))]
/// # use core::net::{Ipv4Addr, Ipv6Addr};
/// # #[cfg(feature = "std")]
/// use std::net::{Ipv4Addr, Ipv6Addr};
/// use ipnet::IpBitOr;
///
Expand Down Expand Up @@ -290,6 +309,10 @@ pub enum IpAddrRange {
/// # Examples
///
/// ```
/// # #![cfg_attr(not(feature = "std"), feature(ip_in_core))]
/// #[cfg(not(feature = "std"))]
/// # use core::net::Ipv4Addr;
/// # #[cfg(feature = "std")]
/// use std::net::Ipv4Addr;
/// use ipnet::Ipv4AddrRange;
///
Expand All @@ -315,7 +338,11 @@ pub struct Ipv4AddrRange {
///
/// # Examples
///
/// ```
/// ```
/// # #![cfg_attr(not(feature = "std"), feature(ip_in_core))]
/// #[cfg(not(feature = "std"))]
/// # use core::net::Ipv6Addr;
/// # #[cfg(feature = "std")]
/// use std::net::Ipv6Addr;
/// use ipnet::Ipv6AddrRange;
///
Expand Down Expand Up @@ -481,12 +508,12 @@ impl Iterator for Ipv4AddrRange {
// so need to explicitly check for overflow.
// 'usize::MAX as u32' is okay here - if usize is 64 bits,
// value truncates to u32::MAX
if count <= std::usize::MAX as u32 {
if count <= core::usize::MAX as u32 {
count as usize + 1
// count overflows usize
} else {
// emulate standard overflow/panic behavior
std::usize::MAX + 2 + count as usize
core::usize::MAX + 2 + count as usize
}
},
Some(Equal) => 1,
Expand Down Expand Up @@ -531,8 +558,8 @@ impl Iterator for Ipv4AddrRange {

fn size_hint(&self) -> (usize, Option<usize>) {
let count = self.count_u64();
if count > std::usize::MAX as u64 {
(std::usize::MAX, None)
if count > core::usize::MAX as u64 {
(core::usize::MAX, None)
} else {
let count = count as usize;
(count, Some(count))
Expand Down Expand Up @@ -561,12 +588,12 @@ impl Iterator for Ipv6AddrRange {
fn count(self) -> usize {
let count = self.count_u128();
// count fits in usize
if count <= std::usize::MAX as u128 {
if count <= core::usize::MAX as u128 {
count as usize
// count does not fit in usize
} else {
// emulate standard overflow/panic behavior
std::usize::MAX + 1 + count as usize
core::usize::MAX + 1 + count as usize
}
}

Expand Down Expand Up @@ -616,14 +643,14 @@ impl Iterator for Ipv6AddrRange {
fn size_hint(&self) -> (usize, Option<usize>) {
if self.can_count_u128() {
let count = self.count_u128();
if count > std::usize::MAX as u128 {
(std::usize::MAX, None)
if count > core::usize::MAX as u128 {
(core::usize::MAX, None)
} else {
let count = count as usize;
(count, Some(count))
}
} else {
(std::usize::MAX, None)
(core::usize::MAX, None)
}
}
}
Expand Down Expand Up @@ -722,8 +749,12 @@ impl FusedIterator for Ipv6AddrRange {}

#[cfg(test)]
mod tests {
use alloc::vec::Vec;
use core::str::FromStr;
#[cfg(not(feature = "std"))]
use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};
#[cfg(feature = "std")]
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::str::FromStr;
use super::*;

#[test]
Expand Down Expand Up @@ -876,7 +907,7 @@ mod tests {
Ipv6Addr::from_str("::").unwrap(),
Ipv6Addr::from_str("8000::").unwrap(),
);
assert_eq!(i.size_hint(), (std::usize::MAX, None));
assert_eq!(i.size_hint(), (core::usize::MAX, None));

// Min, Max, Last
let i = Ipv4AddrRange::new(
Expand Down
34 changes: 23 additions & 11 deletions src/ipnet.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
use std::cmp::{min, max};
use std::cmp::Ordering::{Less, Equal};
use std::convert::From;
use core::cmp::{min, max};
use core::cmp::Ordering::{Less, Equal};
use core::convert::From;
use core::fmt;
use core::iter::FusedIterator;
use core::option::Option::{Some, None};
#[cfg(not(feature = "std"))]
use core::error::Error;
#[cfg(feature = "std")]
use std::error::Error;
use std::fmt;
use std::iter::FusedIterator;
#[cfg(not(feature = "std"))]
use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};
#[cfg(feature = "std")]
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::option::Option::{Some, None};

use alloc::vec::Vec;

use crate::ipext::{IpAdd, IpSub, IpStep, IpAddrRange, Ipv4AddrRange, Ipv6AddrRange};
use crate::mask::{ip_mask_to_prefix, ipv4_mask_to_prefix, ipv6_mask_to_prefix};
Expand Down Expand Up @@ -64,7 +72,11 @@ pub enum IpNet {
/// # Examples
///
/// ```
/// use std::net::Ipv4Addr;
/// # #![cfg_attr(not(feature = "std"), feature(ip_in_core))]
/// # #[cfg(feature = "std")]
/// # use std::net::Ipv6Addr;
/// # #[cfg(not(feature = "std"))]
/// # use core::net::Ipv6Addr;
/// use ipnet::Ipv4Net;
///
/// let net: Ipv4Net = "10.1.1.0/24".parse().unwrap();
Expand Down Expand Up @@ -882,7 +894,7 @@ impl Ipv4Net {
let mut res: Vec<Ipv4Net> = Vec::new();

for (start, mut end) in intervals {
if end != std::u32::MAX {
if end != core::u32::MAX {
end = end.saturating_sub(1)
}
let iter = Ipv4Subnets::new(start.into(), end.into(), 0);
Expand Down Expand Up @@ -1227,7 +1239,7 @@ impl Ipv6Net {
let mut res: Vec<Ipv6Net> = Vec::new();

for (start, mut end) in intervals {
if end != std::u128::MAX {
if end != core::u128::MAX {
end = end.saturating_sub(1)
}
let iter = Ipv6Subnets::new(start.into(), end.into(), 0);
Expand Down Expand Up @@ -1507,7 +1519,7 @@ impl Iterator for IpSubnets {

fn next_ipv4_subnet(start: Ipv4Addr, end: Ipv4Addr, min_prefix_len: u8) -> Ipv4Net {
let range = end.saturating_sub(start).saturating_add(1);
if range == std::u32::MAX && min_prefix_len == 0 {
if range == core::u32::MAX && min_prefix_len == 0 {
Ipv4Net::new(start, min_prefix_len).unwrap()
}
else {
Expand All @@ -1521,7 +1533,7 @@ fn next_ipv4_subnet(start: Ipv4Addr, end: Ipv4Addr, min_prefix_len: u8) -> Ipv4N

fn next_ipv6_subnet(start: Ipv6Addr, end: Ipv6Addr, min_prefix_len: u8) -> Ipv6Net {
let range = end.saturating_sub(start).saturating_add(1);
if range == std::u128::MAX && min_prefix_len == 0 {
if range == core::u128::MAX && min_prefix_len == 0 {
Ipv6Net::new(start, min_prefix_len).unwrap()
}
else {
Expand Down
2 changes: 1 addition & 1 deletion src/ipnet_serde.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{IpNet, Ipv4Net, Ipv6Net};
use std::fmt;
use core::fmt;
use std::net::{Ipv4Addr, Ipv6Addr};
use serde::{self, Serialize, Deserialize, Serializer, Deserializer};
use serde::ser::SerializeTuple;
Expand Down
10 changes: 10 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@
//!
//! [feature]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section

#![no_std]
#![cfg_attr(not(feature = "std"), feature(error_in_core))]
#![cfg_attr(not(feature = "std"), feature(ip_in_core))]

#[cfg(feature = "std")]
extern crate std;

#[cfg_attr(test, macro_use)]
extern crate alloc;

#[cfg(feature = "serde")]
extern crate serde;
#[cfg(feature = "schemars")]
Expand Down
3 changes: 3 additions & 0 deletions src/mask.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::PrefixLenError;
#[cfg(not(feature = "std"))]
use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};
#[cfg(feature = "std")]
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};

/// Converts a `IpAddr` network mask into a prefix.
Expand Down
10 changes: 8 additions & 2 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@
//! is private. It is copied and extended here with methods for parsing
//! IP network addresses.

#[cfg(not(feature = "std"))]
use core::error::Error;
#[cfg(feature = "std")]
use std::error::Error;
use std::fmt;
use core::fmt;
#[cfg(not(feature = "std"))]
use core::net::{Ipv4Addr, Ipv6Addr};
#[cfg(feature = "std")]
use std::net::{Ipv4Addr, Ipv6Addr};
use std::str::FromStr;
use alloc::{str::FromStr, boxed::Box};

use crate::ipnet::{IpNet, Ipv4Net, Ipv6Net};

Expand Down

0 comments on commit 94c3bd2

Please sign in to comment.