use std::ops::Deref; use std::sync::{Arc}; use chrono::{Duration, Local}; use tokio::sync::{RwLock, RwLockReadGuard}; use tokio::time::sleep; use crate::{SharedData}; use crate::post_history::{PostHistory, PostHistoryInner}; pub(crate) async fn run<'a>(shared_data: Arc<RwLock<SharedData>>) { let mut min_len_series: u32 = 0; let mut min_len_slug: u32 = 0; println!("TUI restarted"); loop { let snapshot_data = shared_data.read().await; sleep(Duration::milliseconds(250).to_std().unwrap()).await; print_info(snapshot_data, &mut min_len_series, &mut min_len_slug).await; } } async fn print_info<'a>(data: RwLockReadGuard<'a, SharedData>, min_len_series: &mut u32, min_len_slug: &mut u32) { let mut local_min_len_series = *min_len_series.deref() as usize; let mut local_min_len_slug = *min_len_slug.deref() as usize; let separator_width = local_min_len_slug + local_min_len_series + 44; // 44 should account for length of every other string print!("\x1B[2J\x1B[1;1H"); println!( "##[Ascendance of a Bookworm Bot]## | Time: {}", Local::now().naive_local().format("%H:%M:%S") ); println!("Instance: {}", data.config.instance); println!( "Ran Last: {} | Config Reload Interval: {}", data .start .with_timezone(&Local) .naive_local() .format("%d/%m/%Y %H:%M:%S"), data.config.config_reload_seconds ); println!("{:#<1$}", "", separator_width); let mut sorted_series: Vec<(&String, &PostHistory)> = data.post_history.series.iter().collect(); sorted_series.sort_by(|(a, _), (b, _)| a.cmp(b)); sorted_series.iter().for_each(|(series, post_history)| { if series.len() > local_min_len_series { local_min_len_series = series.len() + 1; *min_len_series = local_min_len_series as u32; } let series_config = data.config.series .iter() .find(|ser| {&&ser.slug == series}) .expect("Config should not parse without this"); let mut sorted_parts: Vec<(&String, &PostHistoryInner)> = post_history.parts.iter().collect(); sorted_parts.sort_by(|(a, _), (b, _)| a.cmp(b)); sorted_parts.iter().for_each(|(part, part_history)| { if part_history.volume.len() > local_min_len_slug { local_min_len_slug = part_history.chapter.len() + 1; *min_len_slug = local_min_len_slug as u32; } print!("{series}"); print!("{:<1$}| ", "", local_min_len_series - series.len()); print!("Part {part}"); print!("{:<1$}| Volume | ", "", 2-part.len()); print!("{}", part_history.volume); print!("{:<1$}| ", "", local_min_len_slug - part_history.volume.len()); print!("{}", series_config.volume_community.name); println!("{:<1$}|", "", 20 - series_config.volume_community.name.len()); if part_history.chapter.len() > local_min_len_slug { local_min_len_slug = part_history.chapter.len() + 1; *min_len_slug = local_min_len_slug as u32; } print!("{series}"); print!("{:<1$}| ", "", local_min_len_series - series.len()); print!("Part {part}"); print!("{:<1$}| Chapter | ", "", 2-part.len()); print!("{}", part_history.chapter); print!("{:<1$}| ", "", local_min_len_slug - part_history.chapter.len()); print!("{}", series_config.prepub_community.name); println!("{:<1$}|", "", 20 - series_config.prepub_community.name.len()); }); }); println!("{:#<1$}", "", separator_width); for error in data.get_messages(true, true, false).iter() { println!("{}", error.content()); } println!("{:#<1$}", "", separator_width); for message in data.get_messages(false, false, true).iter() { println!("{}", message.content()); } }