1use std::path::Path;
4
5use anyhow::anyhow;
6use tokio_util::sync::CancellationToken;
7use wdl_analysis::Document;
8use wdl_engine::EvaluatedTask;
9use wdl_engine::EvaluationError;
10use wdl_engine::EvaluationResult;
11use wdl_engine::Events;
12use wdl_engine::Inputs;
13use wdl_engine::Outputs;
14use wdl_engine::config::Config;
15use wdl_engine::v1::TaskEvaluator;
16use wdl_engine::v1::WorkflowEvaluator;
17
18use crate::inputs::OriginPaths;
19
20pub struct Evaluator<'a> {
22 document: &'a Document,
24
25 name: &'a str,
27
28 inputs: Inputs,
30
31 origins: OriginPaths,
33
34 config: Config,
36
37 output_dir: &'a Path,
39}
40
41impl<'a> Evaluator<'a> {
42 pub fn new(
44 document: &'a Document,
45 name: &'a str,
46 inputs: Inputs,
47 origins: OriginPaths,
48 config: Config,
49 output_dir: &'a Path,
50 ) -> Self {
51 Self {
52 document,
53 name,
54 inputs,
55 origins,
56 config,
57 output_dir,
58 }
59 }
60
61 pub async fn run(
63 mut self,
64 token: CancellationToken,
65 events: Events,
66 ) -> EvaluationResult<Outputs> {
67 match self.inputs {
68 Inputs::Task(ref mut inputs) => {
69 let task = self.document.task_by_name(self.name).ok_or_else(|| {
70 anyhow!(
71 "document does not contain a task named `{name}`",
72 name = self.name
73 )
74 })?;
75
76 inputs.join_paths(task, |key| {
79 self.origins
80 .get(key)
81 .ok_or(anyhow!("unable to find origin path for key `{key}`"))
82 })?;
83
84 let evaluator = TaskEvaluator::new(self.config, token, events).await?;
85
86 evaluator
87 .evaluate(self.document, task, inputs, self.output_dir)
88 .await
89 .and_then(EvaluatedTask::into_result)
90 }
91 Inputs::Workflow(mut inputs) => {
92 let workflow = self
93 .document
94 .workflow()
95 .ok_or_else(|| anyhow!("document does not contain a workflow"))?;
96
97 if workflow.name() != self.name {
98 return Err(EvaluationError::Other(anyhow!(
99 "document does not contain a workflow named `{name}`",
100 name = self.name
101 )));
102 }
103
104 inputs.join_paths(workflow, |key| {
107 self.origins
108 .get(key)
109 .ok_or(anyhow!("unable to find origin path for key `{key}`"))
110 })?;
111
112 let evaluator = WorkflowEvaluator::new(self.config, token, events).await?;
113 evaluator
114 .evaluate(self.document, inputs, self.output_dir)
115 .await
116 }
117 }
118 }
119}