Merge pull request #9 from Tahinli/dev
refactor: better user experience
This commit is contained in:
commit
384e460bc2
1 changed files with 459 additions and 171 deletions
630
src/main.rs
630
src/main.rs
|
@ -1,83 +1,231 @@
|
||||||
use std::fs::{File, Metadata, self};
|
use std::fs::{File, Metadata, self};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use std::net::{TcpListener, TcpStream};
|
use std::net::{TcpListener, TcpStream, IpAddr};
|
||||||
use std::io::{Read, Write, self, BufWriter, BufReader, BufRead};
|
use std::io::{Read, Write, BufWriter, BufReader, BufRead};
|
||||||
use std::env::{self};
|
use std::env::{self};
|
||||||
|
|
||||||
|
|
||||||
const BUFFER_SIZE:u64 = 100000;
|
const BUFFER_SIZE:u64 = 100000;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct UserEnvironment
|
||||||
|
{
|
||||||
|
ip:IpAddr,
|
||||||
|
port:u16,
|
||||||
|
server:bool,
|
||||||
|
send:bool,
|
||||||
|
location:Option<String>,
|
||||||
|
debug:bool,
|
||||||
|
}
|
||||||
|
impl UserEnvironment
|
||||||
|
{
|
||||||
|
fn user_environment() -> UserEnvironment
|
||||||
|
{
|
||||||
|
UserEnvironment
|
||||||
|
{
|
||||||
|
ip:"127.0.0.1".parse().unwrap(),
|
||||||
|
port:2121,
|
||||||
|
server:false,
|
||||||
|
send:false,
|
||||||
|
location:None,
|
||||||
|
debug:false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(Debug)]
|
||||||
struct FileInfo
|
struct FileInfo
|
||||||
{
|
{
|
||||||
file:Option<File>,
|
file:Option<File>,
|
||||||
location:String,
|
location:Option<String>,
|
||||||
size_current:usize,
|
sign:Option<String>,
|
||||||
|
size_total:u64,
|
||||||
|
size_current:u64,
|
||||||
metadata:Option<Metadata>,
|
metadata:Option<Metadata>,
|
||||||
|
progress:u8,
|
||||||
}
|
}
|
||||||
impl FileInfo
|
impl FileInfo
|
||||||
{
|
{
|
||||||
|
fn file_info() -> FileInfo
|
||||||
|
{
|
||||||
|
FileInfo
|
||||||
|
{
|
||||||
|
file: None,
|
||||||
|
location: None,
|
||||||
|
sign: None,
|
||||||
|
size_total: 0,
|
||||||
|
size_current: 0,
|
||||||
|
metadata: None,
|
||||||
|
progress: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn pass_user_environment(&mut self, user_environment:&UserEnvironment)
|
||||||
|
{
|
||||||
|
self.location = user_environment.location.clone();
|
||||||
|
self.sign = user_environment.location.clone();
|
||||||
|
}
|
||||||
fn reading_operations(&mut self, stream:&mut TcpStream, debug_mode:&bool)
|
fn reading_operations(&mut self, stream:&mut TcpStream, debug_mode:&bool)
|
||||||
{
|
{
|
||||||
self.read_metadata();
|
match self.location.as_ref()
|
||||||
match self.metadata
|
|
||||||
{
|
{
|
||||||
Some(ref mut metadata) =>
|
Some(_) =>
|
||||||
{
|
{
|
||||||
if Metadata::is_file(metadata)
|
self.read_metadata(debug_mode);
|
||||||
|
match self.metadata
|
||||||
{
|
{
|
||||||
self.open_file();
|
Some(ref mut metadata) =>
|
||||||
self.send_file(stream, debug_mode);
|
{
|
||||||
}
|
if Metadata::is_symlink(metadata)
|
||||||
else if Metadata::is_symlink(metadata)
|
{
|
||||||
{
|
//Unix-Windows Problem
|
||||||
self.open_file();
|
println!("\n\tError: Symlink Transfers've not Supported yet\n");
|
||||||
self.send_file(stream, debug_mode);
|
return;
|
||||||
}
|
//self.open_file(debug_mode);
|
||||||
else
|
//self.send_file(stream, &(100 as u8),debug_mode);
|
||||||
{
|
}
|
||||||
//path recognition and creation on the other side
|
else if Metadata::is_file(metadata)
|
||||||
//std:path
|
{
|
||||||
panic!("\n\tError: Folder Transfers've not Supported yet\n")
|
self.open_file(debug_mode);
|
||||||
|
self.send_file(stream, &(101 as u8),debug_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if Metadata::is_dir(metadata)
|
||||||
|
{
|
||||||
|
//path recognition and creation on the other side
|
||||||
|
//std:path
|
||||||
|
println!("\n\tError: Folder Transfers've not Supported yet\n");
|
||||||
|
return;
|
||||||
|
//self.open_file(debug_mode);
|
||||||
|
//self.send_file(stream, &(102 as u8),debug_mode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
println!("Error: Undefined Type -> {}", self.location.as_ref().unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None =>
|
||||||
|
{
|
||||||
|
println!("Error: Read Metadata -> {}", self.location.as_ref().unwrap());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None =>
|
None =>
|
||||||
{
|
{
|
||||||
println!("Error: Read Metadata -> {}", self.location);
|
println!("Error: Reading Operations -> {:#?}", &self.location);
|
||||||
|
panic!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn writing_operations(&mut self, stream:&mut TcpStream, debug_mode:&bool)
|
fn writing_operations(&mut self, stream:&mut TcpStream, debug_mode:&bool)
|
||||||
{
|
{
|
||||||
self.forge_file();
|
|
||||||
self.write_file(stream, debug_mode);
|
self.write_file(stream, debug_mode);
|
||||||
|
self.cleaning();
|
||||||
}
|
}
|
||||||
fn read_metadata(&mut self)
|
fn cleaning(&mut self)
|
||||||
{
|
{
|
||||||
self.metadata = Some(fs::metadata(&self.location).expect("Error: Read Metadata"));
|
self.location = self.sign.clone();
|
||||||
|
self.size_current = 0;
|
||||||
}
|
}
|
||||||
fn open_file(&mut self)
|
fn read_metadata(&mut self, debug_mode:&bool)
|
||||||
{
|
{
|
||||||
match File::open(&self.location)
|
let path = PathBuf::from(self.location.as_ref().unwrap());
|
||||||
|
if path.is_symlink()
|
||||||
|
{
|
||||||
|
match path.symlink_metadata()
|
||||||
|
{
|
||||||
|
Ok(metadata) =>
|
||||||
|
{
|
||||||
|
self.metadata = Some(metadata);
|
||||||
|
}
|
||||||
|
Err(err_val) =>
|
||||||
|
{
|
||||||
|
println!("Error: Symlink Metadata -> {:#?} | Error: {}", &self.location, err_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
match fs::metadata(&self.location.as_ref().unwrap())
|
||||||
|
{
|
||||||
|
Ok(metadata) =>
|
||||||
|
{
|
||||||
|
self.metadata = Some(metadata);
|
||||||
|
if *debug_mode
|
||||||
|
{
|
||||||
|
println!("Done: Read Metadata -> {:#?}", self.metadata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err_val) =>
|
||||||
|
{
|
||||||
|
println!("Error: Read Metadata -> {} | Error: {}", &self.location.as_ref().unwrap(), err_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn open_file(&mut self,debug_mode:&bool)
|
||||||
|
{
|
||||||
|
match File::options().read(true).write(true).open(self.location.as_ref().unwrap())
|
||||||
{
|
{
|
||||||
Ok(file) =>
|
Ok(file) =>
|
||||||
{
|
{
|
||||||
self.file = Some(file);
|
self.file = Some(file);
|
||||||
|
if *debug_mode
|
||||||
|
{
|
||||||
|
println!("Done : Open File -> {:#?}", self.file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(err_val) =>
|
Err(err_val) =>
|
||||||
{
|
{
|
||||||
println!("Error: Open File -> {} | Error: {}", self.location, err_val);
|
println!("Error: Open File -> {} | Error: {}", self.location.as_ref().unwrap(), err_val);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
fn send_file(&mut self, stream:&mut TcpStream, debug_mode:&bool)
|
fn send_file(&mut self, stream:&mut TcpStream, what_type:&u8,debug_mode:&bool)
|
||||||
{
|
{
|
||||||
let size = self.metadata.as_ref().unwrap().len();
|
self.size_total = self.metadata.as_ref().unwrap().len();
|
||||||
let mut iteration = (size/BUFFER_SIZE)+1;
|
let mut iteration = (self.size_total/BUFFER_SIZE)+1;
|
||||||
let total_iteration = iteration;
|
let total_iteration = iteration;
|
||||||
self.handshake_validation(stream, size, debug_mode);
|
let path_buf = PathBuf::from(Path::new(self.location.as_ref().unwrap()));
|
||||||
println!("Size = {}", size);
|
match what_type
|
||||||
println!("Iteration = {}", iteration);
|
{
|
||||||
|
100 =>
|
||||||
|
{
|
||||||
|
if *debug_mode
|
||||||
|
{
|
||||||
|
println!("Done: Symlink Detected -> {}", self.location.as_ref().unwrap());
|
||||||
|
}
|
||||||
|
self.callback_validation(stream, &String::from("100"), debug_mode);
|
||||||
|
}
|
||||||
|
101 =>
|
||||||
|
{
|
||||||
|
if *debug_mode
|
||||||
|
{
|
||||||
|
println!("Done: File Detected -> {}", self.location.as_ref().unwrap());
|
||||||
|
}
|
||||||
|
self.callback_validation(stream, &String::from("101"), debug_mode)
|
||||||
|
}
|
||||||
|
102 =>
|
||||||
|
{
|
||||||
|
if *debug_mode
|
||||||
|
{
|
||||||
|
println!("Done: Folder Detected -> {}", self.location.as_ref().unwrap());
|
||||||
|
}
|
||||||
|
self.callback_validation(stream, &String::from("102"), debug_mode)
|
||||||
|
}
|
||||||
|
_ =>
|
||||||
|
{
|
||||||
|
|
||||||
|
println!("Error: Undefined Type Detected ->{}", self.location.as_ref().unwrap());
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.callback_validation(stream, &(self.size_total.to_string()), debug_mode);
|
||||||
|
self.callback_validation(stream, &path_buf.file_name().unwrap().to_str().unwrap().to_string(), debug_mode);
|
||||||
|
|
||||||
|
self.show_info(&iteration, debug_mode);
|
||||||
while iteration != 0
|
while iteration != 0
|
||||||
{
|
{
|
||||||
iteration -= 1;
|
iteration -= 1;
|
||||||
|
@ -88,35 +236,35 @@ impl FileInfo
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
self.read_exact(&mut buffer[..(size%BUFFER_SIZE) as usize], debug_mode);
|
self.read_exact(&mut buffer[..(self.size_total%BUFFER_SIZE) as usize], debug_mode);
|
||||||
}
|
}
|
||||||
if *debug_mode
|
if *debug_mode
|
||||||
{
|
{
|
||||||
println!("Read Data = {:#?}", buffer);
|
println!("Read Data = {:#?}", buffer);
|
||||||
}
|
}
|
||||||
self.send_exact(&mut buffer, stream, debug_mode);
|
self.send_exact(&mut buffer, stream, debug_mode);
|
||||||
println!("%{}", 100 as f64 -((iteration as f64/total_iteration as f64)*100 as f64));
|
self.show_progress(iteration, total_iteration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn handshake_validation(&mut self, stream:&mut TcpStream, size:u64, debug_mode:&bool)
|
fn callback_validation(&mut self, stream:&mut TcpStream, data:&String, debug_mode:&bool)
|
||||||
{
|
{
|
||||||
self.send_exact(String::from(size.to_string()+"\n").as_bytes(), stream, debug_mode);
|
self.send_exact(String::from(data.clone() + "\n").as_bytes(), stream, debug_mode);
|
||||||
match self.recv_until(stream, '\n', debug_mode)
|
match self.recv_until(stream, '\n', debug_mode)
|
||||||
{
|
{
|
||||||
Some(handshake_callback) =>
|
Some(callback_callback) =>
|
||||||
{
|
{
|
||||||
if handshake_callback == size.to_string().as_bytes().to_vec()
|
if callback_callback == data.to_string().as_bytes().to_vec()
|
||||||
{
|
{
|
||||||
println!("Done: Handshake -> {}", self.location);
|
|
||||||
if *debug_mode
|
if *debug_mode
|
||||||
{
|
{
|
||||||
println!("{:#?} ", handshake_callback);
|
println!("Done: Callback -> {}", self.location.as_ref().unwrap());
|
||||||
|
println!("{:#?} ", callback_callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
println!("Error: Handshake -> {}", self.location);
|
println!("Error: Callback -> {}", self.location.as_ref().unwrap());
|
||||||
println!("{:#?} ", handshake_callback);
|
println!("{:#?} ", callback_callback);
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,13 +282,13 @@ impl FileInfo
|
||||||
{
|
{
|
||||||
if *debug_mode
|
if *debug_mode
|
||||||
{
|
{
|
||||||
println!("Done: Read Bytes -> {}", self.location);
|
println!("Done: Read Bytes -> {}", self.location.as_ref().unwrap());
|
||||||
println!("{:#?}", buffer);
|
println!("{:#?}", buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err_val) =>
|
Err(err_val) =>
|
||||||
{
|
{
|
||||||
println!("Error: Read Bytes -> {} | Error: {}", self.location, err_val);
|
println!("Error: Read Bytes -> {} | Error: {}", self.location.as_ref().unwrap(), err_val);
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,16 +300,16 @@ impl FileInfo
|
||||||
{
|
{
|
||||||
Ok(_) =>
|
Ok(_) =>
|
||||||
{
|
{
|
||||||
self.size_current += buffer.len();
|
self.size_current += buffer.len() as u64;
|
||||||
if *debug_mode
|
if *debug_mode
|
||||||
{
|
{
|
||||||
println!("Done: Send Bytes -> {}", self.location);
|
println!("Done: Send Bytes -> {:#?}", self.location);
|
||||||
println!("{:#?}", buffer);
|
println!("{:#?}", buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err_val) =>
|
Err(err_val) =>
|
||||||
{
|
{
|
||||||
println!("Error: Send Bytes -> {} | Error: {}", self.location, err_val);
|
println!("Error: Send Bytes -> {:#?} | Error: {}", self.location, err_val);
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,12 +319,12 @@ impl FileInfo
|
||||||
{
|
{
|
||||||
if *debug_mode
|
if *debug_mode
|
||||||
{
|
{
|
||||||
println!("Done: Flush -> {}", self.location);
|
println!("Done: Flush -> {:#?}", self.location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err_val) =>
|
Err(err_val) =>
|
||||||
{
|
{
|
||||||
println!("Error: Flush -> {} | Error: {}", self.location, err_val);
|
println!("Error: Flush -> {:#?} | Error: {}", self.location, err_val);
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,16 +335,16 @@ impl FileInfo
|
||||||
{
|
{
|
||||||
Ok(_) =>
|
Ok(_) =>
|
||||||
{
|
{
|
||||||
self.size_current += buffer.len();
|
self.size_current += buffer.len() as u64;
|
||||||
if *debug_mode
|
if *debug_mode
|
||||||
{
|
{
|
||||||
println!("Done: Receive Bytes -> {}", self.location);
|
println!("Done: Receive Bytes -> {:#?}", self.location);
|
||||||
println!("{:#?}", buffer);
|
println!("{:#?}", buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err_val) =>
|
Err(err_val) =>
|
||||||
{
|
{
|
||||||
println!("Error: Receive Bytes -> {} | Error: {}", self.location, err_val);
|
println!("Error: Receive Bytes -> {:#?} | Error: {}", self.location, err_val);
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,62 +359,113 @@ impl FileInfo
|
||||||
{
|
{
|
||||||
if *debug_mode
|
if *debug_mode
|
||||||
{
|
{
|
||||||
println!("Done: Receive Until -> {}", self.location);
|
println!("Done: Receive Until -> {:#?}", self.location);
|
||||||
println!("{:#?}", buffer);
|
println!("{:#?}", buffer);
|
||||||
}
|
}
|
||||||
buffer.pop();
|
buffer.pop();
|
||||||
}
|
}
|
||||||
Err(err_val) =>
|
Err(err_val) =>
|
||||||
{
|
{
|
||||||
println!("Error: Receive Until -> {} | Error: {}", self.location, err_val);
|
println!("Error: Receive Until -> {:#?} | Error: {}", self.location, err_val);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Some(buffer);
|
return Some(buffer);
|
||||||
}
|
}
|
||||||
fn forge_file(&mut self)
|
fn forge_file(&mut self, location:String, debug_mode:&bool)
|
||||||
{
|
{
|
||||||
self.file = Some(File::create(&self.location).expect("Error: Create File"));
|
//dont forget
|
||||||
}
|
//directory recognition required for received location
|
||||||
fn handshake_recv(&mut self, stream:&mut TcpStream, debug_mode:&bool) -> u64
|
match self.location.as_ref()
|
||||||
{
|
|
||||||
match self.recv_until(stream, '\n', debug_mode)
|
|
||||||
{
|
{
|
||||||
Some(mut handshake) =>
|
Some(self_location) =>
|
||||||
{
|
{
|
||||||
println!("Done: Handshake -> {}", self.location);
|
let mut path = PathBuf::from(&self_location);
|
||||||
if *debug_mode
|
path.push(location);
|
||||||
{
|
self.forge_folder(self_location.clone(), debug_mode);
|
||||||
println!("{:#?} ", handshake);
|
self.location = Some(path.to_str().unwrap().to_string());
|
||||||
}
|
|
||||||
let size = String::from_utf8(handshake.clone()).unwrap().parse().unwrap();
|
|
||||||
handshake.push(b'\n');
|
|
||||||
self.send_exact(&handshake.as_slice(), stream, debug_mode);
|
|
||||||
size
|
|
||||||
}
|
}
|
||||||
None =>
|
None =>
|
||||||
{
|
{
|
||||||
println!("Error: Handshake -> {}", self.location);
|
self.location = Some(location);
|
||||||
0
|
}
|
||||||
|
}
|
||||||
|
match File::create(self.location.as_ref().unwrap())
|
||||||
|
{
|
||||||
|
Ok(file) =>
|
||||||
|
{
|
||||||
|
if *debug_mode
|
||||||
|
{
|
||||||
|
println!("Done Forge File -> {:#?}", file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err_val) =>
|
||||||
|
{
|
||||||
|
println!("Error: Forge File -> {:#?} | Error: {}", self.location.as_ref(), err_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn forge_folder(&mut self, location:String, debug_mode:&bool)
|
||||||
|
{
|
||||||
|
match fs::create_dir_all(&location)
|
||||||
|
{
|
||||||
|
Ok(_) =>
|
||||||
|
{
|
||||||
|
if *debug_mode
|
||||||
|
{
|
||||||
|
println!("Done: Forge Folder -> {}", &location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err_val) =>
|
||||||
|
{
|
||||||
|
println!("Error: Forge Folder -> {} | Error: {}", location, err_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn callback_recv(&mut self, stream:&mut TcpStream, debug_mode:&bool) -> String
|
||||||
|
{
|
||||||
|
match self.recv_until(stream, '\n', debug_mode)
|
||||||
|
{
|
||||||
|
Some(mut callback) =>
|
||||||
|
{
|
||||||
|
|
||||||
|
if *debug_mode
|
||||||
|
{
|
||||||
|
println!("Done: Callback -> {:#?}", self.location);
|
||||||
|
println!("{:#?} ", callback);
|
||||||
|
}
|
||||||
|
let data = String::from_utf8(callback.clone()).unwrap();
|
||||||
|
callback.push(b'\n');
|
||||||
|
self.send_exact(&callback.as_slice(), stream, debug_mode);
|
||||||
|
data
|
||||||
|
}
|
||||||
|
None =>
|
||||||
|
{
|
||||||
|
println!("Error: Callback -> {:#?}", self.location);
|
||||||
|
panic!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn save_exact(&mut self, buffer:&[u8], debug_mode:&bool)
|
fn save_exact(&mut self, buffer:&[u8], debug_mode:&bool)
|
||||||
{
|
{
|
||||||
let mut file_writer = BufWriter::new(self.file.as_ref().unwrap());
|
let mut file_writer = BufWriter::new(self.file.as_ref().unwrap());
|
||||||
|
if *debug_mode
|
||||||
|
{
|
||||||
|
println!("{:#?}", file_writer);
|
||||||
|
}
|
||||||
match file_writer.write_all(buffer)
|
match file_writer.write_all(buffer)
|
||||||
{
|
{
|
||||||
Ok(_) =>
|
Ok(_) =>
|
||||||
{
|
{
|
||||||
if *debug_mode
|
if *debug_mode
|
||||||
{
|
{
|
||||||
println!("Done: Write -> {} | {} bytes", self.location, self.size_current);
|
println!("Done: Write -> {} | {} bytes", self.location.as_ref().unwrap(), self.size_current);
|
||||||
println!("{:#?}", buffer);
|
println!("{:#?}", buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err_val) =>
|
Err(err_val) =>
|
||||||
{
|
{
|
||||||
println!("Error: Write -> {} | Error: {}", self.location,err_val);
|
println!("Error: Write -> {} | Error: {}", self.location.as_ref().unwrap(),err_val);
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,23 +475,58 @@ impl FileInfo
|
||||||
{
|
{
|
||||||
if *debug_mode
|
if *debug_mode
|
||||||
{
|
{
|
||||||
println!("Done: Flush -> {}", self.location);
|
println!("Done: Flush -> {}", self.location.as_ref().unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err_val) =>
|
Err(err_val) =>
|
||||||
{
|
{
|
||||||
println!("Error: Flush -> {} | Error: {}", self.location,err_val);
|
println!("Error: Flush -> {} | Error: {}", self.location.as_ref().unwrap(),err_val);
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn write_file(&mut self, stream:&mut TcpStream, debug_mode:&bool)
|
fn write_file(&mut self, stream:&mut TcpStream, debug_mode:&bool)
|
||||||
{
|
{
|
||||||
let size = self.handshake_recv(stream, debug_mode);
|
let what_type:u8 = self.callback_recv(stream, debug_mode).parse().unwrap();
|
||||||
let mut iteration:u64 = (size/BUFFER_SIZE)+1;
|
self.size_total = self.callback_recv(stream, debug_mode).parse().unwrap();
|
||||||
|
let location:String = self.callback_recv(stream, debug_mode);
|
||||||
|
match what_type
|
||||||
|
{
|
||||||
|
100 =>
|
||||||
|
{
|
||||||
|
if *debug_mode
|
||||||
|
{
|
||||||
|
println!("Done: Symlink Detected -> {}", self.location.as_ref().unwrap());
|
||||||
|
}
|
||||||
|
self.forge_file( location, debug_mode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
101 =>
|
||||||
|
{
|
||||||
|
if *debug_mode
|
||||||
|
{
|
||||||
|
println!("Done: File Detected -> {}", self.location.as_ref().unwrap());
|
||||||
|
}
|
||||||
|
self.forge_file(location, debug_mode);
|
||||||
|
}
|
||||||
|
102 =>
|
||||||
|
{
|
||||||
|
if *debug_mode
|
||||||
|
{
|
||||||
|
println!("Done: Folder Detected -> {}", self.location.as_ref().unwrap());
|
||||||
|
}
|
||||||
|
self.forge_file(location, debug_mode);
|
||||||
|
}
|
||||||
|
_ =>
|
||||||
|
{
|
||||||
|
println!("Error: Undefined Type -> {}", self.location.as_ref().unwrap());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.open_file(debug_mode);
|
||||||
|
let mut iteration:u64 = (&self.size_total/BUFFER_SIZE)+1;
|
||||||
let total_iteration = iteration;
|
let total_iteration = iteration;
|
||||||
println!("Size = {}", size);
|
self.show_info(&iteration, debug_mode);
|
||||||
println!("Iteration = {}", iteration);
|
|
||||||
while iteration != 0
|
while iteration != 0
|
||||||
{
|
{
|
||||||
iteration -= 1;
|
iteration -= 1;
|
||||||
|
@ -304,37 +538,34 @@ impl FileInfo
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
self.save_exact(&buffer[..(size%BUFFER_SIZE) as usize], debug_mode);
|
self.save_exact(&buffer[..(&self.size_total%BUFFER_SIZE) as usize], debug_mode);
|
||||||
}
|
}
|
||||||
println!("%{}", 100 as f64 -((iteration as f64/total_iteration as f64)*100 as f64));
|
self.show_progress(iteration, total_iteration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn show_info(&mut self, iteration:&u64, debug_mode:&bool)
|
||||||
|
{
|
||||||
|
println!("File = {}", self.location.as_ref().unwrap());
|
||||||
|
println!("Size = {}", self.size_total);
|
||||||
|
if *debug_mode
|
||||||
|
{
|
||||||
|
println!("Iteration = {}", iteration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn show_progress(&mut self, iteration:u64, total_iteration:u64)
|
||||||
|
{
|
||||||
|
if iteration%10 == 0
|
||||||
|
{
|
||||||
|
let progress:u8 = 100 as u8 - ((iteration as f64/total_iteration as f64)*100 as f64)as u8;
|
||||||
|
if progress != self.progress
|
||||||
|
{
|
||||||
|
self.progress = progress;
|
||||||
|
println!("%{}", self.progress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
enum DebugMode
|
|
||||||
{
|
|
||||||
On,
|
|
||||||
Off
|
|
||||||
}
|
|
||||||
impl DebugMode {
|
|
||||||
fn debug_mode(self) -> bool
|
|
||||||
{
|
|
||||||
match self
|
|
||||||
{
|
|
||||||
DebugMode::On =>
|
|
||||||
{
|
|
||||||
println!("Debug: ON");
|
|
||||||
let debug = true;
|
|
||||||
debug
|
|
||||||
}
|
|
||||||
DebugMode::Off =>
|
|
||||||
{
|
|
||||||
println!("Debug: OFF");
|
|
||||||
let debug = false;
|
|
||||||
debug
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enum Connection
|
enum Connection
|
||||||
{
|
{
|
||||||
Server(String, String),
|
Server(String, String),
|
||||||
|
@ -343,9 +574,14 @@ enum Connection
|
||||||
|
|
||||||
impl Connection
|
impl Connection
|
||||||
{
|
{
|
||||||
fn server(self, file_info:&mut FileInfo, debug_mode:bool)
|
fn server(self, file_info:&mut FileInfo, user_environment:&UserEnvironment)
|
||||||
{
|
{
|
||||||
print!("Server -> ");
|
print!("Server -> ");
|
||||||
|
if user_environment.debug
|
||||||
|
{
|
||||||
|
println!("{:#?}", user_environment);
|
||||||
|
println!("{:#?}", file_info);
|
||||||
|
}
|
||||||
let ip:String;
|
let ip:String;
|
||||||
let port:String;
|
let port:String;
|
||||||
let address:String;
|
let address:String;
|
||||||
|
@ -368,7 +604,7 @@ impl Connection
|
||||||
Ok(mut stream) =>
|
Ok(mut stream) =>
|
||||||
{
|
{
|
||||||
println!("Connected");
|
println!("Connected");
|
||||||
send_or_receive(file_info, &mut stream, &debug_mode);
|
send_or_receive(file_info, &mut stream, &user_environment.debug, user_environment);
|
||||||
}
|
}
|
||||||
Err(e) =>
|
Err(e) =>
|
||||||
{
|
{
|
||||||
|
@ -378,9 +614,14 @@ impl Connection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn client(self, file_info:&mut FileInfo, debug_mode:bool)
|
fn client(self, file_info:&mut FileInfo, user_environment:&UserEnvironment)
|
||||||
{
|
{
|
||||||
print!("Client -> ");
|
print!("Client -> ");
|
||||||
|
if user_environment.debug
|
||||||
|
{
|
||||||
|
println!("{:#?}", user_environment);
|
||||||
|
println!("{:#?}", file_info);
|
||||||
|
}
|
||||||
let ip:String;
|
let ip:String;
|
||||||
let port:String;
|
let port:String;
|
||||||
let address:String;
|
let address:String;
|
||||||
|
@ -400,7 +641,7 @@ impl Connection
|
||||||
Ok(mut stream) =>
|
Ok(mut stream) =>
|
||||||
{
|
{
|
||||||
println!("Connected");
|
println!("Connected");
|
||||||
send_or_receive(file_info, &mut stream, &debug_mode);
|
send_or_receive(file_info, &mut stream, &user_environment.debug, user_environment);
|
||||||
}
|
}
|
||||||
Err(e) =>
|
Err(e) =>
|
||||||
{
|
{
|
||||||
|
@ -410,94 +651,141 @@ impl Connection
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn send_or_receive(file_info:&mut FileInfo, stream:&mut TcpStream, debug_mode:&bool)
|
fn send_or_receive(file_info:&mut FileInfo, stream:&mut TcpStream, debug_mode:&bool, user_environment:&UserEnvironment)
|
||||||
{
|
{
|
||||||
match &take_string("Input: Send 's', Receive 'r'".to_string())[..1]
|
match user_environment.send
|
||||||
{
|
{
|
||||||
"s" =>
|
true =>
|
||||||
{
|
{
|
||||||
println!("Connected");
|
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
FileInfo::reading_operations(file_info, stream, &debug_mode);
|
FileInfo::reading_operations(file_info, stream, &debug_mode);
|
||||||
let finish_time = Instant::now();
|
let finish_time = Instant::now();
|
||||||
|
println!("Done: Transfer");
|
||||||
println!("Passed: Total -> {:#?}", finish_time.duration_since(start_time));
|
println!("Passed: Total -> {:#?}", finish_time.duration_since(start_time));
|
||||||
}
|
}
|
||||||
"r" =>
|
false =>
|
||||||
{
|
{
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
FileInfo::writing_operations(file_info, stream, &debug_mode);
|
FileInfo::writing_operations(file_info, stream, &debug_mode);
|
||||||
let finish_time = Instant::now();
|
let finish_time = Instant::now();
|
||||||
|
println!("Done: Transfer");
|
||||||
println!("Passed: Total -> {:#?}", finish_time.duration_since(start_time));
|
println!("Passed: Total -> {:#?}", finish_time.duration_since(start_time));
|
||||||
}
|
}
|
||||||
input =>
|
|
||||||
{
|
|
||||||
println!("Error: Give Valid Input, You Gave : {}", input);
|
|
||||||
panic!() }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn take_string(output:String) -> String
|
fn take_args(mut user_environment:UserEnvironment) -> Option<UserEnvironment>
|
||||||
{
|
{
|
||||||
let mut input = String::new();
|
let env_args:Vec<String> = env::args().collect();
|
||||||
println!("{}", output);
|
if env_args.len() > 16
|
||||||
io::stdin().read_line(&mut input).expect("Error: Failed to Read from Console");
|
{
|
||||||
input
|
println!("Error: Too Many Arguments, You Gave {} Arguments", env_args.len());
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let mut i = 1;
|
||||||
|
while i < env_args.len()
|
||||||
|
{
|
||||||
|
match env_args[i].as_str()
|
||||||
|
{
|
||||||
|
"--ip" | "-i" =>
|
||||||
|
{
|
||||||
|
user_environment.ip = env_args[i+1].parse().unwrap();
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
"--port" | "-p" =>
|
||||||
|
{
|
||||||
|
user_environment.port = env_args[i+1].parse().unwrap();
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
"--location" | "-l" =>
|
||||||
|
{
|
||||||
|
user_environment.location = Some(env_args[i+1].parse().unwrap());
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
"--server"| "-sv" =>
|
||||||
|
{
|
||||||
|
user_environment.server = true;
|
||||||
|
}
|
||||||
|
"--client" | "-cl" =>
|
||||||
|
{
|
||||||
|
user_environment.server = false;
|
||||||
|
}
|
||||||
|
"--send" | "-s" =>
|
||||||
|
{
|
||||||
|
user_environment.send = true;
|
||||||
|
}
|
||||||
|
"--receive" | "-r" =>
|
||||||
|
{
|
||||||
|
user_environment.send = false;
|
||||||
|
}
|
||||||
|
"--debug" | "-d" =>
|
||||||
|
{
|
||||||
|
user_environment.debug = true;
|
||||||
|
}
|
||||||
|
"--help" | "-h" =>
|
||||||
|
{
|
||||||
|
show_help();
|
||||||
|
return None;
|
||||||
|
|
||||||
|
}
|
||||||
|
err =>
|
||||||
|
{
|
||||||
|
println!("Error: Invalid Argument, You Gave {}", err);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
Some(user_environment)
|
||||||
}
|
}
|
||||||
fn take_arg() -> String
|
fn show_help()
|
||||||
{
|
{
|
||||||
env::args().last().as_deref().unwrap_or("default").to_string()
|
println!("\n\n\n");
|
||||||
}
|
println!(" Arguments | Details | Defaults");
|
||||||
fn debug_mod() -> DebugMode
|
println!("----------------------------------------------------------------------");
|
||||||
{
|
println!(" -i -> --ip | Specifies IP Address | 127.0.0.1");
|
||||||
match &take_string("Input: Debug -> On '1', Debug -> Off '0'".to_string())[0..1]
|
println!(" -p -> --port | Specifies Port Address | 2121");
|
||||||
{
|
println!(" -l -> --location | Specifies Location Address | Same as Program");
|
||||||
"1" =>
|
println!(" -sv -> --server | Starts as a Server | False");
|
||||||
{
|
println!(" -cl -> --client | Starts as a Client | True");
|
||||||
DebugMode::On
|
println!(" -s -> --send | Starts as a Sender | False");
|
||||||
}
|
println!(" -r -> --receive | Starts as a Receiver | True");
|
||||||
"0" =>
|
println!(" -d -> --debug | Starts in Debug Mode | False");
|
||||||
{
|
println!(" -h -> --help | Shows Help | False");
|
||||||
DebugMode::Off
|
println!("\n\n\n");
|
||||||
}
|
|
||||||
input =>
|
|
||||||
{
|
|
||||||
println!("Error: Give Valid Input, You Gave : {}", input);
|
|
||||||
panic!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fn main()
|
fn main()
|
||||||
{
|
{
|
||||||
//DONT FORGET
|
//DONT FORGET
|
||||||
//First we should check folder structure and validation then make connection.
|
//First we should check folder structure and validation then make connection.
|
||||||
|
//Until's can be deprecated, 100k byte should be enough for eveything.(Security)
|
||||||
println!("Hello, world!");
|
println!("Hello, world!");
|
||||||
|
let mut file_info:FileInfo = FileInfo::file_info();
|
||||||
let mut data = FileInfo
|
let user_environment:UserEnvironment;
|
||||||
|
match take_args(UserEnvironment::user_environment())
|
||||||
{
|
{
|
||||||
file:None,
|
Some(usr_env) =>
|
||||||
location:take_arg(),
|
|
||||||
size_current:0 as usize,
|
|
||||||
metadata:None,
|
|
||||||
};
|
|
||||||
match &take_string("Input: Server 's', Client 'c'".to_string())[0..1]
|
|
||||||
{
|
|
||||||
"s" =>
|
|
||||||
{
|
{
|
||||||
Connection::server
|
user_environment = usr_env;
|
||||||
(Connection::Server(take_string("Input: Server Stream IP Address".to_string()),
|
|
||||||
take_string("Input: Server Stream Port Address".to_string())),
|
|
||||||
&mut data, DebugMode::debug_mode(debug_mod()));
|
|
||||||
},
|
|
||||||
"c" =>
|
|
||||||
{
|
|
||||||
Connection::client
|
|
||||||
(Connection::Client(take_string("Input: Server IP Address to Connect".to_string()),
|
|
||||||
take_string("Input: Server Port Address to Connect".to_string())),
|
|
||||||
&mut data, DebugMode::debug_mode(debug_mod()));
|
|
||||||
}
|
}
|
||||||
input =>
|
None =>
|
||||||
{
|
{
|
||||||
println!("Error: Give Valid Input, You Gave : {}", input);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
file_info.pass_user_environment(&user_environment);
|
||||||
|
match user_environment.server
|
||||||
|
{
|
||||||
|
true =>
|
||||||
|
{
|
||||||
|
Connection::server
|
||||||
|
(Connection::Server(user_environment.ip.to_string(), user_environment.port.to_string()),
|
||||||
|
&mut file_info, &user_environment);
|
||||||
|
},
|
||||||
|
false =>
|
||||||
|
{
|
||||||
|
Connection::client
|
||||||
|
(Connection::Client(user_environment.ip.to_string(), user_environment.port.to_string()),
|
||||||
|
&mut file_info, &user_environment);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue