use crate::{cat_thread::Page, catalog::Catalog, thread::Thread, Dot4chClient, Update, Result};
use async_trait::async_trait;
use log::info;
use std::{
collections::HashMap,
io::{self, Write},
};
#[derive(Debug)]
pub struct Board {
pub threads: HashMap<u32, Thread>,
pub(crate) board: String,
pub(crate) client: Dot4chClient,
}
impl Board {
pub async fn build(client: &Dot4chClient, board: &str) -> Result<Board> {
writeln!(io::stdout(), "Building Board! Please wait.")?;
let catalog = Catalog::new(client, board).await?;
let ids: Vec<_> = catalog
.all_pages()
.into_iter()
.flat_map(Page::threads)
.map(|thread| thread.id())
.collect();
info!("Number of threads: {}", ids.len());
let mut threads = vec![];
for (idx, id) in ids.iter().enumerate() {
threads.push(Thread::new(client, board, *id).await?);
info!("Pushed Thread: {}/{}", idx + 1, ids.len());
}
let threads: Vec<_> = threads.into_iter().zip(ids).collect();
let mut id_thread_zip = HashMap::new();
for (thread, num) in threads {
id_thread_zip.insert(num, thread);
}
Ok(Self {
threads: id_thread_zip,
board: board.to_string(),
client: client.clone(),
})
}
pub fn get(&self, k: u32) -> Option<&'_ Thread> {
self.threads.get(&k)
}
pub fn insert(&mut self, id: u32, thread: Thread) -> Option<Thread> {
self.threads.insert(id, thread)
}
pub fn board(&self) -> &str {
&self.board
}
}
#[async_trait(?Send)]
impl Update for Board {
type Output = Self;
async fn update(mut self) -> Result<Self::Output> {
info!("Updating Board. Please wait..");
let catalog = Catalog::new(&self.client, &self.board).await?;
let ids: Vec<_> = catalog
.all_pages()
.into_iter()
.flat_map(Page::threads)
.map(|thread| thread.id())
.collect();
let mut threads = vec![];
for (num, (id, thread)) in self.threads.into_iter().enumerate() {
threads.push(thread.update().await?);
info!(
"Updating thread: {}\t Threads updated: {}/{}",
id,
(num + 1),
&ids.len()
);
}
let mut id_thread_zip = HashMap::new();
let threads: Vec<_> = threads.into_iter().zip(ids).collect();
for (thread, num) in threads {
id_thread_zip.insert(num, thread);
}
info!("Finished updating threads!");
Ok(Self {
threads: id_thread_zip,
board: self.board,
client: self.client,
})
}
}