parent
6a2570a0c4
commit
88defc530e
@ -0,0 +1,140 @@
|
||||
//! Tasklist for progressbar
|
||||
use super::*;
|
||||
use std::{
|
||||
collections::LinkedList,
|
||||
fmt,
|
||||
error,
|
||||
};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
|
||||
#[repr(transparent)]
|
||||
pub struct TaskId(Uuid);
|
||||
|
||||
impl fmt::Display for TaskId
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
||||
{
|
||||
write!(f, "<{}>", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// A list of tasks
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TaskList
|
||||
{
|
||||
tasks: LinkedList<(Uuid, String)>,
|
||||
|
||||
strbuf: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for TaskList
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
||||
{
|
||||
write!(f, "{}", self.strbuf)
|
||||
}
|
||||
}
|
||||
|
||||
impl TaskList
|
||||
{
|
||||
/// The current full string
|
||||
pub fn as_str(&self) -> &str
|
||||
{
|
||||
self.strbuf.as_str()
|
||||
}
|
||||
|
||||
/// Create a new, empty tasklist
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self{tasks:LinkedList::new(), strbuf:String::new()}
|
||||
}
|
||||
|
||||
fn recalc_buf(&mut self)
|
||||
{
|
||||
self.strbuf = self.tasks.iter().map(|(_, stri)| stri.as_str()).join(", ");
|
||||
}
|
||||
|
||||
fn push_buf_one(&mut self, task: &str)
|
||||
{
|
||||
if self.strbuf.len() > 0 {
|
||||
self.strbuf.push_str(", ");
|
||||
}
|
||||
self.strbuf.push_str(task)
|
||||
}
|
||||
|
||||
/// Add a task to the end of the list
|
||||
pub fn add(&mut self, task: String) -> TaskId
|
||||
{
|
||||
let id = Uuid::new_v4();
|
||||
|
||||
self.push_buf_one(&task[..]);
|
||||
self.tasks.push_back((id.clone(), task));
|
||||
|
||||
TaskId(id)
|
||||
}
|
||||
|
||||
/// Remove all tasks
|
||||
pub fn clear(&mut self)
|
||||
{
|
||||
self.tasks.clear();
|
||||
self.strbuf.clear();
|
||||
}
|
||||
|
||||
/// An iterator over all tasks currently in
|
||||
pub fn tasks(&self) -> impl Iterator<Item = &'_ str> + '_
|
||||
{
|
||||
self.tasks.iter().map(|(_, strs)| strs.as_str())
|
||||
}
|
||||
|
||||
/// Remove this task from the list, returning its string if it exists
|
||||
pub fn remove(&mut self, task_id: &TaskId) -> Result<String, IdNotFoundError>
|
||||
{
|
||||
let value = match self.tasks.drain_filter(|(id, _)| id==&task_id.0).next() {
|
||||
Some((_, string)) => string,
|
||||
None => return Err(IdNotFoundError(TaskId(task_id.0.clone()))),
|
||||
};
|
||||
self.recalc_buf();
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
/// Get this task ID's string
|
||||
pub fn task_get(&self, task_id: &TaskId)-> Option<&str>
|
||||
{
|
||||
self.tasks.iter().filter(|(id, _)| id == &task_id.0).next().map(|x| x.1.as_str())
|
||||
}
|
||||
|
||||
/// Replace this task ID with this string, retuning the old one.
|
||||
pub fn task_set(&mut self, task_id: &TaskId, value: impl Into<String>) -> Result<String, IdNotFoundError>
|
||||
{
|
||||
let old = match self.tasks.iter_mut().filter(|(id, _)| id == &task_id.0).next().map(|x| &mut x.1) {
|
||||
Some(string) => std::mem::replace(string, value.into()),
|
||||
None => return Err(IdNotFoundError(TaskId(task_id.0.clone()))),
|
||||
};
|
||||
self.recalc_buf();
|
||||
Ok(old)
|
||||
}
|
||||
}
|
||||
|
||||
/// Error when trying to remove a non-existent ID.
|
||||
#[derive(Debug)]
|
||||
pub struct IdNotFoundError(TaskId);
|
||||
|
||||
impl IdNotFoundError
|
||||
{
|
||||
/// Get the ID that was not found
|
||||
pub fn id(&self) -> &TaskId
|
||||
{
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for IdNotFoundError{}
|
||||
impl fmt::Display for IdNotFoundError
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
||||
{
|
||||
write!(f, "{}: unknown ID to this TaskList", self.0)
|
||||
}
|
||||
}
|
Loading…
Reference in new issue