assemble_core/task/
task_container.rs1use crate::__export::TaskId;
2use crate::identifier::TaskIdFactory;
3
4use crate::project::error::{ProjectError, ProjectResult};
5use crate::project::shared::WeakSharedProject;
6use crate::task::any_task::AnyTaskHandle;
7use crate::task::lazy_task::TaskHandle;
8use crate::task::TaskHandleFactory;
9use crate::{Executable, Project, Task};
10use once_cell::sync::OnceCell;
11
12use crate::error::PayloadError;
13use crate::project::finder::TaskPath;
14use crate::project::shared::SharedProject;
15use itertools::Itertools;
16use std::collections::HashMap;
17use std::fmt::Debug;
18
19#[derive(Debug)]
20pub struct TaskContainer {
21 shared: OnceCell<WeakSharedProject>,
22 task_id_factory: TaskIdFactory,
23 handle_factory: OnceCell<TaskHandleFactory>,
24 mapping: HashMap<TaskId, AnyTaskHandle>,
25}
26
27impl TaskContainer {
28 pub fn new(id_factory: TaskIdFactory) -> Self {
31 Self {
32 shared: OnceCell::new(),
33 task_id_factory: id_factory,
34 handle_factory: OnceCell::new(),
35 mapping: HashMap::new(),
36 }
37 }
38
39 pub(crate) fn init(&mut self, project: &WeakSharedProject) {
41 self.shared
42 .set(project.clone())
43 .expect("shared already set");
44 self.handle_factory
45 .set(TaskHandleFactory::new(project.clone()))
46 .expect("factory already set");
47 }
48
49 #[inline]
50 fn handle_factory(&self) -> &TaskHandleFactory {
51 self.handle_factory
52 .get()
53 .expect("task handle should be set")
54 }
55
56 #[inline]
57 fn shared_project(&self) -> SharedProject {
58 let weak = self.shared.get().unwrap();
59 weak.clone().upgrade().expect("should be not weak")
60 }
61
62 pub fn register_task<T: Task + Send + Sync + Debug + 'static>(
63 &mut self,
64 id: &str,
65 ) -> ProjectResult<TaskHandle<T>> {
66 let id = self.task_id_factory.create(id).map_err(PayloadError::new)?;
67
68 if self.mapping.contains_key(&id) {
69 panic!("Task with id {} already registered", id);
70 }
71
72 let handle = self
73 .handle_factory()
74 .create_handle::<T>(id.clone())
75 .map_err(PayloadError::new)?;
76 let any_task_handle = AnyTaskHandle::new(handle.clone());
77 self.mapping.insert(id, any_task_handle);
78 Ok(handle)
79 }
80 pub fn register_task_with<
81 T: Task + Send + Sync + Debug + 'static,
82 F: 'static + Send + FnOnce(&mut Executable<T>, &Project) -> ProjectResult,
83 >(
84 &mut self,
85 id: &str,
86 config: F,
87 ) -> ProjectResult<TaskHandle<T>> {
88 let mut handle = self.register_task::<T>(id)?;
89 handle.configure_with(config)?;
90 Ok(handle)
91 }
92
93 pub fn get_tasks(&self) -> impl IntoIterator<Item = &TaskId> {
95 self.mapping.keys()
96 }
97
98 pub fn get_task(&self, id: &TaskId) -> Option<&AnyTaskHandle> {
100 self.mapping.get(id)
101 }
102}