initial commit
This commit is contained in:
		
						commit
						24616479be
					
				
							
								
								
									
										8
									
								
								Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| [package] | ||||
| name = "ipcalc" | ||||
| version = "0.1.0" | ||||
| edition = "2021" | ||||
| 
 | ||||
| # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||||
| 
 | ||||
| [dependencies] | ||||
							
								
								
									
										93
									
								
								src/ip.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								src/ip.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,93 @@ | ||||
| use std::fmt::{self,Display}; // needed to implement Display for Ip
 | ||||
| use std::convert::From; // needed to implement u32::from(&ip)
 | ||||
| 
 | ||||
| // Debug needed for {:?} format
 | ||||
| // PartialEq and Eq allows comparisons (usefull for unit tests)
 | ||||
| #[derive(Debug,PartialEq,Eq)] 
 | ||||
| pub enum Ip { | ||||
|     V4([u8 ; 4]), | ||||
|     // V6([u16 ; 8]) // not implemented yet...
 | ||||
| } | ||||
| 
 | ||||
| // implement methods on the Ip type
 | ||||
| // 'new' and 'from_str' are arbitrary and could be named differently
 | ||||
| impl Ip { | ||||
|     pub fn new(a: u8, b: u8, c: u8, d: u8) -> Self { | ||||
|         Ip::V4([a, b, c, d]) | ||||
|     } | ||||
|     
 | ||||
|     pub fn from_str(s: &str) -> Option<Self> { | ||||
|         let tbl : Vec<u8> = s.split('.') | ||||
|             .filter_map(|s| s.parse().ok()) | ||||
|             .collect(); | ||||
|         Some(Ip::V4(tbl.try_into().ok()?)) | ||||
|     } | ||||
|     
 | ||||
|     // totaly useless but an example of an object method :)
 | ||||
|     pub fn is_even(&self) -> bool { | ||||
|         let Ip::V4([_,_,_,n]) = self; | ||||
|         n % 2 == 0 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // allows conversion from ip to u32 with this syntax:
 | ||||
| // `let nbr = u32::from(&ip);`
 | ||||
| // use the std::convert::From trait
 | ||||
| impl From<&Ip> for u32 { | ||||
|     fn from(src: &Ip) -> u32 { | ||||
|         let mut ip : u32 = 0; | ||||
|         let Ip::V4(array) = src; | ||||
|         for (idx, n) in array.iter().enumerate() { | ||||
|             ip += (*n as u32) << (8 * (3 - idx)); | ||||
|         } | ||||
|         ip | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Display is a standard trait used by format! and println! and others
 | ||||
| // to display objects...
 | ||||
| impl Display for Ip { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||
|         match self { | ||||
|             Ip::V4(arr) => write!(f, "{}.{}.{}.{}", | ||||
|                                   arr[0], arr[1], arr[2], arr[3]), | ||||
|             /* | ||||
|             Ip::V6(arr) => write!(f, | ||||
|                                   "{:x}:{:x}:{:x}:{:x}:{:x}:{:x}:{:x}:{:x}", | ||||
|                                   arr[0], arr[1], arr[2], arr[3], | ||||
|                                   arr[4], arr[5], arr[6], arr[7]) | ||||
|              */ | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Some unit tests, run with:
 | ||||
| // `$ cargo test`
 | ||||
| #[test] | ||||
| fn test_ip_new() { | ||||
|     let ip = Ip::new(127, 0, 0, 1); | ||||
|     assert_eq!(ip, Ip::V4([127, 0, 0, 1])); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_ip_from_str() { | ||||
|     let ip1 = Ip::from_str("127.0.0.1"); | ||||
|     assert_eq!(ip1, Some(Ip::V4([127, 0, 0, 1]))); | ||||
| 
 | ||||
|     let ip2 = Ip::from_str("512.0.0.1"); | ||||
|     assert_eq!(ip2, None); | ||||
|     
 | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_ip_is_even() { | ||||
|     assert_eq!(Ip::new(127, 0, 0, 1).is_even(), false); | ||||
|     assert_eq!(Ip::new(192, 168, 0, 2).is_even(), true); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn test_u32_from_ip() { | ||||
|     let ip = Ip::new(127, 0, 0, 1); | ||||
|     let nbr = u32::from(&ip); | ||||
|     assert_eq!(nbr, 0x7f000001); | ||||
| } | ||||
							
								
								
									
										30
									
								
								src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/main.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
| mod ip; // declare that there is a ip.rs module needed by this project
 | ||||
| 
 | ||||
| use ip::Ip; // import the Ip type from the ip module
 | ||||
| 
 | ||||
| fn main() { | ||||
|     let Some(arg) = std::env::args().nth(1) else { | ||||
|         println!("we need one argument."); | ||||
|         return; | ||||
|     }; | ||||
| 
 | ||||
|     let Some(ip) = Ip::from_str(&arg) else { | ||||
|         println!("'{}' is is not a valid ipv4 address.", arg); | ||||
|         return; | ||||
|     }; | ||||
|     
 | ||||
|     let nbr = u32::from(&ip); | ||||
|     
 | ||||
|     println!("Canonical: {}", ip);    
 | ||||
|     println!("Debug....: {:?}", ip); | ||||
|     println!("Binary...: {:b}", nbr); | ||||
|     println!("Hexa.....: 0x{:x}", nbr); | ||||
| 
 | ||||
|     let comment = match ip { | ||||
|         Ip::V4([127, 0, 0, 1]) => "This is you.", | ||||
|         Ip::V4([192,168,_,_]) => "This is a local area network", | ||||
|         Ip::V4([10,_,_,_]) => "This is a big local area network", | ||||
|         _ => "Nothing special to say about this address" | ||||
|     }; | ||||
|     println!("{}", comment); | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user