cmtool_assemble/generators/
artefact.rs1use crate::CMError;
4use cmtool_data::{
5 CMCase, CMCaseJson, CMCaseWriter, CMExportType, DEFAULT_CASE_FILE_NAME, PhaseCM, RawPhase,
6};
7use serde::{Deserialize, Serialize};
8use std::fmt;
9use std::path::PathBuf;
10
11#[derive(Serialize, Deserialize, Clone, Default)]
12pub struct GenerateContract {
13 case: CMCase,
14 liquid_phase: Option<RawPhase>,
15 gas_phase: Option<RawPhase>,
16 relative_path: Option<String>,
17}
18
19impl fmt::Debug for GenerateContract {
20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21 f.debug_struct("GenerateContract").finish()
22 }
23}
24
25fn format_path_case(relative_path: &Option<String>, file_name: &str) -> PathBuf {
26 relative_path
27 .as_ref()
28 .map(|rel| std::path::Path::new(&rel).join(file_name))
29 .unwrap_or_else(|| std::path::Path::new(file_name).to_path_buf())
30}
31
32impl GenerateContract {
33 pub fn get_case(&self) -> &CMCase {
34 &self.case
35 }
36
37 pub fn new_single_phase(case: CMCase, phase: RawPhase, relative_path: Option<String>) -> Self {
38 if phase.identifier == PhaseCM::Liquid {
39 Self {
40 case,
41 liquid_phase: Some(phase),
42 gas_phase: None,
43 relative_path,
44 }
45 } else {
46 Self {
47 case,
48 liquid_phase: None,
49 gas_phase: Some(phase),
50 relative_path,
51 }
52 }
53 }
54
55 pub fn new(
56 case: CMCase,
57 liquid_phase: RawPhase,
58 gas_phase: Option<RawPhase>,
59 relative_path: Option<String>,
60 ) -> Self {
61 Self {
62 case,
63 liquid_phase: Some(liquid_phase),
64 gas_phase,
65 relative_path,
66 }
67 }
68
69 fn write_phase(
70 dest: impl AsRef<std::path::Path>,
71 case: &mut CMCase,
72 phase: RawPhase,
73 relative_path: Option<String>,
74 ) -> Result<(), CMError> {
75 let (flowp, volumep) = phase.write(dest.as_ref().to_str().expect("utf path"))?;
76
77 let flowp = format_path_case(&relative_path, &flowp);
78 let volumep = format_path_case(&relative_path, &volumep);
79
80 case.add(
81 CMExportType::Flow(phase.identifier).into(),
82 flowp.to_str().expect("UTF-8 path"),
83 );
84 case.add(
85 CMExportType::Volume(phase.identifier).into(),
86 volumep.to_str().expect("UTF-8 path"),
87 );
88
89 Ok(())
90 }
91
92 fn prepare_fs(&self, root_dir: impl AsRef<std::path::Path>) -> Result<PathBuf, CMError> {
93 let path = if let Some(p) = &self.relative_path {
94 root_dir.as_ref().join(p)
95 } else {
96 root_dir.as_ref().to_owned()
97 };
98 std::fs::create_dir_all(&path)?; Ok(path)
100 }
101
102 pub fn write(mut self, root_dir: impl AsRef<std::path::Path>) -> Result<CMCase, CMError> {
103 if self.liquid_phase.is_none() && self.gas_phase.is_none() {
104 return Err(CMError::Custom("No phase to write".to_owned()));
105 }
106
107 let path = self.prepare_fs(&root_dir)?;
108
109 if let Some(liquid_phase) = self.liquid_phase {
110 Self::write_phase(
111 &path,
112 &mut self.case,
113 liquid_phase,
114 self.relative_path.clone(),
115 )?;
116 }
117
118 if let Some(gas_phase) = self.gas_phase {
119 Self::write_phase(path, &mut self.case, gas_phase, self.relative_path.clone())?;
120 }
121
122 let case_path = root_dir.as_ref().join(DEFAULT_CASE_FILE_NAME);
123 CMCaseJson::write_case(self.case.clone(), &case_path)?;
124
125 Ok(self.case)
126 }
127}