#4 Adapated code to contain a lib.rs so can be used as library. Have also updated doctests as they were poorly formatted and did not actually test any of the functionality

This commit is contained in:
Luke Else 2023-05-26 14:04:21 +01:00
parent 30344b0605
commit 00735d5691
3 changed files with 50 additions and 57 deletions

View File

@ -9,8 +9,11 @@ pub struct InvalidIPErr;
/// # Example /// # Example
/// ``` /// ```
/// //Loopback Addresses: /// //Loopback Addresses:
/// IpAddr::V4(127, 0, 0, 1) /// use subnet_calculator::ip::IpAddr;
/// IpAddr::V6(String::from("::1")) /// use std::str::FromStr;
///
/// IpAddr::V4(127, 0, 0, 1);
/// IpAddr::V6(String::from("::1"));
/// ``` /// ```
#[allow(unused)] #[allow(unused)]
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
@ -27,10 +30,12 @@ impl IpAddr {
/// Currently only works for IPs of type IPv4 /// Currently only works for IPs of type IPv4
/// # Example /// # Example
/// ``` /// ```
/// use subnet_calculator::ip::IpAddr;
///
/// let ip: IpAddr = IpAddr::V4(127, 0, 0, 1); /// let ip: IpAddr = IpAddr::V4(127, 0, 0, 1);
/// ///
/// let ip_add: [u8; 4] = ip.to_arr(); /// let ip_add: [u8; 4] = ip.to_arr().unwrap();
/// >>> ip_add = [127, 0, 0, 1] /// assert_eq!(ip_add, [127, 0, 0, 1]);
/// ``` /// ```
pub fn to_arr(&self) -> Result<[u8; 4], NetworkingErr> { pub fn to_arr(&self) -> Result<[u8; 4], NetworkingErr> {
match self { match self {
@ -48,10 +53,12 @@ impl IpAddr {
/// Currently only works for IPs of type IPv4 /// Currently only works for IPs of type IPv4
/// # Example /// # Example
/// ``` /// ```
/// use subnet_calculator::ip::IpAddr;
///
/// let ip_add: [u8; 4] = [127, 0, 0, 1]; /// let ip_add: [u8; 4] = [127, 0, 0, 1];
/// ///
/// let ip: IpAddr = IpAddr::V4(127, 0, 0, 1); /// let ip: IpAddr = IpAddr::from_arr(&ip_add).unwrap();
/// >>> ip_add = [127, 0, 0, 1] /// assert_eq!(ip, IpAddr::V4(127, 0, 0, 1));
/// ``` /// ```
pub fn from_arr(arr: &[u8; 4]) -> Result<IpAddr, NetworkingErr> { pub fn from_arr(arr: &[u8; 4]) -> Result<IpAddr, NetworkingErr> {
Ok(IpAddr::V4(arr[0], arr[1], arr[2], arr[3])) Ok(IpAddr::V4(arr[0], arr[1], arr[2], arr[3]))
@ -66,10 +73,12 @@ impl From<IpAddr> for u32 {
/// Currently only works for IPs of type IPv4 /// Currently only works for IPs of type IPv4
/// # Example /// # Example
/// ``` /// ```
/// use subnet_calculator::ip::IpAddr;
///
/// let ip: IpAddr = IpAddr::V4(127, 0, 0, 1); /// let ip: IpAddr = IpAddr::V4(127, 0, 0, 1);
/// ///
/// let ip_u32: u32 = u32::from(ip); /// let ip_u32: u32 = u32::from(ip);
/// >>> ip_u32 = 2130706433; /// assert_eq!(ip_u32, 2130706433);
/// ``` /// ```
fn from(ip: IpAddr) -> Self { fn from(ip: IpAddr) -> Self {
u32::from_be_bytes(ip.to_arr().unwrap()) u32::from_be_bytes(ip.to_arr().unwrap())
@ -84,10 +93,12 @@ impl From<u32> for IpAddr {
/// Currently only works for IPs of type IPv4 /// Currently only works for IPs of type IPv4
/// # Example /// # Example
/// ``` /// ```
/// use subnet_calculator::ip::IpAddr;
///
/// let ip: u32 = 2_130_706_433; /// let ip: u32 = 2_130_706_433;
/// ///
/// let ip_addr: u32 = IpAddr::from(ip); /// let ip_addr: IpAddr = IpAddr::from(ip);
/// >>> ip_addr = IpAddr::V4(127, 0, 0, 1); /// assert_eq!(ip_addr, IpAddr::V4(127, 0, 0, 1));
/// ``` /// ```
fn from(ip: u32) -> Self { fn from(ip: u32) -> Self {
IpAddr::from_arr(&(ip.to_be_bytes() as [u8; 4])).unwrap() IpAddr::from_arr(&(ip.to_be_bytes() as [u8; 4])).unwrap()
@ -112,10 +123,13 @@ impl FromStr for IpAddr {
/// Currently only works for IPs of type IPv4 /// Currently only works for IPs of type IPv4
/// # Example /// # Example
/// ``` /// ```
/// use subnet_calculator::ip::IpAddr;
/// use std::str::FromStr;
///
/// let ip: &str = "127.0.0.1"; /// let ip: &str = "127.0.0.1";
/// ///
/// let parsed_ip: IpAddr = IpAddr::from_str(ip); /// let parsed_ip: IpAddr = IpAddr::from_str(ip).unwrap();
/// ///parsed_ip = IpAddr::V4(127,0,0,1) /// assert_eq!(parsed_ip, IpAddr::V4(127,0,0,1));
/// ``` /// ```
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
let split_ip = s.split('.'); let split_ip = s.split('.');
@ -143,6 +157,8 @@ impl FromStr for IpAddr {
/// ///
/// # Example /// # Example
/// ``` /// ```
/// use subnet_calculator::ip::{IpAddr, print_ip};
///
/// let ip = IpAddr::V4(127, 0, 0, 1); /// let ip = IpAddr::V4(127, 0, 0, 1);
/// ///
/// print_ip(ip); /// print_ip(ip);

View File

@ -1,5 +1,5 @@
use std::{str::FromStr, vec};
use ip::IpAddr; use ip::IpAddr;
use std::str::FromStr;
pub mod ip; pub mod ip;
@ -35,9 +35,10 @@ impl Network {
/// Function that constucts a network struct. /// Function that constucts a network struct.
/// ///
/// ``` /// ```
/// let network = Network::new(&IpAddr::V4(127, 0, 0, 1), 32); /// //Awaiting implementation before creating doctest
/// //let network = Network::new(&IpAddr::V4(127, 0, 0, 1), 32);
/// ``` /// ```
pub fn new(given_address: &IpAddr, subnet_mask: &IpAddr) -> Network { fn new(given_address: &IpAddr, subnet_mask: &IpAddr) -> Network {
Network { Network {
network_address: given_address.clone(), network_address: given_address.clone(),
broadcast_addr: given_address.clone(), broadcast_addr: given_address.clone(),
@ -49,7 +50,12 @@ impl Network {
/// Function that constucts a subnet, returning a vector of all subnets included /// Function that constucts a subnet, returning a vector of all subnets included
/// ///
/// ``` /// ```
/// let networks = Network::create_subnet(&IpAddr::V4(127, 0, 0, 1), 32); /// use subnet_calculator::ip::IpAddr;
/// use subnet_calculator::Network;
///
/// let networks = Network::create_subnet(&IpAddr::V4(127, 0, 0, 1), 16).unwrap();
///
/// assert_eq!(networks.len(), 256);
/// ``` /// ```
pub fn create_subnet(network_address: &IpAddr, cidr: u8) -> Result<Vec<IpAddr>, NetworkingErr> { pub fn create_subnet(network_address: &IpAddr, cidr: u8) -> Result<Vec<IpAddr>, NetworkingErr> {
//Get number of host and network bits. //Get number of host and network bits.
@ -102,9 +108,11 @@ impl Network {
/// Function that is used to determine the class of network that an IP is in. /// Function that is used to determine the class of network that an IP is in.
/// ///
/// ``` /// ```ignore
/// let network_class = Network::get_network_class(&[127, 0, 0, 1])?; /// use subnet_calculator::Network;
/// >>> NetworkClass::A ///
/// let network_class = Network::get_network_class(&[127, 0, 0, 1]).unwrap();
/// assert_eq!(network_class, NetworkClass::A);
/// ``` /// ```
fn get_network_class(network_address: &IpAddr) -> Result<NetworkClass, NetworkingErr> { fn get_network_class(network_address: &IpAddr) -> Result<NetworkClass, NetworkingErr> {
let network_address = network_address.to_arr()?; let network_address = network_address.to_arr()?;
@ -123,11 +131,11 @@ impl Network {
#[allow(unused)] #[allow(unused)]
/// Function that takes in a u8 CIDR and converts it to an IP address. /// Function that takes in a u8 CIDR and converts it to an IP address.
/// ///
/// ``` /// ```ignore
/// let cidr: u8 = 22 /// let cidr: u8 = 22;
/// let subnet_mask: [u8; 4] = gen_subnet_mask(cidr); /// let subnet_mask: [u8; 4] = gen_subnet_mask(cidr).unwrap();
/// ///
/// >> IpAddr::V4(255, 255, 252, 0) /// assert_eq!(subnet_mask, IpAddr::V4(255, 255, 252, 0));
/// ``` /// ```
fn gen_subnet_mask(mut cidr: u8) -> Result<IpAddr, NetworkingErr> { fn gen_subnet_mask(mut cidr: u8) -> Result<IpAddr, NetworkingErr> {
if cidr > 32 { if cidr > 32 {
@ -160,13 +168,16 @@ impl Network {
/// both its Address and CIDR /// both its Address and CIDR
/// ///
/// ``` /// ```
/// use subnet_calculator::ip_and_cidr_from_string;
/// use subnet_calculator::ip::IpAddr;
///
/// let ip_string = String::from("192.168.0.1/24"); /// let ip_string = String::from("192.168.0.1/24");
/// let result = match ip_and_cidr_from_string(&ip_string) { /// let result = match ip_and_cidr_from_string(&ip_string) {
/// Err(_) => panic!(), /// Err(_) => panic!(),
/// Ok(ip_and_cidr) => ip_and_cidr /// Ok(ip_and_cidr) => ip_and_cidr
/// }; /// };
/// ///
/// >> (IpAddr::V4(192, 168, 0, 1), 24) /// assert_eq!(result, (IpAddr::V4(192, 168, 0, 1), 24));
/// ``` /// ```
pub fn ip_and_cidr_from_string(ip_and_cidr: &String) -> Result<(IpAddr, u8), ip::InvalidIPErr>{ pub fn ip_and_cidr_from_string(ip_and_cidr: &String) -> Result<(IpAddr, u8), ip::InvalidIPErr>{
let mut cidr: u8 = Default::default(); let mut cidr: u8 = Default::default();

View File

@ -1,34 +0,0 @@
use std::{io};
use networking::Network;
mod networking;
fn main() {
println!("Enter the IP and cidr for your given network");
let ip_and_cidr: (networking::ip::IpAddr, u8);
loop {
let mut ip_buf = String::new();
io::stdin().read_line(&mut ip_buf).unwrap_or_default();
ip_and_cidr = match networking::ip_and_cidr_from_string(&ip_buf) {
Err(_) => {
println!("{} is an invalid IP Address... Please try again", ip_buf);
continue;
},
Ok(ip_and_cidr) => ip_and_cidr
};
break;
}
let networks = Network::create_subnet(&ip_and_cidr.0, ip_and_cidr.1).unwrap_or_default();
for network in networks.iter() {
networking::ip::print_ip(network.clone());
}
println!("There are {} networks available", networks.len());
}