Skip to content

Commit f31cb1b

Browse files
committed
feat: cleanup + Version check trait
1 parent cae5b07 commit f31cb1b

File tree

3 files changed

+145
-151
lines changed

3 files changed

+145
-151
lines changed

src/flow_definition/feature/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
pub mod version;
2+
13
use serde::Deserialize;
24
use tucana::shared::{DefinitionDataType, FlowType, RuntimeFunctionDefinition};
35

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
use tucana::shared::{DefinitionDataType, FlowType, RuntimeFunctionDefinition, Version};
2+
3+
pub trait HasVersion {
4+
fn version(&self) -> &Option<Version>;
5+
fn version_mut(&mut self) -> &mut Option<Version>;
6+
7+
fn normalize_version(&mut self) {
8+
self.version_mut().get_or_insert(Version {
9+
major: 0,
10+
minor: 0,
11+
patch: 0,
12+
});
13+
}
14+
15+
fn is_accepted(&self, filter: &Option<Version>) -> bool {
16+
filter
17+
.as_ref()
18+
.map_or(true, |v| self.version().as_ref() == Some(v))
19+
}
20+
}
21+
22+
impl HasVersion for DefinitionDataType {
23+
fn version(&self) -> &Option<Version> {
24+
&self.version
25+
}
26+
27+
fn version_mut(&mut self) -> &mut Option<Version> {
28+
&mut self.version
29+
}
30+
}
31+
32+
impl HasVersion for FlowType {
33+
fn version(&self) -> &Option<Version> {
34+
&self.version
35+
}
36+
37+
fn version_mut(&mut self) -> &mut Option<Version> {
38+
&mut self.version
39+
}
40+
}
41+
42+
impl HasVersion for RuntimeFunctionDefinition {
43+
fn version(&self) -> &Option<Version> {
44+
&self.version
45+
}
46+
47+
fn version_mut(&mut self) -> &mut Option<Version> {
48+
&mut self.version
49+
}
50+
}

src/flow_definition/mod.rs

Lines changed: 93 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ mod feature;
33

