11use crate :: asyncapi_model:: {
2- schema:: { ObjectType , SchemaKind , Type } ,
3- ReferenceOr , Schema ,
2+ schema:: { ArrayType , IntegerFormat , NumberFormat , ObjectType , SchemaKind , StringFormat , Type } ,
3+ ReferenceOr , Schema , VariantOrUnknownOrEmpty ,
44} ;
55use core:: fmt;
6- use std:: { collections:: HashMap , format} ;
6+ use std:: { collections:: HashMap , format, panic } ;
77
88use super :: common:: validate_identifier_string;
99
@@ -38,7 +38,7 @@ fn object_schema_to_string(
3838) -> Result < String , SchemaParserError > {
3939 let before_string: String = format ! (
4040 "#[derive(Clone, Debug, Deserialize, Serialize)]\n pub struct {} {{\n " ,
41- validate_identifier_string( property_name)
41+ validate_identifier_string( property_name, true )
4242 ) ;
4343 let after_string = String :: from ( "\n }\n " ) ;
4444 let property_string_iterator: Vec < Result < String , SchemaParserError > > = schema
@@ -68,18 +68,122 @@ fn object_schema_to_string(
6868 Ok ( property_name. to_string ( ) )
6969}
7070
71+ fn format_to_rust_type ( schema_type : & Type ) -> String {
72+ match schema_type {
73+ //TODO: Add suggested validators for each string format
74+ Type :: String ( _var) => {
75+ match & _var. format {
76+ VariantOrUnknownOrEmpty :: Item ( item) => {
77+ match item {
78+ StringFormat :: Date => {
79+ // Date format is usually "yyyy-mm-dd"
80+ // You could validate it with a regex
81+ // if date_regex.is_match(_var) {
82+ // return "String".to_string();
83+ // }
84+ // panic!("Invalid Date format for string");
85+ "String" . to_string ( )
86+ } ,
87+ StringFormat :: DateTime => {
88+ // DateTime format could be ISO 8601: "2023-01-16T23:28:56.782Z"
89+ // You could validate it using chrono's parse function
90+ // if let Ok(_dt) = chrono::DateTime::parse_from_rfc3339(_var) {
91+ // return "String".to_string();
92+ // }
93+ // panic!("Invalid DateTime format for string");
94+ "String" . to_string ( )
95+ } ,
96+ StringFormat :: Password => {
97+ // Password might not need specific validation, just keep as String
98+ "String" . to_string ( )
99+ } ,
100+ StringFormat :: Byte => {
101+ // Bytes could be base64 encoded string
102+ // if base64::decode(_var).is_ok() {
103+ // return "String".to_string();
104+ // }
105+ // panic!("Invalid Byte format for string");
106+ "String" . to_string ( )
107+ } ,
108+ StringFormat :: Binary => {
109+ // Binary data might be just represented as a String
110+ "String" . to_string ( )
111+ } ,
112+ }
113+ } ,
114+ VariantOrUnknownOrEmpty :: Unknown ( _unknown) => "String" . to_string ( ) ,
115+ VariantOrUnknownOrEmpty :: Empty => "String" . to_string ( ) ,
116+ }
117+ } ,
118+ Type :: Number ( _var) => {
119+ match & _var. format {
120+ VariantOrUnknownOrEmpty :: Item ( item) => {
121+ match item {
122+ NumberFormat :: Float => "f32" . to_string ( ) ,
123+ NumberFormat :: Double => "f64" . to_string ( ) ,
124+ }
125+ }
126+ VariantOrUnknownOrEmpty :: Unknown ( _unknown) => "f64" . to_string ( ) ,
127+ VariantOrUnknownOrEmpty :: Empty => "f64" . to_string ( ) ,
128+ }
129+ } ,
130+ Type :: Integer ( _var) => {
131+ match & _var. format {
132+ VariantOrUnknownOrEmpty :: Item ( item) => {
133+ match item {
134+ IntegerFormat :: Int32 => "i32" . to_string ( ) ,
135+ IntegerFormat :: Int64 => "i64" . to_string ( ) ,
136+ }
137+ }
138+ VariantOrUnknownOrEmpty :: Unknown ( _unknown) => "i64" . to_string ( ) ,
139+ VariantOrUnknownOrEmpty :: Empty => "i64" . to_string ( ) ,
140+ }
141+ } ,
142+ Type :: Boolean { } => "bool" . to_string ( ) ,
143+ _type => panic ! ( "Unsupported primitive type: Currently only supports string, number, integer and boolean types" ) ,
144+ }
145+ }
146+
71147fn primitive_type_to_string (
72148 schema_type : Type ,
73149 property_name : & str ,
74150) -> Result < String , SchemaParserError > {
75- // TODO: Add support for arrays
76- match schema_type {
77- Type :: String ( _var) => Ok ( format ! ( "pub {}: String" , validate_identifier_string( property_name) ) ) ,
78- Type :: Number ( _var) => Ok ( format ! ( "pub {}: f64" , validate_identifier_string( property_name) ) ) ,
79- Type :: Integer ( _var) => Ok ( format ! ( "pub {}: int64" , validate_identifier_string( property_name) ) ) ,
80- Type :: Boolean { } => Ok ( format ! ( "pub {}: bool" , validate_identifier_string( property_name) ) ) ,
81- _type => Err ( SchemaParserError :: GenericError ( "Unsupported primitive type: Currently only supports string, number, integer and boolean types" . to_string ( ) , Some ( property_name. into ( ) ) ) ) ,
82- }
151+ Ok ( format ! (
152+ "pub {}: {}" ,
153+ validate_identifier_string( property_name, false ) ,
154+ format_to_rust_type( & schema_type)
155+ ) )
156+ }
157+
158+ fn array_type_to_string (
159+ array_type : & ArrayType ,
160+ property_name : & str ,
161+ ) -> Result < String , SchemaParserError > {
162+ let item_type = match & array_type. items {
163+ Some ( type_box) => match type_box {
164+ ReferenceOr :: Item ( schema) => match & schema. schema_kind {
165+ SchemaKind :: Type ( schema_type) => format_to_rust_type ( schema_type) ,
166+ _ => panic ! ( "Unsupported schema kind" ) ,
167+ } ,
168+ ReferenceOr :: Reference { reference : _ } => {
169+ return Err ( SchemaParserError :: GenericError (
170+ "References are not supported yet" . to_string ( ) ,
171+ property_name. to_string ( ) . into ( ) ,
172+ ) )
173+ }
174+ } ,
175+ None => {
176+ return Err ( SchemaParserError :: GenericError (
177+ "Array type without item type" . into ( ) ,
178+ None ,
179+ ) )
180+ }
181+ } ;
182+ Ok ( format ! (
183+ "pub {}: Vec<{}>" ,
184+ validate_identifier_string( property_name, false ) ,
185+ item_type
186+ ) )
83187}
84188
85189pub fn schema_parser_mapper (
@@ -95,9 +199,10 @@ pub fn schema_parser_mapper(
95199 Ok ( format ! (
96200 "pub {}: {}" ,
97201 struct_name,
98- validate_identifier_string( struct_name. as_str( ) ) . as_str( )
202+ validate_identifier_string( struct_name. as_str( ) , false ) . as_str( )
99203 ) )
100204 }
205+ Type :: Array ( array_type) => array_type_to_string ( array_type, property_name) ,
101206 _primitive_type => primitive_type_to_string ( _primitive_type. clone ( ) , property_name) ,
102207 } ,
103208 _other_schema_kind => {
0 commit comments