tidying up

This commit is contained in:
Love 2023-02-28 16:22:53 +01:00
parent 2419592f22
commit 19031035a1
3 changed files with 43 additions and 33 deletions

View File

@ -10,6 +10,8 @@ use indicatif::{ProgressBar, ProgressState, ProgressStyle};
use reqwest::{self, Client};
use std::cmp;
use crate::get_mut_ref;
pub enum DualWriter {
File(File),
Buffer(Vec<u8>),
@ -38,14 +40,14 @@ impl DualWriter {
let mut buf = String::new();
// Well this is safe since I consume the file anyways
let ptr = &file as *const File as *mut File;
let file = unsafe { &mut *ptr };
let file = unsafe { get_mut_ref(&file) };
file.read_to_string(&mut buf)
.or(Err("Failed to read file".to_owned()))?;
buf
}
})
}
pub fn new(file_name: Option<&str>) -> Result<Self, io::Error> {
Ok(if let Some(file_name) = file_name {
Self::File(File::create(&file_name)?)
@ -59,7 +61,7 @@ pub async fn download_with_progress(
link: &str,
file_name: Option<&str>,
) -> Result<DualWriter, String> {
let mut dw = DualWriter::new(file_name).or(Err("Failed to create file".to_owned()))?;
let mut dual_writer = DualWriter::new(file_name).or(Err("Failed to create file".to_owned()))?;
let client = Client::builder()
.gzip(true)
@ -71,14 +73,14 @@ pub async fn download_with_progress(
.send()
.await
.or(Err("Failed to connect server".to_owned()))?;
let content_length = if let Some(s) = resp.content_length() {
s
let content_length = if let Some(got_content_length) = resp.content_length() {
got_content_length
} else {
panic!("Could not retrive content length from server. {:?}", &resp);
};
let pb = ProgressBar::new(content_length);
pb.set_style(ProgressStyle::with_template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta})").unwrap()
let progress_bar = ProgressBar::new(content_length);
progress_bar.set_style(ProgressStyle::with_template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta})").unwrap()
.with_key("eta", |state: &ProgressState, w: &mut dyn fmt::Write| write!(w, "{:.1}s", state.eta().as_secs_f64()).unwrap())
.progress_chars("#>-"));
@ -88,11 +90,12 @@ pub async fn download_with_progress(
while let Some(item) = stream.next().await {
let bytes = item.unwrap();
downloaded = cmp::min(downloaded + (bytes.len() as u64), content_length);
dw.write(bytes)
dual_writer
.write(bytes)
.or(Err("Failed to write to file".to_owned()))?;
pb.set_position(downloaded);
progress_bar.set_position(downloaded);
}
Ok(dw)
Ok(dual_writer)
}

View File

@ -63,3 +63,13 @@ impl<'a> Readline<'a> {
buffer
}
}
/**
* I know that this isn't considered true rusty code, but the places it's used in is
* safe. For this I'll leave the funciton as unsafe, so to better see it's uses.
* This solution makes the uses BLAZINGLY FAST which moreover is the most rusty you can get.
*/
pub unsafe fn get_mut_ref<T>(reference: &T) -> &mut T {
let ptr = reference as *const T as *mut T;
&mut *ptr
}

View File

@ -3,7 +3,7 @@ use std::process::Command;
use std::rc::Rc;
use colored::Colorize;
use iptvnator::{download_with_progress, setup, M3u8, Parser, Readline};
use iptvnator::{download_with_progress, get_mut_ref, setup, M3u8, Parser, Readline};
#[tokio::main]
async fn main() {
@ -52,7 +52,7 @@ async fn main() {
}
search_result = Some(Rc::new(parser.find(search)));
if search_result.as_ref().unwrap().len() == 0 {
if search_result.as_ref().unwrap().is_empty() {
println!("Nothing found");
continue;
}
@ -95,8 +95,8 @@ async fn main() {
// Downloadmode
"d" => {
let to_download =
ask_which_to_download(&mut readline, search_result.as_ref().unwrap().clone());
download_m3u8(to_download).await;
ask_which_to_download(&mut readline, &search_result.as_ref().unwrap());
download_m3u8(&to_download).await;
}
_ => {}
}
@ -104,8 +104,8 @@ async fn main() {
let choosen = user_wish.parse::<usize>();
match choosen {
Ok(k) => {
let search_result = search_result.as_ref().unwrap().clone();
stream(&(search_result[k - 1]), mpv_fs);
let search_result = search_result.as_ref().unwrap();
stream(search_result[k - 1], mpv_fs);
parser.save_watched();
}
Err(e) => println!("Have to be a valid number! {:?}", e),
@ -115,7 +115,7 @@ async fn main() {
fn ask_which_to_download<'a>(
readline: &mut Readline,
search_result: Rc<Vec<&'a M3u8>>,
search_result: &Rc<Vec<&'a M3u8>>,
) -> Rc<Vec<&'a M3u8>> {
let selections = loop {
// Ask for userinput
@ -155,17 +155,7 @@ fn ask_which_to_download<'a>(
)
}
/*
* I know that this is also frowned upon, but it is perfectly safe right here,
* even though the borrowchecker complains
*/
async fn refresh(parser: &Parser) {
let ptr = parser as *const Parser as *mut Parser;
let p = unsafe { &mut *ptr };
p.forcefully_update().await;
}
async fn download_m3u8(files_to_download: Rc<Vec<&M3u8>>) {
async fn download_m3u8(files_to_download: &Vec<&M3u8>) {
for m3u8 in files_to_download.iter() {
let file_ending_place = m3u8.link.rfind(".").unwrap();
let potential_file_ending = &m3u8.link[file_ending_place..];
@ -183,14 +173,13 @@ async fn download_m3u8(files_to_download: Rc<Vec<&M3u8>>) {
}
/**
* This function uses unsafe code to change an atribute, and while I know that this is not
* how youre supposed to do things, it's perfectly safe in this context and also the most efficient way.
* I know that this is not how youre supposed to do things, but it's perfectly safe
* in this context and also the most efficient way.
* With other words, it's BLAZINGLY FAST
*/
fn stream(m3u8item: &M3u8, launch_in_fullscreen: bool) {
let ptr = m3u8item as *const M3u8 as *mut M3u8;
let mut item = unsafe { &mut *ptr };
item.watched = true;
let mut m3u8item = unsafe { get_mut_ref(m3u8item) };
m3u8item.watched = true;
let mut args: Vec<&str> = vec![&m3u8item.link];
if launch_in_fullscreen {
args.push("--fs");
@ -201,3 +190,11 @@ fn stream(m3u8item: &M3u8, launch_in_fullscreen: bool) {
.output()
.expect("Could not listen for output");
}
/*
* I know that this is also frowned upon, but it is perfectly safe right here,
* even though the borrowchecker complains
*/
async fn refresh(parser: &Parser) {
unsafe { get_mut_ref(parser) }.forcefully_update().await;
}