44
use crate::flow_definition::error::ReaderError;
55
use crate::flow_definition::feature::Feature;
6+
use crate::flow_definition::feature::version::HasVersion;
67
use serde::de::DeserializeOwned;
78
use std::fs;
89
use std::path::Path;
@@ -43,42 +44,31 @@ impl Reader {
4344
.map(|f| f.name.clone())
4445
.collect::<Vec<String>>()
4546
);
47+
4648
log::debug!(
4749
"Found FlowTypes {:?}",
4850
&features
4951
.iter()
50-
.map(|f| f
51-
.flow_types
52-
.iter()
53-
.map(|t| t.identifier.clone())
54-
.collect::<Vec<String>>())
55-
.flatten()
52+
.flat_map(|f| f.flow_types.iter().map(|t| t.identifier.clone()))
5653
.collect::<Vec<String>>()
5754
);
55+
5856
log::debug!(
5957
"Found DataTypes {:?}",
6058
&features
6159
.iter()
62-
.map(|f| f
63-
.data_types
64-
.iter()
65-
.map(|t| t.identifier.clone())
66-
.collect::<Vec<String>>())
67-
.flatten()
60+
.flat_map(|f| f.data_types.iter().map(|t| t.identifier.clone()))
6861
.collect::<Vec<String>>()
6962
);
63+
7064
log::debug!(
7165
"Found Functions {:?}",
7266
&features
7367
.iter()
74-
.map(|f| f
75-
.functions
76-
.iter()
77-
.map(|t| t.runtime_name.clone())
78-
.collect::<Vec<String>>())
79-
.flatten()
68+
.flat_map(|f| f.functions.iter().map(|t| t.runtime_name.clone()))
8069
.collect::<Vec<String>>()
8170
);
71+
8272
Ok(features)
8373
}
8474
Err(err) => {
@@ -93,16 +83,14 @@ impl Reader {
9383

9484
fn read_feature_content(&self, dir: &Path) -> Result<Vec<Feature>, ReaderError> {
9585
let mut features: Vec<Feature> = Vec::new();
96-
let readdir = match fs::read_dir(dir) {
97-
Ok(readdir) => readdir,
98-
Err(err) => {
99-
log::error!("Failed to read directory {}: {:?}", dir.display(), err);
100-
return Err(ReaderError::ReadDirectoryError {
101-
path: dir.to_path_buf(),
102-
error: err,
103-
});
86+
87+
let readdir = fs::read_dir(dir).map_err(|err| {
88+
log::error!("Failed to read directory {}: {:?}", dir.display(), err);
89+
ReaderError::ReadDirectoryError {
90+
path: dir.to_path_buf(),
91+
error: err,
10492
}
105-
};
93+
})?;
10694

10795
for entry_result in readdir {
10896
let entry = match entry_result {
@@ -115,139 +103,93 @@ impl Reader {
115103

116104
let path = entry.path();
117105

118-
if path.is_dir() {
119-
let feature_name = path
120-
.file_name()
121-
.unwrap_or_default()
122-
.to_string_lossy()
123-
.to_string();
124-
125-
if !self.accepted_features.is_empty()
126-
&& !self.accepted_features.contains(&feature_name)
127-
{
128-
log::info!("Skipping not accepted feature: {}", feature_name);
129-
continue;
130-
}
106+
if !path.is_dir() {
107+
continue;
108+
}
131109

132-
let data_types_path = path.join("data_type");
133-
let data_types: Vec<DefinitionDataType> =
134-
match self.collect_definitions::<DefinitionDataType>(&data_types_path) {
135-
Ok(types) => types
136-
.into_iter()
137-
.map(|mut f| {
138-
if f.version.is_none() {
139-
f.version = Some(Version {
140-
major: 0,
141-
minor: 0,
142-
patch: 0,
143-
});
144-
}
145-
f
146-
})
147-
.filter(|v| {
148-
if self.accepted_version.is_none() {
149-
return true;
150-
}
151-
152-
v.version == self.accepted_version
153-
})
154-
.collect(),
155-
Err(err) => {
156-
if self.should_break {
157-
return Err(ReaderError::ReadFeatureError {
158-
path: data_types_path.to_string_lossy().to_string(),
159-
source: Box::new(err),
160-
});
161-
} else {
162-
continue;
163-
}
164-
}
165-
};
166-
167-
let flow_types_path = path.join("flow_type");
168-
let flow_types: Vec<FlowType> =
169-
match self.collect_definitions::<FlowType>(&flow_types_path) {
170-
Ok(types) => types
171-
.into_iter()
172-
.map(|mut f| {
173-
if f.version.is_none() {
174-
f.version = Some(Version {
175-
major: 0,
176-
minor: 0,
177-
patch: 0,
178-
});
179-
}
180-
f
181-
})
182-
.filter(|v| {
183-
if self.accepted_version.is_none() {
184-
return true;
185-
}
186-
187-
v.version == self.accepted_version
188-
})
189-
.collect(),
190-
Err(err) => {
191-
if self.should_break {
192-
return Err(ReaderError::ReadFeatureError {
193-
path: flow_types_path.to_string_lossy().to_string(),
194-
source: Box::new(err),
195-
});
196-
} else {
197-
continue;
198-
}
199-
}
200-
};
201-
202-
let functions_path = path.join("runtime_definition");
203-
let functions =
204-
match self.collect_definitions::<RuntimeFunctionDefinition>(&functions_path) {
205-
Ok(func) => func
206-
.into_iter()
207-
.map(|mut f| {
208-
if f.version.is_none() {
209-
f.version = Some(Version {
210-
major: 0,
211-
minor: 0,
212-
patch: 0,
213-
});
214-
}
215-
f
216-
})
217-
.filter(|v| {
218-
if self.accepted_version.is_none() {
219-
return true;
220-
}
221-
222-
v.version == self.accepted_version
223-
})
224-
.collect(),
225-
Err(err) => {
226-
if self.should_break {
227-
return Err(ReaderError::ReadFeatureError {
228-
path: functions_path.to_string_lossy().to_string(),
229-
source: Box::new(err),
230-
});
231-
} else {
232-
continue;
233-
}
234-
}
235-
};
110+
let feature_name = path
111+
.file_name()
112+
.unwrap_or_default()
113+
.to_string_lossy()
114+
.to_string();
115+
116+
if !self.accepted_features.is_empty() && !self.accepted_features.contains(&feature_name)
117+
{
118+
log::info!("Skipping not accepted feature: {}", feature_name);
119+
continue;
120+
}
121+
122+
let data_types = match self
123+
.load_definitions_for_feature::<DefinitionDataType>(&path, "data_type")?
124+
{
125+
Some(v) => v,
126+
None => continue,
127+
};
236128

237-
let feature = Feature {
238-
name: feature_name,
239-
data_types,
240-
flow_types,
241-
functions,
129+
let flow_types =
130+
match self.load_definitions_for_feature::<FlowType>(&path, "flow_type")? {
131+
Some(v) => v,
132+
None => continue,
242133
};
243134

244-
features.push(feature);
245-
}
135+
let functions = match self.load_definitions_for_feature::<RuntimeFunctionDefinition>(
136+
&path,
137+
"runtime_definition",
138+
)? {
139+
Some(v) => v,
140+
None => continue,
141+
};
142+
143+
let feature = Feature {
144+
name: feature_name,
145+
data_types,
146+
flow_types,
147+
functions,
148+
};
149+
150+
features.push(feature);
246151
}
247152

248153
Ok(features)
249154
}
250155

156+
fn load_definitions_for_feature<T>(
157+
&self,
158+
feature_dir: &Path,
159+
sub_dir: &str,
160+
) -> Result<Option<Vec<T>>, ReaderError>
161+
where
162+
T: DeserializeOwned + HasVersion,
163+
{
164+
let dir = feature_dir.join(sub_dir);
165+
166+
let raw: Vec<T> = match self.collect_definitions::<T>(&dir) {
167+
Ok(v) => v,
168+
Err(err) => {
169+
if self.should_break {
170+
return Err(ReaderError::ReadFeatureError {
171+
path: dir.to_string_lossy().to_string(),
172+
source: Box::new(err),
173+
});
174+
} else {
175+
// Skip this feature if we shouldn't break on error
176+
return Ok(None);
177+
}
178+
}
179+
};
180+
181+
let items = raw
182+
.into_iter()
183+
.map(|mut v| {
184+
v.normalize_version();
185+
v
186+
})
187+
.filter(|v| v.is_accepted(&self.accepted_version))
188+
.collect();
189+
190+
Ok(Some(items))
191+
}
192+
251193
fn collect_definitions<T>(&self, dir: &Path) -> Result<Vec<T>, ReaderError>
252194
where
253195
T: DeserializeOwned,

0 commit comments

Comments
 (0)