1+ use std:: path:: Path ;
12use tucana:: shared:: { DataTypeIdentifier , DefinitionDataType , FlowType , RuntimeFunctionDefinition } ;
23use tucana:: shared:: data_type_identifier:: Type ;
34use tucana:: shared:: definition_data_type_rule:: Config ;
5+ use code0_definition_reader:: reader:: { MetaType , ParsableDefinition , Reader } ;
6+ use crate :: formatter:: { error, warning} ;
47
58#[ derive( Clone ) ]
69pub struct AnalysableDataType {
7- pub definition_data_type : DefinitionDataType ,
10+ pub original_definition : ParsableDefinition ,
11+ pub definition_data_type : DefinitionDataType ,
812 pub id : i16
913}
1014
11-
1215pub struct AnalysableFlowType {
16+ pub original_definition : ParsableDefinition ,
1317 pub flow_type : FlowType ,
1418 pub id : i16
1519}
1620
17-
1821pub struct AnalysableFunction {
22+ pub original_definition : ParsableDefinition ,
1923 pub function : RuntimeFunctionDefinition ,
2024 pub id : i16
2125}
@@ -28,6 +32,85 @@ pub struct Analyser {
2832
2933impl Analyser {
3034
35+ pub fn new ( path : & str ) -> Analyser {
36+ let reader = match Reader :: from_path ( path) {
37+ Some ( res) => res,
38+ None => {
39+ panic ! ( "No definitions behind this path" ) ;
40+ }
41+ } ;
42+
43+ let mut current_index = 0 ;
44+ let mut collected_data_types: Vec < AnalysableDataType > = vec ! [ ] ;
45+ let mut collected_flow_types: Vec < AnalysableFlowType > = vec ! [ ] ;
46+ let mut collected_functions: Vec < AnalysableFunction > = vec ! [ ] ;
47+
48+ for features in reader. meta {
49+ match features. r#type {
50+ MetaType :: FlowType => {
51+ for p_flow_type in & features. data {
52+ current_index += 1 ;
53+ match serde_json:: from_str :: < FlowType > ( p_flow_type. definition_string . as_str ( ) ) {
54+ Ok ( flow_type) => collected_flow_types. push ( AnalysableFlowType {
55+ original_definition : p_flow_type. clone ( ) ,
56+ flow_type,
57+ id : current_index,
58+ } ) ,
59+ Err ( err) => {
60+ if let Some ( str_path) = & p_flow_type. path {
61+ let path = Path :: new ( str_path) ;
62+ error ( err. to_string ( ) , format ! ( "{:?}:{}:{}" , path. display( ) , p_flow_type. starting_line, 1 ) ) ;
63+ }
64+ } ,
65+ }
66+ }
67+ } ,
68+ MetaType :: DataType => {
69+ for p_data_type in & features. data {
70+ current_index += 1 ;
71+ match serde_json:: from_str :: < DefinitionDataType > ( p_data_type. definition_string . as_str ( ) ) {
72+ Ok ( data_type) => collected_data_types. push ( AnalysableDataType {
73+ original_definition : p_data_type. clone ( ) ,
74+ definition_data_type : data_type,
75+ id : current_index,
76+ } ) ,
77+ Err ( err) => {
78+ if let Some ( str_path) = & p_data_type. path {
79+ let path = Path :: new ( str_path) ;
80+ error ( err. to_string ( ) , format ! ( "{}:{}:{}" , path. display( ) , p_data_type. starting_line, 1 ) ) ;
81+ }
82+ } ,
83+ }
84+ }
85+ }
86+ MetaType :: RuntimeFunction => {
87+ for p_function in & features. data {
88+ current_index += 1 ;
89+ match serde_json:: from_str :: < RuntimeFunctionDefinition > ( p_function. definition_string . as_str ( ) ) {
90+ Ok ( function) => collected_functions. push ( AnalysableFunction {
91+ original_definition : p_function. clone ( ) ,
92+ function,
93+ id : current_index,
94+ } ) ,
95+ Err ( err) => {
96+ if let Some ( str_path) = & p_function. path {
97+ let path = Path :: new ( str_path) ;
98+ error ( err. to_string ( ) , format ! ( "{:?}:{}:{}" , path. display( ) , p_function. starting_line, 1 ) ) ;
99+ }
100+ } ,
101+ }
102+ }
103+ }
104+ }
105+ }
106+
107+ Self {
108+ data_types : collected_data_types,
109+ functions : collected_functions,
110+ flow_types : collected_flow_types,
111+ }
112+ }
113+
31114 pub fn data_type_identifier_exists ( & self , identifier : String , id : i16 ) -> bool {
32115
33116 for data_types in & self . data_types {
@@ -43,29 +126,33 @@ impl Analyser {
43126 false
44127 }
45128
129+ /// Checks (recursively) if the defined DataTypes are correct
46130 pub fn handle_data_type ( & self , analysable_data_type : AnalysableDataType , data_type_identifier : DataTypeIdentifier ) -> Vec < String > {
47-
48131 let data_type = analysable_data_type. definition_data_type . clone ( ) ;
49-
132+ let path = format ! (
133+ "{:?}:{}:{}" ,
134+ Path :: new( & analysable_data_type. clone( ) . original_definition. path. unwrap_or_default( ) ) . display( ) ,
135+ analysable_data_type. original_definition. starting_line,
136+ 1
137+ ) ;
50138 let id = analysable_data_type. id ;
51139 let mut result = vec ! [ ] ;
140+
52141 if let Some ( r#type) = data_type_identifier. r#type {
53142 match r#type {
54143 Type :: DataTypeIdentifier ( identifier) => {
55144 if !self . data_type_identifier_exists ( identifier. clone ( ) , id) {
56- println ! ( "A Unknown DataType inside a rule was detected: {} " , identifier)
145+ error ( format ! ( "`{}` uses a undefined data_type: `{}`! " , analysable_data_type . definition_data_type . identifier, identifier ) , path ) ;
57146 }
58147 }
59148 Type :: GenericType ( generic) => {
60149 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)
150+ error ( format ! ( "`{}` uses a undefined data_type: `{}`! " , analysable_data_type . definition_data_type . identifier , generic. data_type_identifier) , path ) ;
62151 }
63152
64153 for mapper in generic. generic_mappers {
65154 if data_type. generic_keys . contains ( & mapper. target ) {
66155 result. push ( mapper. target . clone ( ) )
67- } else {
68- println ! ( "A GenericKey was used that did not exists in this DataType: {}" , mapper. target)
69156 }
70157
71158 for source in mapper. source {
@@ -78,7 +165,7 @@ impl Analyser {
78165 }
79166 }
80167 } else {
81- println ! ( "Type is undefined!" )
168+ error ( format ! ( "`{}` has a data_type that's null!" , analysable_data_type . definition_data_type . identifier ) , path ) ;
82169 }
83170
84171 result
@@ -87,22 +174,27 @@ impl Analyser {
87174 pub fn analyse_data_type ( & self , analysable_data_type : AnalysableDataType ) {
88175 let id = analysable_data_type. id ;
89176 let data_type = analysable_data_type. definition_data_type . clone ( ) ;
90- println ! ( "Checking: {}" , data_type. identifier. clone( ) ) ;
177+ let path = format ! (
178+ "{:?}:{}:{}" ,
179+ Path :: new( & analysable_data_type. clone( ) . original_definition. path. unwrap_or_default( ) ) . display( ) ,
180+ analysable_data_type. original_definition. starting_line,
181+ 1
182+ ) ;
91183 // Check if Identifier is duplicate
92184 if self . data_type_identifier_exists ( data_type. identifier . clone ( ) , id) {
93- println ! ( "Duplicate definition of type {} " , data_type. identifier)
185+ error ( format ! ( "The data_type `{}` is already defined! " , data_type. identifier) , path . clone ( ) ) ;
94186 }
95187
96188 // The variant 0 never should occur
97189 if data_type. variant == 0 {
98- println ! ( "Type {} detected varriant 0 " , data_type. identifier)
190+ error ( format ! ( "The variant of `{}` is 0 and thus incorrect! " , data_type. identifier) , path . clone ( ) ) ;
99191 }
100192
101193 // Generic Keys are present. Search if they are referenced!
102194 if !data_type. generic_keys . is_empty ( ) {
103195 let mut detected_generic_keys: Vec < String > = vec ! [ ] ;
104196 if data_type. rules . is_empty ( ) {
105- println ! ( "Generic Keys are defined but never used!" )
197+ error ( format ! ( "`{}` defined generic_keys but never uses one!" , data_type . identifier ) , path . clone ( ) ) ;
106198 }
107199
108200 for optional_rule in & data_type. rules {
@@ -112,71 +204,76 @@ impl Analyser {
112204 if let Some ( data_type_identifier) = rule. data_type_identifier {
113205 detected_generic_keys. append ( & mut self . handle_data_type ( analysable_data_type. clone ( ) , data_type_identifier) )
114206 } else {
115- println ! ( "DataTypeIdentifier is undefined!" )
207+ error ( format ! ( "`{}` uses a definition_data_type_contains_key_rule that is null!" , data_type . identifier ) , path . clone ( ) ) ;
116208 }
117209 }
118210 Config :: ContainsType ( rule) => {
119211 if let Some ( data_type_identifier) = rule. data_type_identifier {
120212 detected_generic_keys. append ( & mut self . handle_data_type ( analysable_data_type. clone ( ) , data_type_identifier) )
121213 } else {
122- println ! ( "DataTypeIdentifier is undefined!" )
214+ error ( format ! ( "`{}` uses a definition_data_type_contains_type_rule that is null!" , data_type . identifier ) , path . clone ( ) ) ;
123215 }
124216 }
125217 Config :: ItemOfCollection ( rule) => {
126218 if rule. items . is_empty ( ) {
127- println ! ( "ItemOfCollection is defined but does not have any items!" )
219+ error ( format ! ( "`{}` uses a definition_data_type_item_of_collection_rule without any defined items!" , data_type . identifier ) , path . clone ( ) ) ;
128220 }
129221 }
130222 Config :: NumberRange ( _) => { }
131223 Config :: Regex ( _) => { }
132224 Config :: InputTypes ( rule) => {
133225 if rule. input_types . is_empty ( ) {
134- println ! ( "InputTypes is defined but does not have any inputs!" )
226+ error ( format ! ( "`{}` uses a definition_data_type_input_types_rule without any defined inputs!" , data_type . identifier ) , path . clone ( ) ) ;
135227 }
136228
137229 for input_type in & rule. input_types {
138230 if let Some ( data_type_identifier) = & input_type. data_type_identifier {
139231 detected_generic_keys. append ( & mut self . handle_data_type ( analysable_data_type. clone ( ) , data_type_identifier. clone ( ) ) )
140232 } else {
141- println ! ( "DataTypeIdentifier is undefined!" )
233+ error ( format ! ( "`{}` uses a definition_data_type_input_types_rule that has a undefined data_type!" , data_type . identifier ) , path . clone ( ) ) ;
142234 }
143235 }
144236 }
145237 Config :: ReturnType ( rule) => {
146238 if let Some ( data_type_identifier) = & rule. data_type_identifier {
147239 detected_generic_keys. append ( & mut self . handle_data_type ( analysable_data_type. clone ( ) , data_type_identifier. clone ( ) ) )
148240 } else {
149- println ! ( "DataTypeIdentifier is undefined!" )
241+ error ( format ! ( "`{}` uses a definition_data_type_return_type_rule that is null!" , data_type . identifier ) , path . clone ( ) ) ;
150242 }
151243 }
152244 Config :: ParentType ( rule) => {
153245 if let Some ( data_type_identifier) = & rule. parent_type {
154246 detected_generic_keys. append ( & mut self . handle_data_type ( analysable_data_type. clone ( ) , data_type_identifier. clone ( ) ) )
155247 } else {
156- println ! ( "DataTypeIdentifier is undefined!" )
248+ error ( format ! ( "`{}` uses a definition_data_type_parent_type_rule that is null!" , data_type . identifier ) , path . clone ( ) ) ;
157249 }
158250 }
159251 }
160252 }
161253 }
162254
163- //TODO: Handle key not present/not exissting
164- for key in & detected_generic_keys {
165- println ! ( "Detected key: {}" , key) ;
255+ let defined_but_unused = data_type. generic_keys . iter ( ) . filter ( |key| !detected_generic_keys. contains ( key) ) . collect :: < Vec < & String > > ( ) ;
256+ let used_but_undefined = detected_generic_keys. iter ( ) . filter ( |key| !data_type. generic_keys . contains ( key) ) . collect :: < Vec < & String > > ( ) ;
257+
258+ for key in defined_but_unused {
259+ error ( format ! ( "`{}` uses a generic_key (`{}`) that's never used!" , analysable_data_type. definition_data_type. identifier, key) , path. clone ( ) ) ;
260+ }
261+
262+ for key in used_but_undefined {
263+ error ( format ! ( "`{}` uses a generic_key (`{}`) that's not defined!" , analysable_data_type. definition_data_type. identifier, key) , path. clone ( ) ) ;
166264 }
167265 } else {
168266 // Check here for any empty configs!
169267 for rule in & data_type. rules {
170268 if rule. config . is_none ( ) {
171- println ! ( "found empty rule!" )
269+ error ( format ! ( "`{}` uses a rule that is null!" , analysable_data_type . definition_data_type . identifier ) , path . clone ( ) ) ;
172270 }
173271 }
174272 }
175273
176274 // Check if at least one Translation is present
177275 if data_type. name . is_empty ( ) {
178- println ! ( "At least one translation should be defined" )
276+ warning ( format ! ( "`{}` has no name defined!" , analysable_data_type . definition_data_type . identifier ) , path . clone ( ) ) ;
179277 }
180-
181278 }
182279}
0 commit comments