use anyhow::Result; use std::collections::HashSet; use weareshared::{ packets::{Packet, Resource}, store::{ResourceStore, sha256}, }; use crate::network::Network; pub struct Downloader { have: HashSet, need: HashSet, pending: HashSet, store: ResourceStore, } impl Downloader { pub fn new(store: ResourceStore) -> Self { Self { have: HashSet::new(), need: HashSet::new(), pending: HashSet::new(), store, } } pub fn try_get(&mut self, hash: Resource) -> Result>> { if self.have.contains(&hash) { self.store.get(hash) } else { self.need.insert(hash); Ok(None) } } pub fn packet(&mut self, p: &Packet) -> Result<()> { match p { Packet::RespondResource(d) => { let key = Resource(sha256(&d)); self.store.set(&d)?; self.need.remove(&key); self.pending.remove(&key); self.have.insert(key); } _ => (), } Ok(()) } pub fn update(&mut self, network: &mut Network) { let mut new_pending = Vec::new(); for n in self.need.difference(&self.pending) { network .packet_send .send(Packet::RequestResource(*n)) .unwrap(); new_pending.push(*n); } self.pending.extend(new_pending); } }