parsli 0.1.2

Parallel status lines for Rust
Documentation
use std::collections::{HashMap, HashSet};
use std::sync::Arc;
use crate::Line;
use crate::Ctx;


type TaskArgs<S> = (Line, String, Ctx<S>, );
type TaskOutput<S> = Result<S, String>;

pub trait TaskFn<S> = Fn<TaskArgs<S>, Output=TaskOutput<S>> + Send + Sync + 'static;

pub type TaskId = usize;

#[derive(Clone)]
pub struct Task<S> {
    inner: Arc<dyn TaskFn<S>>,
}

impl<S> Task<S> {
    pub fn new<F>(f: F) -> Self where F: TaskFn<S> {
        Self { inner: Arc::new(f) }
    }
}

impl<S> FnOnce<TaskArgs<S>> for Task<S> {
    type Output = TaskOutput<S>;

    extern "rust-call" fn call_once(self, args: TaskArgs<S>) -> Self::Output {
        self.inner.as_ref().call_once(args)
    }
}

impl<S> FnMut<TaskArgs<S>> for Task<S> {
    extern "rust-call" fn call_mut(&mut self, args: TaskArgs<S>) -> Self::Output {
        self.inner.as_ref().call_mut(args)
    }
}

impl<S> Fn<TaskArgs<S>> for Task<S> {
    extern "rust-call" fn call(&self, args: TaskArgs<S>) -> Self::Output {
        self.inner.as_ref().call(args)
    }
}

#[derive(Clone)]
pub struct TaskMgr<S> {
    tasks: HashMap<TaskId, Task<S>>,
    deps: HashMap<TaskId, HashSet<TaskId>>,
}

impl<S> TaskMgr<S> {
    pub fn new() -> Self {
        Self { tasks: HashMap::default(), deps: Default::default() }
    }

    pub fn get(&self, id: TaskId) -> Option<&Task<S>> {
        self.tasks.get(&id)
    }

    pub fn get_deps(&self, id: TaskId) -> Option<&HashSet<TaskId>> {
        self.deps.get(&id)
    }

    pub fn insert(&mut self, id: TaskId, task: Task<S>) {
        self.tasks.insert(id, task);
    }

    pub fn insert_dep(&mut self, id: TaskId, dep: TaskId) {
        let entry = self.deps.entry(id).or_insert_with(|| HashSet::default());
        entry.insert(dep);
    }

    pub fn insert_deps(&mut self, id: TaskId, deps: HashSet<TaskId>) {
        let entry = self.deps.entry(id).or_insert_with(|| HashSet::default());
        entry.extend(deps);
    }

    pub fn insert_with_deps(&mut self, id: TaskId, deps: HashSet<TaskId>, task: Task<S>) {
        self.deps.insert(id, deps);
        self.tasks.insert(id, task);
    }
}