summaryrefslogtreecommitdiff
path: root/client/src/download.rs
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/download.rs')
-rw-r--r--client/src/download.rs58
1 files changed, 58 insertions, 0 deletions
diff --git a/client/src/download.rs b/client/src/download.rs
new file mode 100644
index 0000000..256c25c
--- /dev/null
+++ b/client/src/download.rs
@@ -0,0 +1,58 @@
+use anyhow::Result;
+use std::collections::HashSet;
+use weareshared::{
+ packets::{Packet, Resource},
+ store::{ResourceStore, sha256},
+};
+
+use crate::network::Network;
+
+pub struct Downloader {
+ have: HashSet<Resource>,
+ need: HashSet<Resource>,
+ pending: HashSet<Resource>,
+ 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<Option<Vec<u8>>> {
+ 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);
+ }
+}