Skip to content

Commit 79bee89

Browse files
committed
feat: added wip analyser for data types
1 parent 085e02c commit 79bee89

File tree

4 files changed

+243
-18
lines changed

4 files changed

+243
-18
lines changed

cli/src/analyser/mod.rs

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
use tucana::shared::{DataTypeIdentifier, DefinitionDataType, FlowType, RuntimeFunctionDefinition};
2+
use tucana::shared::data_type_identifier::Type;
3+
use tucana::shared::definition_data_type_rule::Config;
4+
5+
#[derive(Clone)]
6+
pub struct AnalysableDataType {
7+
pub definition_data_type: DefinitionDataType,
8+
pub id: i16
9+
}
10+
11+
12+
pub struct AnalysableFlowType {
13+
pub flow_type: FlowType,
14+
pub id: i16
15+
}
16+
17+
18+
pub struct AnalysableFunction {
19+
pub function: RuntimeFunctionDefinition,
20+
pub id: i16
21+
}
22+
23+
pub struct Analyser {
24+
pub data_types: Vec<AnalysableDataType>,
25+
pub flow_types: Vec<AnalysableFlowType>,
26+
pub functions: Vec<AnalysableFunction>
27+
}
28+
29+
impl Analyser {
30+
31+
pub fn data_type_identifier_exists(&self, identifier: String, id: i16) -> bool {
32+
33+
for data_types in &self.data_types {
34+
if id == data_types.id {
35+
continue
36+
}
37+
38+
if data_types.definition_data_type.identifier.to_lowercase() != identifier.to_lowercase() {
39+
continue;
40+
}
41+
return true;
42+
}
43+
false
44+
}
45+
46+
pub fn handle_data_type(&self, analysable_data_type: AnalysableDataType, data_type_identifier: DataTypeIdentifier) -> Vec<String> {
47+
48+
let data_type = analysable_data_type.definition_data_type.clone();
49+
50+
let id = analysable_data_type.id;
51+
let mut result = vec![];
52+
if let Some(r#type) = data_type_identifier.r#type {
53+
match r#type {
54+
Type::DataTypeIdentifier(identifier) => {
55+
if !self.data_type_identifier_exists(identifier.clone(), id) {
56+
println!("A Unknown DataType inside a rule was detected: {}", identifier)
57+
}
58+
}
59+
Type::GenericType(generic) => {
60+
if !self.data_type_identifier_exists(generic.data_type_identifier.clone(), id) {
61+
println!("A Unknown DataType inside a rule was detected: {}", generic.data_type_identifier)
62+
}
63+
64+
for mapper in generic.generic_mappers {
65+
if data_type.generic_keys.contains(&mapper.target) {
66+
result.push(mapper.target.clone())
67+
} else {
68+
println!("A GenericKey was used that did not exists in this DataType: {}", mapper.target)
69+
}
70+
71+
for source in mapper.source {
72+
result.append(&mut self.handle_data_type(analysable_data_type.clone(), source))
73+
}
74+
}
75+
}
76+
Type::GenericKey(key) => {
77+
result.push(key.clone())
78+
}
79+
}
80+
} else {
81+
println!("Type is undefined!")
82+
}
83+
84+
result
85+
}
86+
87+
pub fn analyse_data_type(&self, analysable_data_type: AnalysableDataType) {
88+
let id = analysable_data_type.id;
89+
let data_type = analysable_data_type.definition_data_type.clone();
90+
println!("Checking: {}", data_type.identifier.clone());
91+
// Check if Identifier is duplicate
92+
if self.data_type_identifier_exists(data_type.identifier.clone(), id) {
93+
println!("Duplicate definition of type {}", data_type.identifier)
94+
}
95+
96+
// The variant 0 never should occur
97+
if data_type.variant == 0 {
98+
println!("Type {} detected varriant 0", data_type.identifier)
99+
}
100+
101+
// Generic Keys are present. Search if they are referenced!
102+
if !data_type.generic_keys.is_empty() {
103+
let mut detected_generic_keys: Vec<String> = vec![];
104+
if data_type.rules.is_empty() {
105+
println!("Generic Keys are defined but never used!")
106+
}
107+
108+
for optional_rule in &data_type.rules {
109+
if let Some(config) = optional_rule.clone().config {
110+
match config {
111+
Config::ContainsKey(rule) => {
112+
if let Some(data_type_identifier) = rule.data_type_identifier {
113+
detected_generic_keys.append(&mut self.handle_data_type(analysable_data_type.clone(), data_type_identifier))
114+
} else {
115+
println!("DataTypeIdentifier is undefined!")
116+
}
117+
}
118+
Config::ContainsType(rule) => {
119+
if let Some(data_type_identifier) = rule.data_type_identifier {
120+
detected_generic_keys.append(&mut self.handle_data_type(analysable_data_type.clone(), data_type_identifier))
121+
} else {
122+
println!("DataTypeIdentifier is undefined!")
123+
}
124+
}
125+
Config::ItemOfCollection(rule) => {
126+
if rule.items.is_empty() {
127+
println!("ItemOfCollection is defined but does not have any items!")
128+
}
129+
}
130+
Config::NumberRange(_) => {}
131+
Config::Regex(_) => {}
132+
Config::InputTypes(rule) => {
133+
if rule.input_types.is_empty() {
134+
println!("InputTypes is defined but does not have any inputs!")
135+
}
136+
137+
for input_type in &rule.input_types {
138+
if let Some(data_type_identifier) = &input_type.data_type_identifier {
139+
detected_generic_keys.append(&mut self.handle_data_type(analysable_data_type.clone(), data_type_identifier.clone()))
140+
} else {
141+
println!("DataTypeIdentifier is undefined!")
142+
}
143+
}
144+
}
145+
Config::ReturnType(rule) => {
146+
if let Some(data_type_identifier) = &rule.data_type_identifier {
147+
detected_generic_keys.append(&mut self.handle_data_type(analysable_data_type.clone(), data_type_identifier.clone()))
148+
} else {
149+
println!("DataTypeIdentifier is undefined!")
150+
}
151+
}
152+
Config::ParentType(rule) => {
153+
if let Some(data_type_identifier) = &rule.parent_type {
154+
detected_generic_keys.append(&mut self.handle_data_type(analysable_data_type.clone(), data_type_identifier.clone()))
155+
} else {
156+
println!("DataTypeIdentifier is undefined!")
157+
}
158+
}
159+
}
160+
}
161+
}
162+
163+
//TODO: Handle key not present/not exissting
164+
for key in &detected_generic_keys {
165+
println!("Detected key: {}", key);
166+
}
167+
} else {
168+
// Check here for any empty configs!
169+
for rule in &data_type.rules {
170+
if rule.config.is_none() {
171+
println!("found empty rule!")
172+
}
173+
}
174+
}
175+
176+
// Check if at least one Translation is present
177+
if data_type.name.is_empty() {
178+
println!("At least one translation should be defined")
179+
}
180+
181+
}
182+
}

