diff --git a/lib/codegen/rust/actix.dart b/lib/codegen/rust/actix.dart index be560c53..a1d581e6 100644 --- a/lib/codegen/rust/actix.dart +++ b/lib/codegen/rust/actix.dart @@ -18,16 +18,12 @@ async fn main() -> Result<(), Box> { """; - String kTemplateParams = """ - - let params = {{params}}; - -"""; - int kParamsPadding = 9; + String kTemplateParams = + """\n .query(&{{ params }})\n .unwrap()"""; String kTemplateBody = """ - let payload = "{{body}}"; + let payload = r#"{{body}}"#; """; @@ -37,11 +33,12 @@ async fn main() -> Result<(), Box> { """; + String kTemplateHeaders = + """\n {% for key, val in headers -%}.insert_header(("{{key}}", "{{val}}")){% if not loop.last %}{{ '\n ' }}{% endif %}{%- endfor -%}"""; + String kTemplateFormHeaderContentType = ''' multipart/form-data; boundary={{boundary}}'''; - int kHeadersPadding = 10; - String kTemplateRequest = """ let mut response = client\n .{{method}}(url) @@ -97,18 +94,12 @@ multipart/form-data; boundary={{boundary}}'''; let payload = build_data_list(form_data_items); """; - String kTemplateRequestParams = - """\n .query(&{{ params }})\n .unwrap()"""; - String kStringRequestBody = """\n .send_body(payload)"""; String kStringRequestJson = """\n .send_json(&payload)"""; 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(); @@ -186,13 +177,13 @@ multipart/form-data; boundary={{boundary}}'''; .map((entry) => '("${entry.key}", "${entry.value}")') .toList(); var paramsString = "[${tupleStrings.join(', ')}]"; - var templateParms = jj.Template(kTemplateRequestParams); + var templateParms = jj.Template(kTemplateParams); result += templateParms.render({"params": paramsString}); } } var headersList = requestModel.enabledRequestHeaders; - if (headersList != null) { + if (headersList != null || hasBody || requestModel.isFormDataRequest) { var headers = requestModel.enabledHeadersMap; if (requestModel.isFormDataRequest) { var formHeaderTemplate = @@ -200,15 +191,13 @@ multipart/form-data; boundary={{boundary}}'''; headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({ "boundary": uuid, }); + } else if (hasBody) { + headers[HttpHeaders.contentTypeHeader] = + requestModel.requestBodyContentType.header; } if (headers.isNotEmpty) { - if (hasBody) { - headers[HttpHeaders.contentTypeHeader] = - requestModel.requestBodyContentType.header; - } - - var templateHeaders = jj.Template(kTemplateRequestHeaders); + var templateHeaders = jj.Template(kTemplateHeaders); result += templateHeaders.render({"headers": headers}); } } diff --git a/test/codegen/rust_actix_codegen_test.dart b/test/codegen/rust_actix_codegen_test.dart new file mode 100644 index 00000000..567f64b6 --- /dev/null +++ b/test/codegen/rust_actix_codegen_test.dart @@ -0,0 +1,564 @@ +import 'package:apidash/codegen/rust/actix.dart'; +import '../request_models.dart'; +import 'package:test/test.dart'; + +void main() { + final rustActixCodeGen = RustActixCodeGen(); + + group('GET Request', () { + test('GET 1', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelGet1, "https"), expectedCode); + }); + + test('GET 2', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com/country/data"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("code", "US")]) + .unwrap() + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelGet2, "https"), expectedCode); + }); + + test('GET 3', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com/country/data"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("code", "IND")]) + .unwrap() + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelGet3, "https"), expectedCode); + }); + + test('GET 4', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com/humanize/social"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("num", "8700000"), ("digits", "3"), ("system", "SS"), ("add_space", "true"), ("trailing_zeros", "true")]) + .unwrap() + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelGet4, "https"), expectedCode); + }); + + test('GET 5', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.github.com/repos/foss42/apidash"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .insert_header(("User-Agent", "Test Agent")) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelGet5, "https"), expectedCode); + }); + + test('GET 6', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.github.com/repos/foss42/apidash"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("raw", "true")]) + .unwrap() + .insert_header(("User-Agent", "Test Agent")) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelGet6, "https"), expectedCode); + }); + + test('GET 7', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelGet7, "https"), expectedCode); + }); + + test('GET 8', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.github.com/repos/foss42/apidash"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("raw", "true")]) + .unwrap() + .insert_header(("User-Agent", "Test Agent")) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelGet8, "https"), expectedCode); + }); + + test('GET 9', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com/humanize/social"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("num", "8700000"), ("add_space", "true")]) + .unwrap() + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelGet9, "https"), expectedCode); + }); + + test('GET 10', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com/humanize/social"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .insert_header(("User-Agent", "Test Agent")) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + rustActixCodeGen.getCode( + requestModelGet10, + "https", + ), + expectedCode); + }); + + test('GET 11', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com/humanize/social"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .query(&[("num", "8700000"), ("digits", "3")]) + .unwrap() + .insert_header(("User-Agent", "Test Agent")) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + rustActixCodeGen.getCode(requestModelGet11, "https"), expectedCode); + }); + + test('GET 12', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com/humanize/social"; + let client = awc::Client::default(); + + let mut response = client + .get(url) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + rustActixCodeGen.getCode(requestModelGet12, "https"), expectedCode); + }); + }); + + group('HEAD Request', () { + test('HEAD 1', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com"; + let client = awc::Client::default(); + + let mut response = client + .head(url) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + rustActixCodeGen.getCode(requestModelHead1, "https"), expectedCode); + }); + + test('HEAD 2', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "http://api.foss42.com"; + let client = awc::Client::default(); + + let mut response = client + .head(url) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelHead2, "http"), expectedCode); + }); + }); + + group('POST Request', () { + test('POST 1', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com/case/lower"; + let client = awc::Client::default(); + + let payload = r#"{ +"text": "I LOVE Flutter" +}"#; + + let mut response = client + .post(url) + .insert_header(("content-type", "text/plain")) + .send_body(payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + rustActixCodeGen.getCode(requestModelPost1, "https"), expectedCode); + }); + + test('POST 2', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com/case/lower"; + let client = awc::Client::default(); + + let payload = serde_json::json!({ +"text": "I LOVE Flutter" +}); + + let mut response = client + .post(url) + .send_json(&payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + rustActixCodeGen.getCode(requestModelPost2, "https"), expectedCode); + }); + + test('POST 3', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://api.foss42.com/case/lower"; + let client = awc::Client::default(); + + let payload = serde_json::json!({ +"text": "I LOVE Flutter" +}); + + let mut response = client + .post(url) + .insert_header(("User-Agent", "Test Agent")) + .send_json(&payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + rustActixCodeGen.getCode(requestModelPost3, "https"), expectedCode); + }); + }); + + group('PUT Request', () { + test('PUT 1', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://reqres.in/api/users/2"; + let client = awc::Client::default(); + + let payload = serde_json::json!({ +"name": "morpheus", +"job": "zion resident" +}); + + let mut response = client + .put(url) + .send_json(&payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect(rustActixCodeGen.getCode(requestModelPut1, "https"), expectedCode); + }); + }); + + group('PATCH Request', () { + test('PATCH 1', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://reqres.in/api/users/2"; + let client = awc::Client::default(); + + let payload = serde_json::json!({ +"name": "marfeus", +"job": "accountant" +}); + + let mut response = client + .patch(url) + .send_json(&payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + rustActixCodeGen.getCode(requestModelPatch1, "https"), expectedCode); + }); + }); + + group('DELETE Request', () { + test('DELETE 1', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://reqres.in/api/users/2"; + let client = awc::Client::default(); + + let mut response = client + .delete(url) + .send() + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + rustActixCodeGen.getCode(requestModelDelete1, "https"), expectedCode); + }); + + test('DELETE 2', () { + const expectedCode = r"""#[actix_rt::main] +async fn main() -> Result<(), Box> { + let url = "https://reqres.in/api/users/2"; + let client = awc::Client::default(); + + let payload = serde_json::json!({ +"name": "marfeus", +"job": "accountant" +}); + + let mut response = client + .delete(url) + .send_json(&payload) + .await + .unwrap(); + + let body_bytes = response.body().await.unwrap(); + let body = std::str::from_utf8(&body_bytes).unwrap(); + println!("Response Status: {}", response.status()); + println!("Response: {:?}", body); + + Ok(()) +} +"""; + expect( + rustActixCodeGen.getCode(requestModelDelete2, "https"), expectedCode); + }); + }); +}