(rust) PathBuf push() behaviour

This commit is contained in:
2025-06-24 19:26:51 +02:00
parent 2b52a3d949
commit 1acb77331b
2 changed files with 23 additions and 185 deletions
-4
View File
@@ -7,11 +7,7 @@ edition = "2021"
anyhow = "1.0"
chrono = "0.4.41"
clap = { version = "4.5.0", features = ["derive"] }
ctrlc = "3.4"
dirs = "5.0.1"
sqlx = { version = "0.8", features = [ "runtime-tokio", "sqlite", "chrono" ] }
thiserror = "2.0.12"
tokio = { version = "1.42.0", features = ["full", "rt"] }
prost = "0.13"
proto = { path = "proto" }
+21 -179
View File
@@ -1,198 +1,40 @@
#![allow(dead_code, unused)]
use chrono::{DateTime, Local};
use prost::{DecodeError, EncodeError, Message};
use proto::protest::*;
use tokio::{
use std::{
fs,
io::{AsyncReadExt, AsyncWriteExt},
net::{TcpListener, TcpStream},
time::{sleep, Duration},
path::PathBuf,
};
use dirs::config_dir;
const BLOCK_SIZE: usize = 1024;
const TIMEOUT_LIMIT: usize = 32;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let listener = TcpListener::bind("127.0.0.1:9090").await?;
let mut file = fs::read("../lorem.md").await?;
println!("filesize = {}", file.len());
tokio::spawn(async move {
let mut connection = TcpStream::connect("127.0.0.1:9090").await.unwrap();
let blocks = if 0 == file.len() % BLOCK_SIZE {
file.len() / BLOCK_SIZE
} else {
file.len() / BLOCK_SIZE + 1
};
let mut index = 0;
println!("blocks = {blocks}");
loop {
let mut buffer = vec![0u8; BLOCK_SIZE + 1024];
let data: Vec<u8> = if file.len() > BLOCK_SIZE {
file.drain(0..BLOCK_SIZE).collect()
} else {
file.drain(..).collect()
};
index += 1;
if index > blocks {
panic!("something went horribly wrong, index ({index}) > blocks ({blocks}), remaining filesize = {}", file.len());
}
println!("sending index = {}", index);
let frame = Payload {
index: index as u64,
blocks: blocks as u64,
payload: data,
let mut path: PathBuf = match config_dir() {
Some(value) => value,
None => return Err(anyhow::Error::msg("no configuration directory for you")),
};
let length = encode_with_length(&frame, &mut buffer).unwrap();
_ = connection.write_all(&buffer[0..length]).await;
if index == blocks {
break;
}
sleep(Duration::from_millis(1)).await;
}
});
match listener.accept().await {
Ok((mut stream, address)) => {
let mut output = Vec::<u8>::new();
let mut buffer = [0u8; BLOCK_SIZE + 1024];
let mut vector: Vec<u8> = Vec::new();
let mut timeout_counter: usize = 0;
'receive: loop {
loop {
let num = stream.read(&mut buffer[..]).await.unwrap();
if num != 0 {
vector.extend(buffer[0..num].iter());
if timeout_counter > 0 {
timeout_counter -= 1;
}
break;
}
timeout_counter += 1;
if timeout_counter > TIMEOUT_LIMIT {
println!("\n\n[[ TIMEOUT ]]\n\n");
break 'receive;
}
sleep(Duration::from_millis(100)).await;
}
let mut delimiter = prost::decode_length_delimiter(&vector[..]).unwrap();
delimiter += prost::length_delimiter_len(delimiter);
let payload = Payload::decode_length_delimited(&vector[0..delimiter]).unwrap();
_ = vector.drain(0..delimiter);
println!("-- receiving index = {}, delimiter = {}", payload.index, delimiter);
output.extend(payload.payload.iter());
if payload.index == payload.blocks {
break;
}
sleep(Duration::from_millis(1)).await;
}
_ = fs::write("./lorem-copy.md", output).await?;
}
Err(error) => {
println!("this is unexpected.. {}", error.to_string());
}
}
check_path(&path);
path.push("navigate");
check_path(&path);
path.push("bookmarks");
check_path(&path);
path.push("default.toml");
check_path(&path);
Ok(())
}
async fn receive_file(stream: &mut TcpStream) -> Result<Vec<u8>, anyhow::Error> {
const BUFFER_SIZE: usize = 4096;
let mut buffer = [0u8; BUFFER_SIZE];
let mut index_counter: usize = 0;
let mut processing_buffer = Vec::<u8>::new();
let mut file = Vec::<u8>::new();
let mut size: usize = 0;
loop {
let num_bytes = stream.read(&mut buffer[..]).await?;
processing_buffer.extend(&buffer[0..num_bytes]);
if 0 == index_counter {
size = usize::from_be_bytes(
processing_buffer
.drain(0..8)
.collect::<Vec<_>>()
.try_into()
.unwrap(),
);
fn check_path(path: &PathBuf) {
if path.is_dir() {
println!("[{:#?}] is a valid `DIRECTORY`", path);
} else if path.is_file() {
println!("[{:#?}] is a valid `FILE`", path);
} else if path.exists() {
println!("[{:#?}] is a valid `ENTITY`", path);
} else {
_ = processing_buffer.drain(0..8);
println!("[{:#?}] is `NOT` a valid path", path);
}
let block_size = usize::from_be_bytes(
processing_buffer
.drain(0..8)
.collect::<Vec<_>>()
.try_into()
.unwrap(),
);
let index = usize::from_be_bytes(
processing_buffer
.drain(0..8)
.collect::<Vec<_>>()
.try_into()
.unwrap(),
);
if index_counter != index {
panic!("meh, counter = {index_counter}, index = {index}");
}
file.extend(processing_buffer.drain(0..block_size));
index_counter += 1;
if block_size >= size {
break;
} else {
size -= block_size;
}
}
Ok(file)
}
async fn send_file(stream: &mut TcpStream, mut file: Vec<u8>) -> Result<(), anyhow::Error> {
const BLOCK_SIZE: usize = 2048;
let size: usize = file.len();
let mut remaining = size;
let mut index: usize = 0;
while remaining > 0 {
let mut block = Vec::<u8>::new();
let len = if remaining >= BLOCK_SIZE {
BLOCK_SIZE
} else {
remaining
};
block.extend(size.to_be_bytes());
block.extend(len.to_be_bytes());
block.extend(index.to_be_bytes());
block.extend(file.drain(0..len));
stream.write(&block[..]).await?;
remaining -= len;
index += 1;
}
Ok(())
}
fn encode_with_length(message: &impl Message, buffer: &mut Vec<u8>) -> Result<usize, EncodeError> {
let mut length = message.encoded_len();
length += prost::length_delimiter_len(length);
message.encode_length_delimited(&mut &mut buffer[0..length])?;
Ok(length)
}