1use crate::exception::BuildResult;
2use crate::project::Project;
3
4use parking_lot::RwLock;
5use std::error::Error;
6use std::fmt::{Debug, Display, Formatter};
7use std::sync::Arc;
8
9use crate::identifier::TaskId;
10
11use crate::project::buildable::BuiltByContainer;
12
13pub mod action;
14mod any_task;
15pub mod create_task;
16mod executable;
17pub mod flags;
18pub mod initialize_task;
19mod lazy_task;
20pub mod task_container;
21pub mod task_executor;
22pub mod task_io;
23mod task_ordering;
24pub mod up_to_date;
25pub mod work_handler;
26
27use crate::project::error::ProjectResult;
28use crate::task::flags::{OptionDeclarations, OptionsDecoder};
29use crate::task::up_to_date::UpToDate;
30pub use any_task::AnyTaskHandle;
31use create_task::CreateTask;
32pub use executable::{force_rerun, Executable};
33use initialize_task::InitializeTask;
34pub use lazy_task::*;
35use task_io::TaskIO;
36
37pub use task_ordering::*;
38
39#[derive(Debug, Clone)]
41pub enum TaskOutcome {
42 Executed,
44 Skipped,
46 UpToDate,
48 NoSource,
50 Failed,
52}
53
54pub trait Task: UpToDate + InitializeTask + CreateTask + TaskIO + Sized + Debug {
55 fn did_work(&self) -> bool {
59 true
60 }
61
62 fn task_action(_task: &mut Executable<Self>, _project: &Project) -> BuildResult;
64}
65
66pub trait HasTaskId {
68 fn task_id(&self) -> TaskId;
70}
71
72pub trait BuildableTask: HasTaskId {
77 fn built_by(&self) -> BuiltByContainer {
79 let mut output = BuiltByContainer::new();
80 for task_ordering in self.ordering() {
81 match task_ordering.ordering_kind() {
82 TaskOrderingKind::DependsOn => {
83 output.add(task_ordering.buildable().clone());
84 }
85 _ => {}
86 }
87 }
88 output
89 }
90
91 fn ordering(&self) -> Vec<TaskOrdering>;
96}
97
98pub trait ExecutableTask: HasTaskId + Send + Sync {
100 fn options_declarations(&self) -> Option<OptionDeclarations>;
102
103 fn try_set_from_decoder(&mut self, decoder: &OptionsDecoder) -> ProjectResult<()>;
105
106 fn execute(&mut self, project: &Project) -> BuildResult;
108
109 fn did_work(&self) -> bool;
111 fn task_up_to_date(&self) -> bool;
113
114 fn group(&self) -> String;
116
117 fn description(&self) -> String;
119}
120
121assert_obj_safe!(ExecutableTask);
122
123pub trait FullTask: BuildableTask + ExecutableTask + Send + Sync {}
125
126impl Debug for Box<dyn FullTask> {
127 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
128 write!(f, "Task {}", self.task_id())
129 }
130}
131
132impl Display for Box<dyn FullTask> {
133 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
134 write!(f, "Task {}", self.task_id())
135 }
136}
137
138impl HasTaskId for Box<dyn FullTask> {
139 fn task_id(&self) -> TaskId {
140 (**self).task_id()
141 }
142}
143
144impl ExecutableTask for Box<dyn FullTask> {
145 fn options_declarations(&self) -> Option<OptionDeclarations> {
146 (**self).options_declarations()
147 }
148
149 fn try_set_from_decoder(&mut self, decoder: &OptionsDecoder) -> ProjectResult<()> {
150 (**self).try_set_from_decoder(decoder)
151 }
152
153 fn execute(&mut self, project: &Project) -> BuildResult {
154 (**self).execute(project)
155 }
156
157 fn did_work(&self) -> bool {
158 (**self).did_work()
159 }
160
161 fn task_up_to_date(&self) -> bool {
162 (**self).task_up_to_date()
163 }
164
165 fn group(&self) -> String {
166 (**self).group()
167 }
168
169 fn description(&self) -> String {
170 (**self).description()
171 }
172}
173
174impl<E: ExecutableTask> HasTaskId for Arc<RwLock<E>> {
175 fn task_id(&self) -> TaskId {
176 self.read().task_id()
177 }
178}
179
180impl<E: ExecutableTask + Send + Sync> ExecutableTask for Arc<RwLock<E>> {
181 fn options_declarations(&self) -> Option<OptionDeclarations> {
182 self.read().options_declarations()
183 }
184
185 fn try_set_from_decoder(&mut self, decoder: &OptionsDecoder) -> ProjectResult<()> {
186 self.write().try_set_from_decoder(decoder)
187 }
188
189 fn execute(&mut self, project: &Project) -> BuildResult {
190 self.write().execute(project)
191 }
192
193 fn did_work(&self) -> bool {
194 self.read().did_work()
195 }
196
197 fn task_up_to_date(&self) -> bool {
198 self.read().task_up_to_date()
199 }
200
201 fn group(&self) -> String {
202 self.read().group()
203 }
204
205 fn description(&self) -> String {
206 self.read().description()
207 }
208}
209
210impl Debug for Box<dyn FullTask + Send + Sync> {
211 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
212 write!(f, "Task {}", self.task_id())
213 }
214}
215
216impl Display for Box<dyn FullTask + Send + Sync> {
217 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
218 write!(f, "Task {}", self.task_id())
219 }
220}
221
222impl<F: BuildableTask + ExecutableTask> FullTask for F {}
223
224assert_obj_safe!(FullTask);