use std::{ fs, io::Write, net::{SocketAddr, TcpListener, TcpStream}, path::Path, result, str::FromStr, }; use crate::buffer::ByteBuffer; mod buffer; const IP: &str = "0.0.0.0"; const PORT: &str = "9696"; type Result = result::Result; fn main() -> Result<()> { let socket = SocketAddr::from_str(&format!("{}:{}", IP, PORT)).unwrap(); let listener = TcpListener::bind(socket).unwrap(); for stream in listener.incoming() { match stream { Ok(conn) => handle_connection(conn)?, Err(e) => eprintln!("Something went wrong while listening {e}"), } } Ok(()) } fn handle_connection(mut conn: TcpStream) -> Result<()> { let export = "./examples/"; let mut paths = vec![]; let mut buffer = ByteBuffer::default(); visit_dir(export, &mut paths); buffer.write_usize(paths.len()); for file in paths { let path = file.replace(export, ""); buffer.write_string(&path); match fs::read(format!("./{file}")) { Ok(data) => { buffer.write_usize(data.len()); buffer.write_bytes(&data); } Err(_) => { buffer.write_usize(0); eprintln!("No file found") } }; } let _ = conn.write_all(&buffer); let _ = conn.flush(); Ok(()) } fn visit_dir>(path: P, file_paths: &mut Vec) { for entry in fs::read_dir(path).unwrap().flatten() { if entry.path().is_dir() { visit_dir(entry.path(), file_paths); return; } let file_path = entry.path().to_str().unwrap().to_string(); file_paths.push(file_path); } } #[cfg(test)] mod tests { use std::io::Read; use super::*; #[test] fn test_connection() { let conn = TcpStream::connect(format!("{}:{}", IP, PORT)); assert!(conn.is_ok()); let mut conn = conn.unwrap(); let mut buffer = ByteBuffer::default(); let bytes_read = conn.read_to_end(&mut buffer); assert!(bytes_read.is_ok()); let file_name = buffer.read_string(); assert_eq!(file_name, "examples/test.md"); // let content = buffer.read_bytes(buffer.unread_len()); // println!("{}", String::from_utf8(content).unwrap()); } }