Skip to content

Commit

Permalink
Merge pull request #683 from postmanlabs/feature/rust-codegen
Browse files Browse the repository at this point in the history
Code Snippet generation for Rust's reqwest library
  • Loading branch information
Dhwaneet Bhatt committed Mar 24, 2023
2 parents 3c0f1ee + 771de57 commit 5a9668f
Show file tree
Hide file tree
Showing 44 changed files with 1,277 additions and 48 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/integration.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
name: Test

on: [push, pull_request]
on:
push:
branches:
- develop
- master
pull_request:

jobs:
Unit-Tests:
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,11 @@ typings/
# next.js build output
.next

out/
# Cargo
target/

# Newman test generated files
out/
newmanResponses.json
dummyFile*.txt
dummyBinaryFile
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,16 @@ List of supported code generators:
| NodeJs | Unirest |
| Objective-C| NSURLSession|
| OCaml | Cohttp |
|PHP | cURL |
|PHP | Guzzle |
|PHP | pecl_http |
|PHP | HTTP_Request2 |
| PHP | cURL |
| PHP | Guzzle |
| PHP | pecl_http |
| PHP | HTTP_Request2 |
| PowerShell | RestMethod |
| Python | http.client |
| Python | Requests |
| R | httr |
| R | RCurl |
| Rust | Reqwest |
| Ruby | Net:HTTP |
| Shell | Httpie |
| Shell | wget |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1115,7 +1115,7 @@
"response": []
},
{
"name": "PROFIND request",
"name": "PROPFIND request",
"request": {
"method": "PROPFIND",
"header": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,7 @@
"response": []
},
{
"name": "PROFIND request",
"name": "PROPFIND request",
"request": {
"method": "PROPFIND",
"header": [
Expand Down
2 changes: 1 addition & 1 deletion codegens/http/test/resources/test-collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -1046,7 +1046,7 @@
"response": []
},
{
"name": "PROFIND request",
"name": "PROPFIND request",
"request": {
"method": "PROPFIND",
"header": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1240,7 +1240,7 @@
"response": []
},
{
"name": "PROFIND request",
"name": "PROPFIND request",
"request": {
"method": "PROPFIND",
"header": [
Expand Down
2 changes: 1 addition & 1 deletion codegens/js-jquery/test/unit/fixtures/snippetFixtures.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"UNLINK request": "var%20settings%20%3D%20%7B%0A%20%20%20%20%22url%22%3A%20%22https%3A//mockbin.org/request%22%2C%0A%20%20%20%20%22method%22%3A%20%22UNLINK%22%2C%0A%20%20%20%20%22timeout%22%3A%20100%2C%0A%20%20%20%20%22headers%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22Content-Type%22%3A%20%22text/plain%22%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22data%22%3A%20%22Duis%20posuere%20augue%20vel%20cursus%20pharetra.%20In%20luctus%20a%20ex%20nec%20pretium.%20Praesent%20neque%20quam%2C%20tincidunt%20nec%20leo%20eget%2C%20rutrum%20vehicula%20magna.%5CnMaecenas%20consequat%20elementum%20elit%2C%20id%20semper%20sem%20tristique%20et.%20Integer%20pulvinar%20enim%20quis%20consectetur%20interdum%20volutpat.%22%2C%0A%7D%3B%0A%0A%24.ajax%28settings%29.done%28function%20%28response%29%20%7B%0A%20%20%20%20console.log%28response%29%3B%0A%7D%29%3B",
"LOCK request": "var%20settings%20%3D%20%7B%0A%20%20%20%20%22url%22%3A%20%22https%3A//mockbin.org/request%22%2C%0A%20%20%20%20%22method%22%3A%20%22LOCK%22%2C%0A%20%20%20%20%22timeout%22%3A%20100%2C%0A%20%20%20%20%22headers%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22Content-Type%22%3A%20%22text/plain%22%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22data%22%3A%20%22Duis%20posuere%20augue%20vel%20cursus%20pharetra.%20In%20luctus%20a%20ex%20nec%20pretium.%20Praesent%20neque%20quam%2C%20tincidunt%20nec%20leo%20eget%2C%20rutrum%20vehicula%20magna.%5CnMaecenas%20consequat%20elementum%20elit%2C%20id%20semper%20sem%20tristique%20et.%20Integer%20pulvinar%20enim%20quis%20consectetur%20interdum%20volutpat.%22%2C%0A%7D%3B%0A%0A%24.ajax%28settings%29.done%28function%20%28response%29%20%7B%0A%20%20%20%20console.log%28response%29%3B%0A%7D%29%3B",
"UNLOCK request": "var%20settings%20%3D%20%7B%0A%20%20%20%20%22url%22%3A%20%22https%3A//mockbin.org/request%22%2C%0A%20%20%20%20%22method%22%3A%20%22UNLOCK%22%2C%0A%20%20%20%20%22timeout%22%3A%20100%2C%0A%7D%3B%0A%0A%24.ajax%28settings%29.done%28function%20%28response%29%20%7B%0A%20%20%20%20console.log%28response%29%3B%0A%7D%29%3B",
"PROFIND request": "var%20settings%20%3D%20%7B%0A%20%20%20%20%22url%22%3A%20%22https%3A//mockbin.org/request%22%2C%0A%20%20%20%20%22method%22%3A%20%22PROPFIND%22%2C%0A%20%20%20%20%22timeout%22%3A%20100%2C%0A%20%20%20%20%22headers%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22Content-Type%22%3A%20%22text/plain%22%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22data%22%3A%20%22Duis%20posuere%20augue%20vel%20cursus%20pharetra.%20In%20luctus%20a%20ex%20nec%20pretium.%20Praesent%20neque%20quam%2C%20tincidunt%20nec%20leo%20eget%2C%20rutrum%20vehicula%20magna.%5CnMaecenas%20consequat%20elementum%20elit%2C%20id%20semper%20sem%20tristique%20et.%20Integer%20pulvinar%20enim%20quis%20consectetur%20interdum%20volutpat.%22%2C%0A%7D%3B%0A%0A%24.ajax%28settings%29.done%28function%20%28response%29%20%7B%0A%20%20%20%20console.log%28response%29%3B%0A%7D%29%3B",
"PROPFIND request": "var%20settings%20%3D%20%7B%0A%20%20%20%20%22url%22%3A%20%22https%3A//mockbin.org/request%22%2C%0A%20%20%20%20%22method%22%3A%20%22PROPFIND%22%2C%0A%20%20%20%20%22timeout%22%3A%20100%2C%0A%20%20%20%20%22headers%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22Content-Type%22%3A%20%22text/plain%22%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22data%22%3A%20%22Duis%20posuere%20augue%20vel%20cursus%20pharetra.%20In%20luctus%20a%20ex%20nec%20pretium.%20Praesent%20neque%20quam%2C%20tincidunt%20nec%20leo%20eget%2C%20rutrum%20vehicula%20magna.%5CnMaecenas%20consequat%20elementum%20elit%2C%20id%20semper%20sem%20tristique%20et.%20Integer%20pulvinar%20enim%20quis%20consectetur%20interdum%20volutpat.%22%2C%0A%7D%3B%0A%0A%24.ajax%28settings%29.done%28function%20%28response%29%20%7B%0A%20%20%20%20console.log%28response%29%3B%0A%7D%29%3B",
"VIEW request": "var%20settings%20%3D%20%7B%0A%20%20%20%20%22url%22%3A%20%22https%3A//mockbin.org/request%22%2C%0A%20%20%20%20%22method%22%3A%20%22VIEW%22%2C%0A%20%20%20%20%22timeout%22%3A%20100%2C%0A%20%20%20%20%22headers%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22Content-Type%22%3A%20%22text/plain%22%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22data%22%3A%20%22Duis%20posuere%20augue%20vel%20cursus%20pharetra.%20In%20luctus%20a%20ex%20nec%20pretium.%20Praesent%20neque%20quam%2C%20tincidunt%20nec%20leo%20eget%2C%20rutrum%20vehicula%20magna.%5CnMaecenas%20consequat%20elementum%20elit%2C%20id%20semper%20sem%20tristique%20et.%20Integer%20pulvinar%20enim%20quis%20consectetur%20interdum%20volutpat.%22%2C%0A%7D%3B%0A%0A%24.ajax%28settings%29.done%28function%20%28response%29%20%7B%0A%20%20%20%20console.log%28response%29%3B%0A%7D%29%3B",
"PURGE Request": "var%20settings%20%3D%20%7B%0A%20%20%20%20%22url%22%3A%20%22https%3A//9c76407d-5b8d-4b22-99fb-8c47a85d9848.mock.pstmn.io%22%2C%0A%20%20%20%20%22method%22%3A%20%22PURGE%22%2C%0A%20%20%20%20%22timeout%22%3A%20100%2C%0A%7D%3B%0A%0A%24.ajax%28settings%29.done%28function%20%28response%29%20%7B%0A%20%20%20%20console.log%28response%29%3B%0A%7D%29%3B",
"COPY Request": "var%20settings%20%3D%20%7B%0A%20%20%20%20%22url%22%3A%20%22https%3A//9c76407d-5b8d-4b22-99fb-8c47a85d9848.mock.pstmn.io%22%2C%0A%20%20%20%20%22method%22%3A%20%22COPY%22%2C%0A%20%20%20%20%22timeout%22%3A%20100%2C%0A%7D%3B%0A%0A%24.ajax%28settings%29.done%28function%20%28response%29%20%7B%0A%20%20%20%20console.log%28response%29%3B%0A%7D%29%3B"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1055,7 +1055,7 @@
"response": []
},
{
"name": "PROFIND request",
"name": "PROPFIND request",
"request": {
"method": "PROPFIND",
"header": [
Expand Down
13 changes: 7 additions & 6 deletions codegens/kotlin-okhttp/lib/okhttp.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ const METHODS_WITHOUT_BODY = ['GET', 'HEAD', 'COPY', 'UNLOCK', 'UNLINK', 'PURGE'
function makeSnippet (request, indentString, options) {
let isBodyRequired = !(_.includes(METHODS_WITHOUT_BODY, request.method)),
snippet = 'val client = OkHttpClient',
hasNoOptions = !(options.requestTimeout || options.followRedirects),
requestBody;
hasNoOptions = !(options.requestTimeout || options.followRedirects);

if (hasNoOptions) {
snippet += '()\n';
Expand All @@ -30,7 +29,7 @@ function makeSnippet (request, indentString, options) {
snippet += indentString + `.connectTimeout(${options.requestTimeout}, TimeUnit.SECONDS)\n`;
}

if (!options.followRedirect) {
if (_.get(request, 'protocolProfileBehavior.followRedirects', options.followRedirect) === false) {
snippet += indentString + '.followRedirects(false)\n';
}

Expand Down Expand Up @@ -73,10 +72,12 @@ function makeSnippet (request, indentString, options) {
formdata: formdataArray
});
}
requestBody = (request.body ? request.body.toJSON() : {});

const contentType = parseRequest.parseContentType(request),
requestBody = (request.body ? request.body.toJSON() : {});
// snippet for creating mediatype object in java based on content-type of request
snippet += `val mediaType = "${parseRequest.parseContentType(request)}".toMediaType()\n`;
snippet += parseRequest.parseBody(requestBody, indentString, options.trimRequestBody);
snippet += `val mediaType = "${contentType}".toMediaType()\n`;
snippet += parseRequest.parseBody(requestBody, indentString, options.trimRequestBody, contentType);
}

snippet += 'val request = Request.Builder()\n';
Expand Down
21 changes: 19 additions & 2 deletions codegens/kotlin-okhttp/lib/parseRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,38 @@ function parseFormData (requestBody, indentString, trimFields) {
}, '') + indentString + '.build()';
}

/**
* Parses request object and returns kotlin okhttp code snippet for raw body
*
* @param {Object} requestBody - JSON object representing body of request
* @param {Boolean} trimFields - indicates whether to trim fields of body
* @param {String} contentType - content type of request body
*/
function parseRawBody (requestBody, trimFields, contentType) {
if (contentType && contentType.startsWith('application/json')) {
return `val body = ${JSON.stringify(requestBody[requestBody.mode])}.toRequestBody(mediaType)\n`;
}

return `val body = "${sanitize(requestBody[requestBody.mode], trimFields)}".toRequestBody(mediaType)\n`;
}

/**
* parses request object and returns java okhttp code snippet for adding request body
*
* @param {Object} requestBody - JSON object representing body of request
* @param {String} indentString - string for indentation
* @param {Boolean} trimFields - indicates whether to trim fields of body
* @param {String} contentType - content type of request body
*
* @returns {String} - code snippet of java okhttp parsed from request object
*/
function parseBody (requestBody, indentString, trimFields) {
function parseBody (requestBody, indentString, trimFields, contentType) {
if (!_.isEmpty(requestBody)) {
switch (requestBody.mode) {
case 'urlencoded':
return `val body = "${parseUrlencode(requestBody, trimFields)}".toRequestBody(mediaType)\n`;
case 'raw':
return `val body = ${JSON.stringify(requestBody[requestBody.mode])}.toRequestBody(mediaType)\n`;
return parseRawBody(requestBody, trimFields, contentType);
case 'graphql':
// eslint-disable-next-line no-case-declarations
let query = requestBody[requestBody.mode].query,
Expand Down
8 changes: 7 additions & 1 deletion codegens/kotlin-okhttp/lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ module.exports = {
if (typeof inputString !== 'string') {
return '';
}
inputString = inputString.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
inputString = inputString
.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"')
.replace(/\$/g, '\\$')
.replace(/\n/g, '\\n')
.replace(/\r/g, '\\r')
.replace(/\t/g, '\\t');
return trim ? inputString.trim() : inputString;

},
Expand Down
8 changes: 4 additions & 4 deletions codegens/kotlin-okhttp/package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"name": "@postman/codegen-kotlin-okhttp",
"version": "0.0.1",
"description": "Converts postman request into kotlin ktor code snippet",
"description": "Converts postman request into kotlin okhttp code snippet",
"com_postman_plugin": {
"type": "code_generator",
"lang": "kotlin",
"variant": "Ktor",
"syntax_mode": "java"
"lang": "Kotlin",
"variant": "Okhttp",
"syntax_mode": "kotlin"
},
"main": "index.js",
"directories": {
Expand Down
2 changes: 1 addition & 1 deletion codegens/kotlin-okhttp/test/unit/validation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ describe('package.json', function () {
expect(package.com_postman_plugin.type).to.equal('code_generator');
expect(package.com_postman_plugin.lang).to.be.a('string');
expect(package.com_postman_plugin.variant).to.be.a('string');
expect(package.com_postman_plugin.syntax_mode).to.be.equal('java');
expect(package.com_postman_plugin.syntax_mode).to.be.equal('kotlin');
});
it('should have main property with relative path to object with convert property', function () {
var languageModule;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1141,7 +1141,7 @@
"response": []
},
{
"name": "PROFIND request",
"name": "PROPFIND request",
"request": {
"method": "PROPFIND",
"header": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1176,7 +1176,7 @@
"response": []
},
{
"name": "PROFIND request",
"name": "PROPFIND request",
"request": {
"method": "PROPFIND",
"header": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1236,7 +1236,7 @@
"response": []
},
{
"name": "PROFIND request",
"name": "PROPFIND request",
"request": {
"method": "PROPFIND",
"header": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1236,7 +1236,7 @@
"response": []
},
{
"name": "PROFIND request",
"name": "PROPFIND request",
"request": {
"method": "PROPFIND",
"header": [
Expand Down
2 changes: 1 addition & 1 deletion codegens/r-httr/test/unit/fixtures/sample_collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -1238,7 +1238,7 @@
"response": []
},
{
"name": "PROFIND request",
"name": "PROPFIND request",
"request": {
"method": "PROPFIND",
"header": [
Expand Down
2 changes: 1 addition & 1 deletion codegens/r-rcurl/test/unit/fixtures/sample_collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -1236,7 +1236,7 @@
"response": []
},
{
"name": "PROFIND request",
"name": "PROPFIND request",
"request": {
"method": "PROPFIND",
"header": [
Expand Down
72 changes: 72 additions & 0 deletions codegens/rust-reqwest/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
.DS_Store
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Prevent IDE stuff
.idea
.vscode
*.sublime-*

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
.coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Typescript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env

out/

# Cargo
target/
src/
Cargo.toml
Cargo.lock
Loading

0 comments on commit 5a9668f

Please sign in to comment.