diff --git a/src/ext.rs b/src/ext.rs new file mode 100644 index 0000000..63f971d --- /dev/null +++ b/src/ext.rs @@ -0,0 +1,80 @@ +use super::*; +use std::iter::{ + FusedIterator, + Fuse, +}; + +pub struct HexStringIter +{ + ar: Fuse, + hex1: u8, +} + +impl From> for String +where I: Iterator, + I::Item: Into +{ + #[inline] fn from(from: HexStringIter) -> Self + { + from.collect() + } +} + +const fn gen_hex_table() -> [(u8, u8); 256] +{ + let mut res = [(0, 0); 256]; + let mut i =0; + const HEX: &'static [u8] = b"0123456789abcdef"; + while i < 256 { + let by = i as u8; + res[i] = (HEX[(by >> 4) as usize], HEX[(by & 0xf) as usize]); + i+=1; + } + res +} + +static HEX_TABLE: [(u8, u8); 256] = gen_hex_table(); + +impl Iterator for HexStringIter +where I: Iterator, + I::Item: Into +{ + type Item = char; + fn next(&mut self) -> Option + { + if self.hex1 != 0 { + return Some(std::mem::replace(&mut self.hex1, 0) as char); + } + let by = self.ar.next()?.into(); + let (h0, h1) = HEX_TABLE[by as usize]; + self.hex1 = h1; + Some(h0 as char) + } + fn size_hint(&self) -> (usize, Option) { + let (s, l) = self.ar.size_hint(); + (s * 2, l.map(|x| x*2)) + } +} +impl ExactSizeIterator for HexStringIter +where I: Iterator + ExactSizeIterator, + I::Item: Into{} +impl FusedIterator for HexStringIter +where I: Iterator, + I::Item: Into{} + +pub trait HexStringIterExt: Sized +{ + fn hex_string(self) -> HexStringIter; +} + +impl HexStringIterExt for I +where I: IntoIterator, + I::Item: Into +{ + #[inline] fn hex_string(self) -> HexStringIter { + HexStringIter { + ar: self.into_iter().fuse(), + hex1: 0, + } + } +} diff --git a/src/handle.rs b/src/handle.rs index 698942c..e8d119e 100644 --- a/src/handle.rs +++ b/src/handle.rs @@ -163,9 +163,15 @@ where C: Future + 'static + Unpin + Send eprintln!("Got file: {:?}", path); - let mut file = OpenOptions::new() + let mut file = match OpenOptions::new() .read(true) - .open(&path).await.unwrap(); + .open(&path).await { + Ok(v) => v, + Err(e) => { + let _ = ret.send((path, Err(e))).await; + return; + }, + }; eprintln!("Opened file {:?}",path); let mut hasher = Sha256::new(); let ring_res = uring_read(&mut file, |buffer| { @@ -200,11 +206,12 @@ where C: Future + 'static + Unpin + Send ]; }); - //Yield the current task to allow the newly spawned one to acquire the semaphore. - //XXX: Is this a safe way of passing the semaphore to the task? - tokio::task::yield_now().await; } + //Yield the current task to allow the newly spawned one to run. + //XXX: Is this a safe way of passing the semaphore to the task? + tokio::task::yield_now().await; // --- End of new inputs + //XXX: FUUUUUUUCK why can't i just acquire_owned() without using Arc? Fucking hell... //let _sem = sem.as_ref().map(|x| x.try_acquire_many(x.available_permits() as u32).unwrap()); @@ -222,10 +229,8 @@ where C: Future + 'static + Unpin + Send if let Some(sem) = &sem { sem.close(); } - drop(_sem); drop(sem); }); }); ReceiverStream::new(r_rx) } -//TODO: Higher-level wrapper around `file_handler()` diff --git a/src/main.rs b/src/main.rs index 5c474a7..a672905 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use std::convert::Infallible; use std::path::PathBuf; +mod ext; use ext::*; mod handle; #[tokio::main] @@ -9,7 +10,7 @@ async fn main() { let (tx, mut rx) = handle::spawn(Default::default()); let _res = tokio::join![ tokio::spawn(async move { - for file in ["./src/main.rs", "./src/handle.rs"] + for file in ["./src/main.rs", "./src/handle.rs", "./target", "./tet", "./"] { eprintln!("Sending {}", file); tx.send(std::path::Path::new(file).into()).await.unwrap(); @@ -18,7 +19,7 @@ async fn main() { tokio::spawn(async move { use futures::prelude::*; while let Some((file, hash)) = rx.next().await { - println!("Got file hash for {:?}: {:?}", file, hash); + println!("Got file hash for {:?}: {:?}", file, hash.map(|x| x.as_ref().iter().copied().hex_string().collect::())); } }), ];