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

View File

@ -1,5 +1,5 @@
use std::{str::FromStr, vec};
use ip::IpAddr;
use std::str::FromStr;
pub mod ip;
@ -35,9 +35,10 @@ impl Network {
/// 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_address: 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
///
/// ```
/// 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> {
//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.
///
/// ```
/// let network_class = Network::get_network_class(&[127, 0, 0, 1])?;
/// >>> NetworkClass::A
/// ```ignore
/// use subnet_calculator::Network;
///
/// 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> {
let network_address = network_address.to_arr()?;
@ -123,11 +131,11 @@ impl Network {
#[allow(unused)]
/// Function that takes in a u8 CIDR and converts it to an IP address.
///
/// ```
/// let cidr: u8 = 22
/// let subnet_mask: [u8; 4] = gen_subnet_mask(cidr);
/// ```ignore
/// let cidr: u8 = 22;
/// 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> {
if cidr > 32 {
@ -160,13 +168,16 @@ impl Network {
/// 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 result = match ip_and_cidr_from_string(&ip_string) {
/// Err(_) => panic!(),
/// 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>{
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());
}