chord_flow/flow/case/
arg.rs

1use std::fmt::{Display, Formatter};
2use std::sync::Arc;
3
4use chord_core::case::CaseId;
5use chord_core::collection::TailDropVec;
6use chord_core::flow::Flow;
7use chord_core::step::{StepAsset, StepState};
8use chord_core::task::TaskId;
9use chord_core::value::Map;
10use chord_core::value::Value;
11
12use crate::flow::step::{action_asset_to_value, StepRunner};
13use crate::flow::step::arg::ArgStruct;
14use crate::flow::step::res::StepAssetStruct;
15use crate::model::app::App;
16use crate::model::app::RenderContext;
17
18#[derive(Clone)]
19pub struct CaseIdStruct {
20    task_id: Arc<dyn TaskId>,
21    stage_id: Arc<String>,
22    exec_id: Arc<String>,
23    case: String,
24}
25
26impl CaseIdStruct {
27    pub fn new(
28        task_id: Arc<dyn TaskId>,
29        stage_id: Arc<String>,
30        exec_id: Arc<String>,
31        case_id: String,
32    ) -> CaseIdStruct {
33        CaseIdStruct {
34            task_id,
35            stage_id,
36            exec_id,
37            case: case_id,
38        }
39    }
40}
41
42impl CaseId for CaseIdStruct {
43    fn case(&self) -> &str {
44        self.case.as_str()
45    }
46
47    fn exec_id(&self) -> &str {
48        self.exec_id.as_str()
49    }
50
51    fn stage_id(&self) -> &str {
52        self.stage_id.as_str()
53    }
54
55    fn task_id(&self) -> &dyn TaskId {
56        self.task_id.as_ref()
57    }
58}
59
60impl Display for CaseIdStruct {
61    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
62        f.write_str(
63            format!(
64                "{}-{}-{}-{}",
65                self.task_id, self.stage_id, self.exec_id, self.case
66            )
67            .as_str(),
68        )
69    }
70}
71
72pub struct CaseArgStruct {
73    flow: Arc<Flow>,
74    step_vec: Arc<TailDropVec<(String, StepRunner)>>,
75    id: Arc<CaseIdStruct>,
76    data: Value,
77    render_ctx: RenderContext,
78}
79
80impl CaseArgStruct {
81    pub fn new(
82        flow: Arc<Flow>,
83        step_vec: Arc<TailDropVec<(String, StepRunner)>>,
84        data: Value,
85        pre_ctx: Option<Arc<Map>>,
86        def_ctx: Option<Arc<Map>>,
87        task_id: Arc<dyn TaskId>,
88        stage_id: Arc<String>,
89        case_exec_id: Arc<String>,
90        case_id: String,
91    ) -> CaseArgStruct {
92        let id = Arc::new(CaseIdStruct::new(task_id, stage_id, case_exec_id, case_id));
93
94        let mut render_data: Map = Map::new();
95        render_data.insert("__meta__".to_owned(), Value::Object(flow.meta().clone()));
96        if let Some(def_ctx) = def_ctx {
97            render_data.insert(String::from("def"), Value::Object(def_ctx.as_ref().clone()));
98        }
99        render_data.insert(String::from("case"), data.clone());
100        if let Some(pre_ctx) = pre_ctx.as_ref() {
101            render_data.insert(String::from("pre"), Value::Object(pre_ctx.as_ref().clone()));
102        }
103        if !render_data.contains_key("step") {
104            render_data.insert(String::from("step"), Value::Object(Map::new()));
105        }
106
107        let render_ctx = RenderContext::wraps(render_data).unwrap();
108        return CaseArgStruct {
109            flow,
110            step_vec,
111            id,
112            data,
113            render_ctx,
114        };
115    }
116
117    pub fn step_vec(self: &CaseArgStruct) -> Arc<TailDropVec<(String, StepRunner)>> {
118        self.step_vec.clone()
119    }
120
121    pub fn step_arg_create<'app>(
122        self: &CaseArgStruct,
123        step_id: &str,
124        flow_app: &'app dyn App,
125    ) -> ArgStruct<'app, '_> {
126        ArgStruct::new(
127            flow_app,
128            self.flow.as_ref(),
129            self.render_ctx.clone(),
130            self.id.clone(),
131            step_id.to_owned(),
132        )
133    }
134
135    pub async fn step_asset_register(&mut self, sid: &str, step_asset: &StepAssetStruct) {
136        if let StepState::Ok(av) = step_asset.state() {
137            if let Value::Object(reg) = self.render_ctx.data_mut() {
138                let mut am = Map::new();
139                for a in av.iter() {
140                    am.insert(a.id().to_string(), action_asset_to_value(a.as_ref()));
141                }
142                reg["step"][sid] = Value::Object(am);
143            }
144        }
145    }
146
147    pub fn id(&self) -> Arc<CaseIdStruct> {
148        self.id.clone()
149    }
150
151    pub fn take_data(self) -> Value {
152        self.data
153    }
154}