Merge pull request 'Adding current working progress to hashmap for dynamic routes.' (#3) from bflip-1 into main
Reviewed
This commit is contained in:
		
						commit
						ad5f96c45c
					
				| @ -6,4 +6,5 @@ edition = "2021" | ||||
| [dependencies] | ||||
| base64 = "0.22.1" | ||||
| rand = "0.8" | ||||
| regex = "1.11.1" | ||||
| sqlite = "0.36.1" | ||||
|  | ||||
| @ -1,15 +0,0 @@ | ||||
| <!Doctype html> | ||||
| <html> | ||||
|   <head> | ||||
|     <title>Page Not Found</title> | ||||
|     <style> | ||||
|       body { | ||||
|         background: orange; | ||||
|       } | ||||
|     </style> | ||||
|   </head> | ||||
|   <body> | ||||
|     <h1>Page cannot be found</h1> | ||||
|     <h3>Sorry, this page cannot be found.</h3> | ||||
|   </body> | ||||
| </html> | ||||
| @ -1,2 +1 @@ | ||||
| alert("time to rock"); | ||||
| console.log("hello"); | ||||
| console.log("main.js loaded"); | ||||
|  | ||||
| @ -1,3 +1,19 @@ | ||||
| @import url("https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap"); | ||||
| @import url("https://fonts.googleapis.com/css2?family=Anton&family=Bebas+Neue&display=swap"); | ||||
| :root { | ||||
|   --blue: #002D62; | ||||
|   --red: #C8102E; | ||||
|   --green: #4CAF50; | ||||
|   --background: #F5F5F5; | ||||
|   --primary-text: #1A1A1A; | ||||
|   --secondary-text: #555555; | ||||
|   --success: #2E8B57; | ||||
|   --warning: #FFA500; | ||||
|   --error: #D72638; | ||||
|   --primary-font: "Bebas Neue", sans-serif; | ||||
|   --secondary-font: "Anton", sans-serif; | ||||
| } | ||||
| 
 | ||||
| /* 1. Use a more-intuitive box-sizing model */ | ||||
| *, *::before, *::after { | ||||
|   box-sizing: border-box; | ||||
| @ -53,8 +69,95 @@ h1, h2, h3, h4, h5, h6 { | ||||
|   isolation: isolate; | ||||
| } | ||||
| 
 | ||||
| header { | ||||
|   background: var(--blue); | ||||
|   padding: 20px; | ||||
| } | ||||
| header #site-name { | ||||
|   font-family: var(--secondary-font); | ||||
|   font-size: 2rem; | ||||
|   letter-spacing: 1px; | ||||
| } | ||||
| header a { | ||||
|   color: var(--background); | ||||
| } | ||||
| 
 | ||||
| h1, h2, h3, h4, h5, h6 { | ||||
|   font-family: var(--primary-font); | ||||
| } | ||||
| 
 | ||||
| h1 { | ||||
|   font-size: 3rem; | ||||
|   font-weight: 700; | ||||
| } | ||||
| 
 | ||||
| h2 { | ||||
|   font-size: 2.5rem; | ||||
|   font-weight: 700; | ||||
| } | ||||
| 
 | ||||
| h3 { | ||||
|   font-size: 2rem; | ||||
|   font-weight: 500; | ||||
| } | ||||
| 
 | ||||
| h4 { | ||||
|   font-size: 1.5rem; | ||||
|   font-weight: 500; | ||||
| } | ||||
| 
 | ||||
| h5 { | ||||
|   font-size: 1.2rem; | ||||
|   font-weight: 500; | ||||
| } | ||||
| 
 | ||||
| h6 { | ||||
|   font-size: 1rem; | ||||
|   font-weight: 500; | ||||
| } | ||||
| 
 | ||||
| .styled-table { | ||||
|   border-collapse: collapse; | ||||
|   margin: 25px 0; | ||||
|   font-size: 0.9em; | ||||
|   font-family: sans-serif; | ||||
|   min-width: 400px; | ||||
|   box-shadow: 0 0 20px rgba(0, 0, 0, 0.15); | ||||
| } | ||||
| 
 | ||||
| .styled-table thead tr { | ||||
|   background-color: #009879; | ||||
|   color: #ffffff; | ||||
|   text-align: left; | ||||
| } | ||||
| 
 | ||||
| .styled-table th, | ||||
| .styled-table td { | ||||
|   padding: 12px 15px; | ||||
| } | ||||
| 
 | ||||
| .styled-table tbody tr { | ||||
|   border-bottom: 1px solid #dddddd; | ||||
| } | ||||
| 
 | ||||
| .styled-table tbody tr:nth-of-type(even) { | ||||
|   background-color: #f3f3f3; | ||||
| } | ||||
| 
 | ||||
| .styled-table tbody tr:last-of-type { | ||||
|   border-bottom: 2px solid #009879; | ||||
| } | ||||
| 
 | ||||
| .styled-table tbody tr.active-row { | ||||
|   font-weight: bold; | ||||
|   color: #009879; | ||||
| } | ||||
| 
 | ||||
| body { | ||||
|   background: orange; | ||||
|   background: var(--background); | ||||
|   color: var(--primary-text); | ||||
|   padding: 20px; | ||||
|   font-size: 1.2rem; | ||||
| } | ||||
| 
 | ||||
| img { | ||||
|  | ||||
| @ -1 +1 @@ | ||||
| {"version":3,"sourceRoot":"","sources":["../../theme/reset.scss","../../theme/styles.scss"],"names":[],"mappings":"AAAA;AACA;EACE;;;AAGF;AACA;EACE;;;AAGF;AACA;EACE;IACE;;;AAIJ;AACE;EACA;AACA;EACA;;;AAGF;AACA;EACE;EACA;;;AAGF;AACA;EACE;;;AAGF;AACA;EACE;;;AAGF;AACA;EACE;;;AAEF;EACE;;;AAGF;AAAA;AAAA;AAGA;EACE;;;AClDF;EACE;;;AAGF;EACE;EACA","file":"style.css"} | ||||
| {"version":3,"sourceRoot":"","sources":["../../theme/styles.scss","../../theme/variables.scss","../../theme/reset.scss","../../theme/header.scss","../../theme/headings.scss","../../theme/tables.scss"],"names":[],"mappings":"AAAQ;AACA;ACAR;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ACZF;AACA;EACE;;;AAGF;AACA;EACE;;;AAGF;AACA;EACE;IACE;;;AAIJ;AACE;EACA;AACA;EACA;;;AAGF;AACA;EACE;EACA;;;AAGF;AACA;EACE;;;AAGF;AACA;EACE;;;AAGF;AACA;EACE;;;AAEF;EACE;;;AAGF;AAAA;AAAA;AAGA;EACE;;;ACpDF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;;;ACXJ;EACE;;;AAGF;EACE;EACA;;;AAIF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAIF;EACE;EACA;;;AAIF;EACE;EACA;;;AClCF;EACI;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;;;AAGJ;AAAA;EAEI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;EACA;;;AL1BJ;EACE;EACA;EACA;EACA;;;AAKF;EACE;EACA","file":"style.css"} | ||||
							
								
								
									
										5
									
								
								public/components/header.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								public/components/header.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| <meta charset="UTF-8" /> | ||||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||
| <link rel="stylesheet" href="./assets/style.css" /> | ||||
| <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script> | ||||
| <script src="./assets/main.js"></script> | ||||
							
								
								
									
										
											BIN
										
									
								
								public/images/fenway.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/images/fenway.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 594 KiB | 
| @ -1,12 +0,0 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|   <head> | ||||
|     <title>Toolshed</title> | ||||
|     <link rel="stylesheet" href="/assets/style.css" /> | ||||
|     <script src="/assets/main.js"></script> | ||||
|   </head> | ||||
|   <body> | ||||
|     <h1>This is my toolshed. This web server is built using Rust :)</h1> | ||||
|     <img src="/images/6.jpg" alt="some image" /> | ||||
|   </body> | ||||
| </html> | ||||
							
								
								
									
										32
									
								
								public/pages/404.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								public/pages/404.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | ||||
| <!Doctype html> | ||||
| <html> | ||||
|   <head> | ||||
|     <title>Page Not Found</title> | ||||
|     <link rel="stylesheet" href="./assets/style.css" /> | ||||
|     <meta charset="UTF-8" /> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||
|     <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script> | ||||
|     <script src="./assets/main.js"></script> | ||||
|   </head> | ||||
|   <body> | ||||
|     <header id="site-header"> | ||||
|       <div id="site-name"> | ||||
|         <a href="/">BatFlip</a> | ||||
|       </div> | ||||
|       <div id="site-menu"> | ||||
|         <ul> | ||||
|           <li><a href="/scorecards">Past Scorecards</a></li> | ||||
|           <li><a href="/add-scorecard">Add New</a></li> | ||||
|         </ul> | ||||
|       </div> | ||||
|     </header> | ||||
|     <div id="main-content"> | ||||
|       <h1>Sorry, this page cannot be found.</h1> | ||||
|       <h2>Sorry, this page cannot be found.</h2> | ||||
|       <h3>Sorry, this page cannot be found.</h3> | ||||
|       <h4>Sorry, this page cannot be found.</h4> | ||||
|       <h5>Sorry, this page cannot be found.</h5> | ||||
|       <h6>Sorry, this page cannot be found.</h6> | ||||
|     </div> | ||||
|   </body> | ||||
| </html> | ||||
| @ -1,9 +0,0 @@ | ||||
| <!DOCTYPE HTML> | ||||
| <html> | ||||
|   <head> | ||||
|     <title>About</title> | ||||
|   </head> | ||||
|   <body> | ||||
|     <h1>This is the about page!</h1> | ||||
|   </body> | ||||
| </html> | ||||
							
								
								
									
										38
									
								
								public/pages/add-scorecard.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								public/pages/add-scorecard.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|   <head> | ||||
|     <title>Add New Scorecard</title> | ||||
|     {% header %} | ||||
|   </head> | ||||
|   <body> | ||||
|     <header id="site-header"> | ||||
|       <div id="site-name"> | ||||
|         <a href="/">BatFlip</a> | ||||
|       </div> | ||||
|       <div id="site-menu"> | ||||
|         <ul> | ||||
|           <li><a href="/scorecards">Past Scorecards</a></li> | ||||
|         </ul> | ||||
|       </div> | ||||
|     </header> | ||||
|     <div id="main-content"> | ||||
|       <table id="home-scorecard" class="styled-table"> | ||||
|         <thead> | ||||
|           <tr> | ||||
|             <th>Name</th> | ||||
|             <th>Date</th> | ||||
|             <th>Score</th> | ||||
|             <th>Actions</th> | ||||
|           </tr> | ||||
|         </thead | ||||
|         <tbody> | ||||
|           <tr> | ||||
|             <td><input type="text" name="name" placeholder="Name" /></td> | ||||
|             <td><input type="text" name="date" placeholder="Date" /></td> | ||||
|             <td><input type="text" name="score" placeholder="Score" /></td> | ||||
|             <td><input type="submit" value="Add" /></td> | ||||
|         </tbody> | ||||
|       </table> | ||||
|     </div> | ||||
|   </body> | ||||
| </html> | ||||
							
								
								
									
										24
									
								
								public/pages/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								public/pages/index.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|   <head> | ||||
|     <title>BatFlip Scoring App</title> | ||||
|     {% header %} | ||||
|   </head> | ||||
|   <body> | ||||
|     <header id="site-header"> | ||||
|       <div id="site-name"> | ||||
|         <a href="/">BatFlip</a> | ||||
|       </div> | ||||
|       <div id="site-menu"> | ||||
|         <ul> | ||||
|           <li><a href="/scorecards">Past Scorecards</a></li> | ||||
|           <li><a href="/add-scorecard">Add New</a></li> | ||||
|         </ul> | ||||
|       </div> | ||||
|     </header> | ||||
|     <div id="main-content"> | ||||
|       <h1>Live Baseball Scoring App, written in Rust</h1> | ||||
|       <img src="./images/fenway.jpg" alt="some image" /> | ||||
|     </div> | ||||
|   </body> | ||||
| </html> | ||||
							
								
								
									
										22
									
								
								public/pages/scorecards.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								public/pages/scorecards.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|   <head> | ||||
|     <title>Scorecards</title> | ||||
|     {% header %} | ||||
|   </head> | ||||
|   <body> | ||||
|     <header id="site-header"> | ||||
|       <div id="site-name"> | ||||
|         <a href="/">BatFlip</a> | ||||
|       </div> | ||||
|       <div id="site-menu"> | ||||
|         <ul> | ||||
|           <li><a href="/add-scorecard">Add New</a></li> | ||||
|         </ul> | ||||
|       </div> | ||||
|     </header> | ||||
|     <div id="main-content"> | ||||
|       <h1>Scorecards Go Here.</h1> | ||||
|     </div> | ||||
|   </body> | ||||
| </html> | ||||
| @ -3,8 +3,7 @@ use std::{ | ||||
|     io::{prelude::*, BufReader}, | ||||
|     net::TcpStream, | ||||
| }; | ||||
| 
 | ||||
| use crate::router; | ||||
| use batflip::*; | ||||
| 
 | ||||
| #[allow(dead_code)] | ||||
| struct IncomingRequest { | ||||
| @ -13,7 +12,7 @@ struct IncomingRequest { | ||||
|     // headers: Vec<String>
 | ||||
| } | ||||
| 
 | ||||
| #[allow(unused_assignments)] | ||||
| // Handle the incoming connection.
 | ||||
| pub fn handle_connection(mut stream: TcpStream) { | ||||
|     // Create a new buffer reader with the stream data.
 | ||||
|     let buf_reader = BufReader::new(&stream); | ||||
| @ -36,9 +35,10 @@ pub fn handle_connection(mut stream: TcpStream) { | ||||
|     // Handle 404.
 | ||||
|     if inc_request.path.is_empty() { | ||||
|         response = return_response("404"); | ||||
|         stream.write_all(response.as_bytes()).unwrap() | ||||
|     } | ||||
| 
 | ||||
|     // Handle images.
 | ||||
|     // Handle images, else pages or assets.
 | ||||
|     if inc_request.path.contains("images") { | ||||
|         let mut public_route: String = "./public".to_string(); | ||||
|         public_route.push_str(&inc_request.path); | ||||
| @ -49,53 +49,10 @@ pub fn handle_connection(mut stream: TcpStream) { | ||||
|             status_line, | ||||
|             image_data.len() | ||||
|         ); | ||||
|         stream.write(response.as_bytes()).unwrap(); | ||||
|         stream.write(&image_data).unwrap(); | ||||
|     } | ||||
|     else { | ||||
|         stream.write_all(response.as_bytes()).unwrap(); | ||||
|         stream.write_all(&image_data).unwrap() | ||||
|     } else { | ||||
|         response = return_response(&inc_request.path); | ||||
|         stream.write(response.as_bytes()).unwrap(); | ||||
|         stream.write_all(response.as_bytes()).unwrap() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[allow(dead_code)] | ||||
| fn get_header(headers: Vec<String>, needle: &str) -> String { | ||||
|     let mut value = String::new(); | ||||
|     for header in headers { | ||||
|         let split_header: Vec<&str> = header.split(":").collect(); | ||||
|         let header_key: String = split_header.first().expect("Nothing here").to_string(); | ||||
|         if header_key == needle { | ||||
|             value = split_header[1].to_string(); | ||||
|         } | ||||
|     } 
 | ||||
|     value | ||||
| } | ||||
| 
 | ||||
| fn return_response(path_or_code: &str) -> String { | ||||
|     let status_line: String; | ||||
|     let contents: String; | ||||
| 
 | ||||
|     match path_or_code { | ||||
|         "404" => { | ||||
|             status_line = "HTTP/1.1 404 Not Found".to_string(); | ||||
|             contents = fs::read_to_string("./public/404.html").unwrap(); | ||||
|         }, | ||||
|         "200" => { | ||||
|             status_line = "HTTP/1.1 200 OK".to_string(); | ||||
|             contents = fs::read_to_string("./public/index.html").unwrap(); | ||||
|         }, | ||||
|         &_ => { | ||||
|             // Need to get the proper response based on the given path.
 | ||||
|             status_line = "HTTP/1.1 200 OK".to_string(); | ||||
|             contents = router::get_route_data(path_or_code); | ||||
|             // status_line = "HTTP/1.1 404 Not Found".to_string();
 | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     let length = contents.len(); | ||||
|     format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}") | ||||
| } | ||||
| 
 | ||||
| pub fn path_exists(path: &str) -> bool { | ||||
|     fs::metadata(path).is_ok() | ||||
| } | ||||
|  | ||||
							
								
								
									
										136
									
								
								src/lib.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								src/lib.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,136 @@ | ||||
| use std::fs; | ||||
| use std::{ | ||||
|     sync::{mpsc, Arc, Mutex}, | ||||
|     thread, | ||||
| }; | ||||
| use regex::Regex; | ||||
| 
 | ||||
| #[allow(dead_code)] | ||||
| pub struct ThreadPool { | ||||
|     workers: Vec<Worker>, | ||||
|     sender: mpsc::Sender<Job>, | ||||
| } | ||||
| 
 | ||||
| type Job = Box<dyn FnOnce() + Send + 'static>; | ||||
| 
 | ||||
| impl ThreadPool { | ||||
|     pub fn new(size: usize) -> ThreadPool { | ||||
|         assert!(size > 0); | ||||
|         let (sender, receiver) = mpsc::channel(); | ||||
|         let receiver = Arc::new(Mutex::new(receiver)); | ||||
|         let mut workers = Vec::with_capacity(size); | ||||
|         for id in 0..size { | ||||
|             workers.push(Worker::new(id, Arc::clone(&receiver))); | ||||
|         } | ||||
|         ThreadPool { workers, sender } | ||||
|     } | ||||
| 
 | ||||
|     pub fn process<F>(&self, f: F) | ||||
|     where | ||||
|         F: FnOnce() + Send + 'static, | ||||
|     { | ||||
|         let job = Box::new(f); | ||||
|         self.sender.send(job).unwrap(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[allow(dead_code)] | ||||
| struct Worker { | ||||
|     id: usize, | ||||
|     thread: thread::JoinHandle<()>, | ||||
| } | ||||
| 
 | ||||
| impl Worker { | ||||
|     fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker { | ||||
|         let thread = thread::spawn(move || loop { | ||||
|             let job = receiver.lock().unwrap().recv().unwrap(); | ||||
|             // println!("Worker {id} got a job; executing.");
 | ||||
|             job(); | ||||
|         }); | ||||
| 
 | ||||
|         Worker { id, thread } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Create the response for a request.
 | ||||
| pub fn return_response(path_or_code: &str) -> String { | ||||
|     let status_line: String; | ||||
|     let contents: String; | ||||
|     match path_or_code { | ||||
|         "404" => { | ||||
|             status_line = "HTTP/1.1 404 Not Found".to_string(); | ||||
|             contents = fs::read_to_string("./public/pages/404.html").unwrap(); | ||||
|         }, | ||||
|         &_ => { | ||||
|             status_line = "HTTP/1.1 200 OK".to_string(); | ||||
|             contents = get_route_data(path_or_code); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     let length = contents.len(); | ||||
|     format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}") | ||||
| } | ||||
| 
 | ||||
| // Generate the data for the given route.
 | ||||
| pub fn get_route_data(route: &str) -> String { | ||||
|     match route { | ||||
|         "/" => { | ||||
|             let file_contents = fs::read_to_string("./public/pages/index.html").unwrap(); | ||||
|             hot_swap(&file_contents) | ||||
|         }, | ||||
|         "/scorecards" => { | ||||
|             let file_contents = fs::read_to_string("./public/pages/scorecards.html").unwrap(); | ||||
|             hot_swap(&file_contents) | ||||
|         }, | ||||
|         "/add-scorecard" => { | ||||
|             let file_contents = fs::read_to_string("./public/pages/add-scorecard.html").unwrap(); | ||||
|             hot_swap(&file_contents) | ||||
|         }, | ||||
|         _ if route.contains("assets") => { | ||||
|             let mut public_route: String = "./public".to_string(); | ||||
|             public_route.push_str(&route); | ||||
|             return fs::read_to_string(&public_route).unwrap() | ||||
|         }, | ||||
|         &_ => { | ||||
|             return fs::read_to_string("./public/pages/404.html").unwrap(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Swap dynamic sections of html template.
 | ||||
| pub fn hot_swap(source_html: &str) -> String { | ||||
|     let mut updated_html: String = String::from(source_html); | ||||
|     let re = Regex::new(r"\{%.(?<name>.*).%\}").unwrap(); | ||||
|     for section in re.captures_iter(source_html) { | ||||
|         let comp_content = retrieve_component(§ion["name"]); | ||||
|         updated_html = updated_html.replace(§ion[0], &comp_content); | ||||
|     } | ||||
|     updated_html | ||||
| } | ||||
| 
 | ||||
| // Retrieve html markup from component.
 | ||||
| pub fn retrieve_component(component: &str) -> String { | ||||
|     let mut comp_path = String::from("./public/components/"); | ||||
|     let html_ext = String::from(".html"); | ||||
|     comp_path.push_str(&component); | ||||
|     comp_path.push_str(&html_ext); | ||||
|     fs::read_to_string(&comp_path).unwrap() | ||||
| } | ||||
| 
 | ||||
| // Validate if a given path exists.
 | ||||
| pub fn path_exists(path: &str) -> bool { | ||||
|     fs::metadata(path).is_ok() | ||||
| } | ||||
| 
 | ||||
| #[allow(dead_code)] | ||||
| pub fn get_header(headers: Vec<String>, needle: &str) -> String { | ||||
|     let mut value = String::new(); | ||||
|     for header in headers { | ||||
|         let split_header: Vec<&str> = header.split(":").collect(); | ||||
|         let header_key: String = split_header.first().expect("Nothing here").to_string(); | ||||
|         if header_key == needle { | ||||
|             value = split_header[1].to_string(); | ||||
|         } | ||||
|     } 
 | ||||
|     value | ||||
| } | ||||
							
								
								
									
										17
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								src/main.rs
									
									
									
									
									
								
							| @ -1,20 +1,17 @@ | ||||
| use std::net::TcpListener; | ||||
| 
 | ||||
| use batflip::ThreadPool; | ||||
| // use std::thread;
 | ||||
| pub mod connection; | ||||
| mod router; | ||||
| 
 | ||||
| // Listen on port and return response.
 | ||||
| fn main() { | ||||
|     let run_local = true; | ||||
|     let mut listener = TcpListener::bind("127.0.0.1:6942").unwrap(); | ||||
| 
 | ||||
|     if !run_local { | ||||
|         listener = TcpListener::bind("0.0.0.0:6942").unwrap(); | ||||
|     } 
 | ||||
| 
 | ||||
|     let listener = TcpListener::bind("127.0.0.1:6942").unwrap(); | ||||
|     let pool = ThreadPool::new(4); | ||||
|     for stream in listener.incoming() { | ||||
|         let stream = stream.unwrap(); | ||||
|         connection::handle_connection(stream); | ||||
|         pool.process(move || { | ||||
|             connection::handle_connection(stream); | ||||
|         }); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,24 +0,0 @@ | ||||
| use std::fs; | ||||
| 
 | ||||
| pub fn get_route_data(route: &str) -> String { | ||||
|     match route { | ||||
|         "/" => { | ||||
|             return fs::read_to_string("./public/index.html").unwrap(); | ||||
|         }, | ||||
|         "/about" => { | ||||
|             return fs::read_to_string("./public/pages/about.html").unwrap(); | ||||
|         } | ||||
|         _ if route.contains("assets") => { | ||||
|             let mut public_route: String = "./public".to_string(); | ||||
|             public_route.push_str(&route); | ||||
|             return fs::read_to_string(&public_route).unwrap() | ||||
|         }, | ||||
|         &_ => { | ||||
|             return fs::read_to_string("./public/404.html").unwrap(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // pub fn path_exists(path: &str) -> bool {
 | ||||
| //     fs::metadata(path).is_ok()
 | ||||
| // }
 | ||||
							
								
								
									
										14
									
								
								theme/header.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								theme/header.scss
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| header { | ||||
|   background: var(--blue); | ||||
|   padding: 20px; | ||||
| 
 | ||||
|   #site-name { | ||||
|     font-family: var(--secondary-font); | ||||
|     font-size: 2rem; | ||||
|     letter-spacing: 1px; | ||||
|   } | ||||
| 
 | ||||
|   a { | ||||
|     color: var(--background); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										36
									
								
								theme/headings.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								theme/headings.scss
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | ||||
| h1, h2, h3, h4, h5, h6 { | ||||
|   font-family:  var(--primary-font); | ||||
| } | ||||
| 
 | ||||
| h1 { | ||||
|   font-size: 3rem; | ||||
|   font-weight: 700; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| h2 { | ||||
|   font-size: 2.5rem; | ||||
|   font-weight: 700; | ||||
| } | ||||
| 
 | ||||
| h3 { | ||||
|   font-size: 2rem; | ||||
|   font-weight: 500;   | ||||
| } | ||||
| 
 | ||||
| h4 { | ||||
|   font-size: 1.5rem; | ||||
|   font-weight: 500;   | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| h5 { | ||||
|   font-size: 1.2rem; | ||||
|   font-weight: 500;   | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| h6 { | ||||
|   font-size: 1rem; | ||||
|   font-weight: 500; | ||||
| } | ||||
| @ -1,9 +1,20 @@ | ||||
| @import url('https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap'); | ||||
| @import url('https://fonts.googleapis.com/css2?family=Anton&family=Bebas+Neue&display=swap'); | ||||
| @import "variables"; | ||||
| @import "reset"; | ||||
| @import "header"; | ||||
| @import "headings"; | ||||
| @import "tables"; | ||||
| 
 | ||||
| body { | ||||
|   background: orange; | ||||
|   background: var(--background); | ||||
|   color: var(--primary-text); | ||||
|   padding: 20px; | ||||
|   font-size: 1.2rem; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| img { | ||||
|   max-width: 100%; | ||||
|   display: block; | ||||
|  | ||||
							
								
								
									
										36
									
								
								theme/tables.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								theme/tables.scss
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | ||||
| .styled-table { | ||||
|     border-collapse: collapse; | ||||
|     margin: 25px 0; | ||||
|     font-size: 0.9em; | ||||
|     font-family: sans-serif; | ||||
|     min-width: 400px; | ||||
|     box-shadow: 0 0 20px rgba(0, 0, 0, 0.15); | ||||
| } | ||||
| 
 | ||||
| .styled-table thead tr { | ||||
|     background-color: #009879; | ||||
|     color: #ffffff; | ||||
|     text-align: left; | ||||
| } | ||||
| 
 | ||||
| .styled-table th, | ||||
| .styled-table td { | ||||
|     padding: 12px 15px; | ||||
| } | ||||
| 
 | ||||
| .styled-table tbody tr { | ||||
|     border-bottom: 1px solid #dddddd; | ||||
| } | ||||
| 
 | ||||
| .styled-table tbody tr:nth-of-type(even) { | ||||
|     background-color: #f3f3f3; | ||||
| } | ||||
| 
 | ||||
| .styled-table tbody tr:last-of-type { | ||||
|     border-bottom: 2px solid #009879; | ||||
| } | ||||
| 
 | ||||
| .styled-table tbody tr.active-row { | ||||
|     font-weight: bold; | ||||
|     color: #009879; | ||||
| } | ||||
							
								
								
									
										14
									
								
								theme/variables.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								theme/variables.scss
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| // Color Scheme | ||||
| :root { | ||||
|   --blue: #002D62; | ||||
|   --red: #C8102E; | ||||
|   --green: #4CAF50; | ||||
|   --background: #F5F5F5; | ||||
|   --primary-text: #1A1A1A; | ||||
|   --secondary-text: #555555; | ||||
|   --success: #2E8B57; | ||||
|   --warning: #FFA500; | ||||
|   --error: #D72638; | ||||
|   --primary-font: "Bebas Neue", sans-serif; | ||||
|   --secondary-font: "Anton", sans-serif; | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user