From 8b91a26409b8d85e1a39e37172b17a2ce98c462d Mon Sep 17 00:00:00 2001 From: Avril Date: Sun, 9 Aug 2020 20:05:45 +0100 Subject: [PATCH] start async prog --- Cargo.lock | 20 ++++++++ Cargo.toml | 4 +- src/.#progress.rs | 1 + src/ext.rs | 26 ++++++++++ src/main.rs | 6 +++ src/progress.rs | 48 +++++++++++++++++++ src/task_list.rs | 118 ++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 222 insertions(+), 1 deletion(-) create mode 120000 src/.#progress.rs create mode 100644 src/ext.rs create mode 100644 src/progress.rs create mode 100644 src/task_list.rs diff --git a/Cargo.lock b/Cargo.lock index 9b00544..3abaf26 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -182,6 +182,7 @@ dependencies = [ "futures", "lazy_static", "rustc_version", + "termprogress", "tokio", ] @@ -428,6 +429,25 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "terminal_size" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a14cd9f8c72704232f0bfc8455c0e861f0ad4eb60cc9ec8a170e231414c1e13" +dependencies = [ + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "termprogress" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdac4acf3a5e8889b18583692fcae227f0dacc42c6714696cf6b424ecac51aa6" +dependencies = [ + "terminal_size", +] + [[package]] name = "tokio" version = "0.2.22" diff --git a/Cargo.toml b/Cargo.toml index 399b05f..912a870 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,8 +8,9 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] -default = ["splash"] +default = ["splash", "progress"] +progress = ["termprogress"] threads = ["tokio/rt-threaded"] splash = [] @@ -17,6 +18,7 @@ splash = [] lazy_static = "1.4" tokio = {version = "0.2", features= ["rt-core", "rt-util", "macros", "fs", "io-driver", "io-util", "io-std", "process", "sync", "stream"]} futures = "0.3" +termprogress = {version="0.2", optional=true} [build-dependencies] rustc_version = "0.2" diff --git a/src/.#progress.rs b/src/.#progress.rs new file mode 120000 index 0000000..5d9d145 --- /dev/null +++ b/src/.#progress.rs @@ -0,0 +1 @@ +avril@flan-laptop.204627:1596751578 \ No newline at end of file diff --git a/src/ext.rs b/src/ext.rs new file mode 100644 index 0000000..78bc335 --- /dev/null +++ b/src/ext.rs @@ -0,0 +1,26 @@ +pub trait JoinStrsExt: Sized +{ + /// Join an iterator of `str` with a seperator + fn join(self, with: &str) -> String; +} + +impl JoinStrsExt for I +where I: Iterator, + T: AsRef +{ + fn join(self, with: &str) -> String + { + let mut output = String::new(); + let mut first=true; + for string in self + { + if !first { + output.push_str(with); + } + let string = string.as_ref(); + output.push_str(string); + first=false; + } + output + } +} diff --git a/src/main.rs b/src/main.rs index 291e92f..2747854 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,10 @@ #![cfg_attr(nightly, feature(int_error_matching))] +#![cfg_attr(nightly, feature(linked_list_remove))] #![allow(dead_code)] +mod ext; +pub use ext::JoinStrsExt as _; #[cfg(feature="splash")] mod splash; @@ -17,6 +20,9 @@ mod fixed_stack; mod process; mod work; +#[cfg(feature="progress")] mod task_list; +#[cfg(feature="progress")] mod progress; + async fn work() -> Result<(), Box> { let args = arg::parse_args().await.with_prefix("failed to parse args")?; diff --git a/src/progress.rs b/src/progress.rs new file mode 100644 index 0000000..d0ef75a --- /dev/null +++ b/src/progress.rs @@ -0,0 +1,48 @@ +use super::*; +use std::{ + iter::FromIterator as _, +}; +use tokio::{ + sync::{ + oneshot, + watch, + }, + task::{ + self, + JoinHandle, + }, +}; +use termprogress::{ + Display as _, + WithTitle, + ProgressBar, +}; + +#[derive(Debug)] +enum CommandKind +{ + +} + +#[derive(Debug)] +pub struct Command +{ + comm: CommandKind, + comp: oneshot::Sender<()>, +} + +#[derive(Debug, Clone)] +pub struct ProgressSender +{ + shutdown: watch::Receiver>, +} + +/// Create the async progress counter and return a sender object and a handle to join the worker task. +pub async fn create_progress>(high: usize, tasks: I) -> (ProgressSender, JoinHandle<()>) +{ + let list = task_list::TaskList::from_iter(tasks); + let mut progress = P::with_title(50, &list); + + todo!() +} diff --git a/src/task_list.rs b/src/task_list.rs new file mode 100644 index 0000000..158558b --- /dev/null +++ b/src/task_list.rs @@ -0,0 +1,118 @@ +use super::*; +use std::iter::FromIterator; + +#[cfg(nightly)] type ListAbs = std::collections::LinkedList; +#[cfg(not(nightly))] type ListAbs = Vec; + +#[derive(Debug)] +pub struct TaskList { + list: ListAbs<(usize, String)>, + buffer: String, + index: usize, +} + +fn find(list: &ListAbs, mut fun: F) -> Option +where F: FnMut(&T) -> bool +{ + for (i,x) in (0..).zip(list.iter()) + { + if fun(x) { + return Some(i); + } + } + None +} + +impl TaskList +{ + /// Create a new tasklist + pub fn new() -> Self + { + Self { + list: ListAbs::new(), + buffer: String::new(), + index: 0, + } + } + + /// Number of tasks in the list + pub fn len(&self) -> usize + { + self.list.len() + } + + /// Push a new task string, and return its ID. + pub fn push(&mut self, string: impl Into) -> usize + { + let idx = { + self.index+=1; + self.index + }; + #[cfg(nightly)] self.list.push_front((idx,string.into())); + #[cfg(not(nightly))] self.list.push((idx,string.into())); + + self.recalc(); + idx + } + + /// Pop a task off the string, returns `true` if successful, `false` if wasn't found. + pub fn pop(&mut self, idx: usize) -> bool + { + if let Some(idx) = find(&self.list, |&(i, _)| idx == i) + { + self.list.remove(idx); + self.recalc(); + true + } else { + false + } + } + + /// Clear the `TaskList` + pub fn clear(&mut self) + { + self.list.clear(); + self.buffer = String::default(); + } + + /// As a single `str` + pub fn as_str(&self) -> &str + { + &self.buffer[..] + } + + fn recalc(&mut self) + { + #[cfg(nightly)] { + self.buffer = self.list.iter().map(|(_, s)| s.as_str()).join(", "); + } + #[cfg(not(nightly))] { + self.buffer = self.list.iter().rev().map(|(_, s)| s.as_str()).join(", "); + } + } +} + +impl AsRef for TaskList +{ + #[inline] fn as_ref(&self) -> &str + { + self.as_str() + } +} + +impl FromIterator for TaskList + where T: Into +{ + fn from_iter>(iter: I) -> Self + { + let mut i=0usize; + let mut this = Self { + list: iter.into_iter().map(|x| ((i, x.into()), i+=1).0).collect(), + buffer: Default::default(), + index: 0, + }; + this.index = i; + this.recalc(); + this + } +}