cli/src/command/report.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::table::{error_table, summary_table};
22
use code0_definition_reader::parser::Parser;
3+
use crate::analyser::{AnalysableDataType, AnalysableFlowType, AnalysableFunction, Analyser};
34

45
pub fn report_errors(path: Option<String>) {
56
let dir_path = path.unwrap_or_else(|| "./definitions".to_string());
@@ -10,6 +11,60 @@ pub fn report_errors(path: Option<String>) {
1011
panic!("Error reading definitions");
1112
}
1213
};
14+
15+
let mut index = 0;
16+
let collected_data_types = parser
17+
.features
18+
.iter()
19+
.map(|f| f.data_types.clone())
20+
.flatten()
21+
.map(|d| {
22+
index = index + 1;
23+
return AnalysableDataType {
24+
definition_data_type: d.clone(),
25+
id: index
26+
}
27+
})
28+
.collect::<Vec<_>>();
29+
30+
let collected_functions = parser
31+
.features
32+
.iter()
33+
.map(|f| f.runtime_functions.clone())
34+
.flatten()
35+
.map(|d| {
36+
index = index + 1;
37+
return AnalysableFunction {
38+
function: d.clone(),
39+
id: index
40+
}
41+
})
42+
.collect::<Vec<_>>();
43+
44+
let collected_flow_types = parser
45+
.features
46+
.iter()
47+
.map(|f| f.flow_types.clone())
48+
.flatten()
49+
.map(|d| {
50+
index = index + 1;
51+
return AnalysableFlowType {
52+
flow_type: d.clone(),
53+
id: index
54+
}
55+
})
56+
.collect::<Vec<_>>();
57+
58+
let analyser = Analyser {
59+
data_types: collected_data_types.clone(),
60+
functions: collected_functions,
61+
flow_types: collected_flow_types,
62+
};
63+
64+
for data_type in collected_data_types {
65+
analyser.analyse_data_type(data_type);
66+
}
67+
1368
error_table(&parser.features);
1469
summary_table(&parser.features);
1570
}

cli/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use clap::{Parser as ClapParser, Subcommand};
22

33
mod command;
44
mod table;
5+
mod analyser;
56

67
/// Top-level CLI for 'definition'
78
#[derive(ClapParser)]

cli/src/table.rs

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -281,18 +281,7 @@ pub fn error_table(features: &Vec<Feature>) {
281281
pub fn summary_table(features: &[Feature]) {
282282
println!(
283283
"\n{}",
284-
"╔══════════════════════════════════════════════════════════════════════════════╗"
285-
.bright_cyan()
286-
);
287-
println!(
288-
"{} {} {}",
289-
"║".bright_cyan(),
290-
"CONCLUSION".bright_white().bold().on_blue(),
291-
"║".bright_cyan()
292-
);
293-
println!(
294-
"{}",
295-
"╚══════════════════════════════════════════════════════════════════════════════╝"
284+
"╔═══════════════════════════════ CONCLUSION ═══════════════════════════════╗"
296285
.bright_cyan()
297286
);
298287

@@ -302,9 +291,9 @@ pub fn summary_table(features: &[Feature]) {
302291
.map(|feature| {
303292
let is_successful = feature.errors.is_empty();
304293
let status = if is_successful {
305-
"SUCCESS".to_string()
294+
"SUCCESS".to_string()
306295
} else {
307-
"FAILED".to_string()
296+
"FAILED".to_string()
308297
};
309298

310299
FeatureSummaryRow {
@@ -329,13 +318,11 @@ pub fn summary_table(features: &[Feature]) {
329318
let total_features = features.len();
330319
let successful_features = features.iter().filter(|f| f.errors.is_empty()).count();
331320

332-
println!("\n{}", "OVERALL SUMMARY".bright_blue().bold());
333-
334321
if total_errors == 0 {
335322
println!(
336323
"{}",
337324
format!(
338-
"PROCESS SUCCESSFUL! All {total_features} feature(s) processed without errors.",
325+
"[SUCCESSFUL]! All {total_features} feature(s) processed without errors.",
339326
)
340327
.bright_green()
341328
.bold()
@@ -344,7 +331,7 @@ pub fn summary_table(features: &[Feature]) {
344331
println!(
345332
"{}",
346333
format!(
347-
"PROCESS FAILED! {total_errors} error(s) found across {total_features} feature(s)."
334+
"[FAILED]! {total_errors} error(s) found across {total_features} feature(s)."
348335
)
349336
.bright_red()
350337
.bold()

0 commit comments

Comments
 (0)