1- use std:: { fs, path:: Path } ;
1+ use std:: { collections :: HashSet , fs, path:: Path } ;
22
33use inflector:: Inflector ;
4+ use proc_macro2:: Ident ;
45use regex:: Regex ;
56
67use crate :: asyncapi_model:: AsyncAPI ;
78
8- pub fn parse_spec_to_model ( path : & Path ) -> Result < AsyncAPI , serde_json:: Error > {
9- let string_content = fs:: read_to_string ( path) . expect ( "file could not be read" ) ;
9+ use super :: {
10+ preprocessor:: { resolve_refs, sanitize_operation_ids_and_check_duplicate} ,
11+ validator:: validate_asyncapi_schema,
12+ } ;
13+
14+ pub fn parse_spec_to_model (
15+ spec_path : & Path ,
16+ validator_schema_path : & Path ,
17+ ) -> Result < AsyncAPI , serde_json:: Error > {
18+ let spec = parse_string_to_serde_json_value ( spec_path) ;
19+ let validator = parse_string_to_serde_json_value ( validator_schema_path) ;
20+
21+ validate_asyncapi_schema ( & validator, & spec) ;
22+
23+ let preprocessed_spec = preprocess_schema ( spec) ;
24+ let spec = serde_json:: from_value :: < AsyncAPI > ( preprocessed_spec) ?;
25+ Ok ( spec)
26+ }
27+
28+ fn preprocess_schema ( spec : serde_json:: Value ) -> serde_json:: Value {
29+ let resolved_refs = resolve_refs ( spec. clone ( ) , spec) ;
30+ let mut seen = HashSet :: new ( ) ;
31+ let sanitized =
32+ sanitize_operation_ids_and_check_duplicate ( resolved_refs. clone ( ) , resolved_refs, & mut seen) ;
33+ println ! ( "Preprocessed spec: {}" , sanitized) ;
34+ sanitized
35+ }
36+
37+ fn parse_string_to_serde_json_value ( file_path : & Path ) -> serde_json:: Value {
38+ let file_string = fs:: read_to_string ( file_path) . expect ( "File could not be read" ) ;
1039 // check if file is yaml or json
11- let parsed = match path . extension ( ) {
40+ let parsed_value = match file_path . extension ( ) {
1241 Some ( ext) => match ext. to_str ( ) {
13- Some ( "yaml" ) => serde_yaml:: from_str :: < serde_json:: Value > ( & string_content) . unwrap ( ) ,
14- Some ( "yml" ) => serde_yaml:: from_str :: < serde_json:: Value > ( & string_content) . unwrap ( ) ,
15- Some ( "json" ) => serde_json:: from_str :: < serde_json:: Value > ( & string_content) . unwrap ( ) ,
42+ Some ( "yaml" ) | Some ( "yml" ) => {
43+ serde_yaml:: from_str :: < serde_json:: Value > ( & file_string) . unwrap ( )
44+ }
45+ Some ( "json" ) => serde_json:: from_str :: < serde_json:: Value > ( & file_string) . unwrap ( ) ,
1646 _ => {
17- panic ! ( "file has no extension" ) ;
47+ panic ! ( "File has an unsupported extension" ) ;
1848 }
1949 } ,
2050 None => {
21- panic ! ( "file has no extension" ) ;
51+ panic ! ( "File has no extension" ) ;
2252 }
2353 } ;
24- let with_resolved_references =
25- crate :: parser:: resolve_refs:: resolve_refs ( parsed. clone ( ) , parsed) ;
26- let spec = serde_json:: from_value :: < AsyncAPI > ( with_resolved_references) ?;
27- Ok ( spec)
54+ parsed_value
2855}
2956
3057fn capitalize_first_char ( s : & str ) -> String {
@@ -35,11 +62,16 @@ fn capitalize_first_char(s: &str) -> String {
3562 }
3663}
3764
38- pub fn convert_string_to_valid_type_name ( s : & str , suffix : & str ) -> String {
39- let re = Regex :: new ( r"[^\w\s]" ) . unwrap ( ) ;
65+ pub fn validate_identifier_string ( s : & str ) -> String {
4066 // Remove special chars, capitalize words, remove spaces
41- let mut root_msg_name = re. replace_all ( s, " " ) . to_title_case ( ) . replace ( ' ' , "" ) ;
42- // Append Message to the end of the name
43- root_msg_name. push_str ( suffix) ;
44- capitalize_first_char ( root_msg_name. as_str ( ) )
67+ let re = Regex :: new ( r"[^\w\s]" ) . unwrap ( ) ;
68+ let sanitized_identifier = re. replace_all ( s, " " ) . to_title_case ( ) . replace ( ' ' , "" ) ;
69+ let capitalized_sanitized_identifier = capitalize_first_char ( sanitized_identifier. as_str ( ) ) ;
70+ // Create a new identifier
71+ // This acts as validation for the message name, panics when the name is invalid
72+ Ident :: new (
73+ & capitalized_sanitized_identifier,
74+ proc_macro2:: Span :: call_site ( ) ,
75+ ) ;
76+ capitalized_sanitized_identifier
4577}
0 commit comments