From 88c1b2517c8cca90be53c2d6e92aae1a22aea7eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20Kaan=20G=C3=BCm=C3=BC=C5=9F?= Date: Sat, 1 Mar 2025 22:35:04 +0300 Subject: [PATCH] refactor: :recycle: file organizations --- configs/client_config.toml | 2 + configs/server_config.toml | 2 + src/client.rs | 45 +++++++++++++++++++ src/lib.rs | 91 ++++++++++++++++++++++++++++++++++++++ src/main.rs | 70 +---------------------------- src/server.rs | 53 ++++++++++++++++++++++ src/voice.rs | 0 7 files changed, 195 insertions(+), 68 deletions(-) create mode 100644 configs/client_config.toml create mode 100644 configs/server_config.toml create mode 100644 src/client.rs create mode 100644 src/lib.rs create mode 100644 src/server.rs create mode 100644 src/voice.rs diff --git a/configs/client_config.toml b/configs/client_config.toml new file mode 100644 index 0000000..95fc839 --- /dev/null +++ b/configs/client_config.toml @@ -0,0 +1,2 @@ +[client_config] +server_address = "127.0.0.1:2554" diff --git a/configs/server_config.toml b/configs/server_config.toml new file mode 100644 index 0000000..ad9a2ac --- /dev/null +++ b/configs/server_config.toml @@ -0,0 +1,2 @@ +[server_config] +server_address = "127.0.0.1:2554" diff --git a/src/client.rs b/src/client.rs new file mode 100644 index 0000000..297a275 --- /dev/null +++ b/src/client.rs @@ -0,0 +1,45 @@ +use std::{net::SocketAddr, path::Path}; + +use s2n_quic::{Client, client::Connect}; +use tokio::io::AsyncWriteExt; + +use crate::ClientConfig; + +pub async fn run<'a>(client_config: ClientConfig<'a>) { + let client = Client::builder() + .with_io("0:0") + .unwrap() + .with_tls(Path::new("certificates/cert.pem")) + .unwrap() + .start() + .unwrap(); + + println!("Client Address = {}", client.local_addr().unwrap()); + let connect = Connect::new(client_config.server_address.parse::().unwrap()) + .with_server_name("localhost"); + let mut connection = match client.connect(connect).await { + Ok(connection) => connection, + Err(err_val) => { + eprintln!("Error: Client Connection | {}", err_val); + return; + } + }; + connection.keep_alive(true).unwrap(); + + let stream = connection.open_bidirectional_stream().await.unwrap(); + let (mut receive_stream, mut send_stream) = stream.split(); + send_stream + .send("Hi from Tahinli".as_bytes().into()) + .await + .unwrap(); + let received = receive_stream.receive().await.unwrap().unwrap(); + println!("{}", String::from_utf8(received.to_vec()).unwrap()); + + if let Err(err_val) = send_stream.close().await { + eprintln!("Error: Stream Close | {}", err_val); + } + + if let Err(err_val) = send_stream.shutdown().await { + eprintln!("Error: Stream Shutdown| {}", err_val); + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..cb61464 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,91 @@ +use std::{collections::VecDeque, env, fs::File, io::Read}; + +mod client; +mod server; +mod voice; + +#[derive(Debug, Clone)] +struct TOML { + header: String, + fields: VecDeque, +} + +const SERVER_CONFIG_FILE_LOCATION: &str = "configs/server_config.toml"; +const CLIENT_CONFIG_FILE_LOCATION: &str = "configs/client_config.toml"; + +#[derive(Debug)] +struct ServerConfig<'a> { + server_address: &'a str, +} + +#[derive(Debug)] +struct ClientConfig<'a> { + server_address: &'a str, +} + +async fn server() { + let mut config = naive_toml_parser(SERVER_CONFIG_FILE_LOCATION); + + if config.header.as_str() == "server_config" { + let server_config = ServerConfig { + server_address: &config.fields.pop_front().unwrap(), + }; + server::run(server_config).await; + } else { + eprintln!("Error: Server Config File Couldn't Be Parsed Correctly"); + } +} + +async fn client() { + let mut config = naive_toml_parser(CLIENT_CONFIG_FILE_LOCATION); + + if config.header.as_str() == "client_config" { + let client_config = ClientConfig { + server_address: &config.fields.pop_front().unwrap(), + }; + client::run(client_config).await; + } else { + eprintln!("Error: Client Config File Couldn't Be Parsed Correctly"); + } +} + +pub async fn start() { + match env::args().collect::>().get(1) { + Some(arg) => match arg.as_str() { + "-c" | "--client" => client().await, + "-s" | "--server" => server().await, + _ => return, + }, + None => return, + } +} + +fn naive_toml_parser(file_location: &str) -> TOML { + let mut toml_file = File::open(file_location).unwrap(); + let mut toml_ingredients = String::default(); + toml_file.read_to_string(&mut toml_ingredients).unwrap(); + let mut toml_ingredients = toml_ingredients.lines().collect::>(); + + let header = toml_ingredients + .pop_front() + .unwrap() + .replace('[', "") + .replace(']', "") + .trim_end() + .to_string(); + + let fields = toml_ingredients + .iter() + .map(|ingredient| { + ingredient + .split_once('=') + .unwrap() + .1 + .replace('"', "") + .trim() + .to_string() + }) + .collect(); + + TOML { header, fields } +} diff --git a/src/main.rs b/src/main.rs index 2b4a770..6a25663 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,74 +1,8 @@ -use std::{net::SocketAddr, path::Path, time::Duration}; - -use s2n_quic::{Client, Server, client::Connect}; - -const SERVER_ADDRESS: &str = "127.0.0.1:2021"; +use voice_chat::start; #[tokio::main] async fn main() { println!("Hello, world!"); - tokio::spawn(server()); - tokio::time::sleep(Duration::from_secs(1)).await; - client().await; -} - -async fn server() { - let mut server = Server::builder() - .with_io(SERVER_ADDRESS) - .unwrap() - .with_tls(( - Path::new("certificates/cert.pem"), - Path::new("certificates/key.pem"), - )) - .unwrap() - .start() - .unwrap(); - while let Some(mut connection) = server.accept().await { - println!( - "Server Name = {}", - connection.server_name().unwrap().unwrap().to_string() - ); - while let Ok(Some(mut stream)) = connection.accept_bidirectional_stream().await { - println!( - "{}", - String::from_utf8(stream.receive().await.unwrap().unwrap().to_vec()).unwrap() - ); - stream - .send("Hi from Tahinli too".as_bytes().into()) - .await - .unwrap(); - } - } -} - -async fn client() { - let client = Client::builder() - .with_io("127.0.0.1:0") - .unwrap() - .with_tls(Path::new("certificates/cert.pem")) - .unwrap() - .start() - .unwrap(); - - println!("Client Address = {}", client.local_addr().unwrap()); - let connect = - Connect::new(SERVER_ADDRESS.parse::().unwrap()).with_server_name("localhost"); - let mut connection = match client.connect(connect).await { - Ok(connection) => connection, - Err(err_val) => { - eprintln!("Client Connection | {}", err_val); - return; - } - }; - connection.keep_alive(true).unwrap(); - - let stream = connection.open_bidirectional_stream().await.unwrap(); - let (mut receive_stream, mut send_stream) = stream.split(); - send_stream - .send("Hi from Tahinli".as_bytes().into()) - .await - .unwrap(); - let received = receive_stream.receive().await.unwrap().unwrap(); - println!("{}", String::from_utf8(received.to_vec()).unwrap()); + start().await; } diff --git a/src/server.rs b/src/server.rs new file mode 100644 index 0000000..9a0799b --- /dev/null +++ b/src/server.rs @@ -0,0 +1,53 @@ +use std::path::Path; + +use s2n_quic::Server; +use tokio::io::AsyncWriteExt; + +use crate::ServerConfig; + +pub async fn run<'a>(server_config: ServerConfig<'a>) { + let mut server = Server::builder() + .with_io(server_config.server_address) + .unwrap() + .with_tls(( + Path::new("certificates/cert.pem"), + Path::new("certificates/key.pem"), + )) + .unwrap() + .start() + .unwrap(); + while let Some(mut connection) = server.accept().await { + println!( + "Server Name = {}", + connection.server_name().unwrap().unwrap().to_string() + ); + + println!( + "Client Address = {}", + connection.remote_addr().unwrap().to_string() + ); + while let Ok(Some(mut stream)) = connection.accept_bidirectional_stream().await { + println!( + "{}", + String::from_utf8(stream.receive().await.unwrap().unwrap().to_vec()).unwrap() + ); + match stream.send("Hi from Tahinli too".as_bytes().into()).await { + Ok(_) => { + if let Err(err_val) = stream.flush().await { + eprintln!("Error: Flush | {}", err_val); + } + } + Err(err_val) => eprintln!("Error: Send | {}", err_val), + } + if let Err(err_val) = stream.close().await { + eprintln!("Error: Stream Close | {}", err_val); + } + + if let Err(err_val) = stream.shutdown().await { + eprintln!("Error: Stream Shutdown | {}", err_val); + } + return; + } + return; + } +} diff --git a/src/voice.rs b/src/voice.rs new file mode 100644 index 0000000..e69de29