diff --git a/lib/codegen/rust/actix.dart b/lib/codegen/rust/actix.dart index 191ed7eb..7e0cd9a8 100644 --- a/lib/codegen/rust/actix.dart +++ b/lib/codegen/rust/actix.dart @@ -3,7 +3,7 @@ import 'dart:convert'; import 'package:jinja/jinja.dart' as jj; import 'package:apidash/consts.dart'; import 'package:apidash/utils/utils.dart' - show getNewUuid, getValidRequestUri, padMultilineString, stripUriParams; + show getNewUuid, getValidRequestUri, stripUriParams; import 'package:apidash/models/models.dart' show RequestModel; class RustActixCodeGen { @@ -12,7 +12,7 @@ class RustActixCodeGen { #[actix_rt::main] async fn main() -> Result<(), Box> { let url = "{{url}}"; - let mut client = awc::Client::default().{{method}}(url); + let client = awc::Client::default(); """; @@ -35,15 +35,6 @@ async fn main() -> Result<(), Box> { """; - String kTemplateHeaders = """ - - let header_str = r#"{{headers}}"#; - let headers_map: std::collections::HashMap<&str, &str> = serde_json::from_str(header_str)?; - for (key, val) in headers_map { - client = client.insert_header((key, val)); - } - -"""; String kTemplateFormHeaderContentType = ''' multipart/form-data; boundary={{boundary}}'''; @@ -51,18 +42,27 @@ multipart/form-data; boundary={{boundary}}'''; String kTemplateRequest = """ - let mut response = client + let mut response = client\n .{{method}}(url) """; - final String kStringFormDataBody = r''' - #[derive(serde::Deserialize)] + final String kStringFormDataBody = r""" + struct FormDataItem { name: String, value: String, field_type: String, } - let data_str = r#"{{fields_list}}"#; - let form_data_items: Vec = serde_json::from_str(data_str).unwrap(); + + let form_data_items: Vec = vec![ + {%- for formitem in fields_list %} + FormDataItem { + {%- for key, val in formitem %} + {% if key == "type" %}field_type: "{{ val }}".to_string(),{% else %}{{ key }}: "{{ val }}".to_string(),{% endif %} + {%- endfor %} + }, + {%- endfor %} + ]; + fn build_data_list(fields: Vec) -> Vec { let mut data_list = Vec::new(); @@ -70,29 +70,15 @@ multipart/form-data; boundary={{boundary}}'''; data_list.extend_from_slice(b"--{{boundary}}\r\n"); if field.field_type == "text" { - data_list.extend_from_slice( - format!( - "Content-Disposition: form-data; name=\"{}\"\r\n", - field.name - ) - .as_bytes(), - ); + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"\r\n", field.name).as_bytes()); data_list.extend_from_slice(b"Content-Type: text/plain\r\n\r\n"); data_list.extend_from_slice(field.value.as_bytes()); data_list.extend_from_slice(b"\r\n"); } else if field.field_type == "file" { - data_list.extend_from_slice( - format!( - "Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", - field.name, field.value - ) - .as_bytes(), - ); + data_list.extend_from_slice(format!("Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n", field.name, field.value).as_bytes()); - let mime_type = mime_guess::from_path(&field.value) - .first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); - data_list - .extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); + let mime_type = mime_guess::from_path(&field.value).first_or(mime_guess::mime::APPLICATION_OCTET_STREAM); + data_list.extend_from_slice(format!("Content-Type: {}\r\n\r\n", mime_type).as_bytes()); let mut file = std::fs::File::open(&field.value).unwrap(); let mut file_contents = Vec::new(); @@ -107,16 +93,21 @@ multipart/form-data; boundary={{boundary}}'''; } let payload = build_data_list(form_data_items); -'''; +"""; - String kStringRequestParams = """\n .query(¶ms)\n .unwrap() - """; + String kTemplateRequestParams = + """\n .query(&{{ params }})\n .unwrap()"""; - String kStringRequestBody = """\n .send_body(payload)"""; + String kStringRequestBody = """\n .send_body(payload)"""; - String kStringRequestJson = """\n .send_json(&payload)"""; + String kStringRequestJson = """\n .send_json(&payload)"""; - final String kStringRequestEnd = """\n .await\n .unwrap(); + String kStringRequestNormal = """\n .send()"""; + + String kTemplateRequestHeaders = + """\n {% for key, val in headers %}.insert_header(("{{key}}", "{{val}}")){% if not loop.last %}{{ '\n ' }}{% endif %}{% endfor %}"""; + + final String kStringRequestEnd = """\n .await\n .unwrap(); let body_bytes = response.body().await.unwrap(); let body = std::str::from_utf8(&body_bytes).unwrap(); @@ -133,7 +124,6 @@ multipart/form-data; boundary={{boundary}}'''; ) { try { String result = ""; - bool hasQuery = false; bool hasBody = false; bool hasJsonBody = false; String uuid = getNewUuid(); @@ -156,20 +146,6 @@ multipart/form-data; boundary={{boundary}}'''; "method": requestModel.method.name.toLowerCase() }); - if (uri.hasQuery) { - var params = uri.queryParameters; - if (params.isNotEmpty) { - hasQuery = true; - var tupleStrings = params.entries - .map((entry) => '("${entry.key}", "${entry.value}")') - .toList(); - var paramsString = "[${tupleStrings.join(', ')}]"; - var templateParams = jj.Template(kTemplateParams); - paramsString = padMultilineString(paramsString, kParamsPadding); - result += templateParams.render({"params": paramsString}); - } - } - var method = requestModel.method; var requestBody = requestModel.requestBody; if (kMethodsWithBody.contains(method) && requestBody != null) { @@ -187,32 +163,11 @@ multipart/form-data; boundary={{boundary}}'''; } } - var headersList = requestModel.enabledRequestHeaders; - if (headersList != null || hasBody) { - var headers = requestModel.enabledHeadersMap; - if (requestModel.isFormDataRequest) { - var formHeaderTemplate = - jj.Template(kTemplateFormHeaderContentType); - headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ - "boundary": uuid, - }); - } - if (headers.isNotEmpty || hasBody) { - if (hasBody) { - headers[HttpHeaders.contentTypeHeader] = - requestModel.requestBodyContentType.header; - } - var headersString = kEncoder.convert(headers); - headersString = padMultilineString(headersString, kHeadersPadding); - var templateHeaders = jj.Template(kTemplateHeaders); - result += templateHeaders.render({"headers": headersString}); - } - } if (requestModel.isFormDataRequest) { var formDataBodyData = jj.Template(kStringFormDataBody); result += formDataBodyData.render( { - "fields_list": json.encode(requestModel.formDataMapList), + "fields_list": requestModel.formDataMapList, "boundary": uuid, }, ); @@ -222,16 +177,45 @@ multipart/form-data; boundary={{boundary}}'''; "method": method.name.toLowerCase(), }); - if (hasQuery) { - result += kStringRequestParams; + if (uri.hasQuery) { + var params = uri.queryParameters; + if (params.isNotEmpty) { + var tupleStrings = params.entries + .map((entry) => '("${entry.key}", "${entry.value}")') + .toList(); + var paramsString = "[${tupleStrings.join(', ')}]"; + var templateParms = jj.Template(kTemplateRequestParams); + result += templateParms.render({"params": paramsString}); + } + } + + var headersList = requestModel.enabledRequestHeaders; + if (headersList != null) { + var headers = requestModel.enabledHeadersMap; + if (headers.isNotEmpty) { + if (hasBody) { + headers[HttpHeaders.contentTypeHeader] = + requestModel.requestBodyContentType.header; + } + } + if (requestModel.isFormDataRequest) { + var formHeaderTemplate = + jj.Template(kTemplateFormHeaderContentType); + headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ + "boundary": uuid, + }); + } + + var templateHeaders = jj.Template(kTemplateRequestHeaders); + result += templateHeaders.render({"headers": headers}); } if (hasBody || requestModel.isFormDataRequest) { result += kStringRequestBody; - } - - if (hasJsonBody) { + } else if (hasJsonBody) { result += kStringRequestJson; + } else { + result += kStringRequestNormal; } result += kStringRequestEnd;