-
Notifications
You must be signed in to change notification settings - Fork 241
Add target for Reqwest library for Rust #242
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| { | ||
| "version": "2.0.0", | ||
| "version": "2.1.0", | ||
| "name": "httpsnippet", | ||
| "description": "HTTP Request snippet generator for *most* languages", | ||
| "author": "Ahmad Nassri <[email protected]> (https://www.mashape.com/)", | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| const OriginalCodeBuilder = require('../../helpers/code-builder') | ||
| class CodeBuilder extends OriginalCodeBuilder { | ||
| constructor(indent = ' ', join = '\n', defaultLevel = 0) { | ||
| super(indent, join) | ||
| this.indentLevel = defaultLevel | ||
| } | ||
|
|
||
| /** Current indentation level */ | ||
| indentLevel = 0 | ||
|
|
||
| /** | ||
| * Increase indentation level | ||
| * | ||
| * @returns {this} | ||
| */ | ||
| indent() { | ||
| this.indentLevel++ | ||
| return this | ||
| } | ||
| /** | ||
| * Decrease indentation level | ||
| * | ||
| * @returns {this} | ||
| */ | ||
| unindent() { | ||
| this.indentLevel-- | ||
| return this | ||
| } | ||
| /** | ||
| * Reset indentation level | ||
| * | ||
| * @returns {this} | ||
| */ | ||
| reindent() { | ||
| this.indentLevel = 0 | ||
| return this | ||
| } | ||
|
|
||
| /** @inheritdoc */ | ||
| push(str) { | ||
| return super.push(this.indentLevel, str) | ||
| } | ||
| } | ||
|
|
||
| module.exports = CodeBuilder |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| 'use strict' | ||
|
|
||
| module.exports = { | ||
| info: { | ||
| key: 'rust', | ||
| title: 'Rust', | ||
| extname: '.rs', | ||
| default: 'reqwest' | ||
| }, | ||
|
|
||
| reqwest: require('./reqwest'), | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| /** | ||
| * @typedef {Object} Features | ||
| * @property {bool} fullMethod Whether the request method should be written in full form | ||
| * @property {bool} inlineMethod Whether the request method can be written in inline form | ||
| * @property {bool} headers Whether the request has custom headers | ||
| * @property {bool} query Whether the request has custom url query | ||
| * @property {bool} raw Whether the request has post data of any type | ||
| * @property {bool} form Whether the request has post data of type form | ||
| * @property {bool} json Whether the request has post data of type json | ||
| * @property {bool} body Whether the request has post data of other type | ||
| */ | ||
|
|
||
| /** Methods that can be inlined, e.g. `client.get(...)` */ | ||
| const inlineMethods = ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'PATCH'] | ||
| /** Methods that can not be inlined, so we should do this: client.request(Method::OPTIONS, ...) */ | ||
| const fullMethods = ['OPTIONS', 'CONNECT', 'TRACE'] | ||
|
|
||
| /** | ||
| * @param {any} data | ||
| * @returns {bool} If the value is truthy, and in case of object, has at least 1 key | ||
| */ | ||
| function isSet(data) { | ||
| if (!data) return false | ||
| if (typeof data !== 'object') return !!data | ||
| return Object.keys(data).length > 0 | ||
| } | ||
|
|
||
| /** | ||
| * | ||
| * @param {object} source HAR object processed by the library | ||
| * @param {Options} options Options passed to the generator function | ||
| * @returns {Features} | ||
| */ | ||
| function inferFeatures(source, options) { | ||
| const fullMethod = fullMethods.includes(source.method) | ||
| const inlineMethod = inlineMethods.includes(source.method) | ||
| const headers = isSet(source.queryObj) | ||
| const query = options.expandQuery && isSet(source.queryObj) | ||
| const raw = isSet(source.postData.text) | ||
| const form = options.expandBody && isSet(source.postData.paramsObj) | ||
| const json = options.expandBody && isSet(source.postData.jsonObj) | ||
| const body = !form && !json && raw | ||
|
|
||
| return { fullMethod, inlineMethod, headers, query, raw, form, json, body } | ||
| } | ||
|
|
||
| module.exports = inferFeatures |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,131 @@ | ||
| /** | ||
| * @description | ||
| * HTTP code snippet generator for Rust using Reqwest | ||
| * | ||
| * @author | ||
| * @eeWynell | ||
| * | ||
| * for any questions or issues regarding the generated code snippet, please open an issue mentioning the author. | ||
| */ | ||
|
|
||
| /** | ||
| * @typedef {Object} Options | ||
| * @property {bool} blocking Whether the request should be blocking | ||
| * @property {bool} boilerplate Whether to show boilerplate code | ||
| * @property {bool} print Whether to print the response | ||
| * @property {bool} expandQuery Whether to expand the url query | ||
| * @property {bool} expandBody Whether to expand the body | ||
| */ | ||
|
|
||
| 'use strict' | ||
|
|
||
| const str = require('./str') | ||
| const inferFeatures = require('./infer-features') | ||
| const CodeBuilder = require('./code-builder') | ||
|
|
||
| /** | ||
| * @param {object} source | ||
| * @param {Options} options | ||
| * @returns {string} Code | ||
| */ | ||
| module.exports = function (source, options) { | ||
| options = Object.assign( | ||
| { | ||
| blocking: true, | ||
| boilerplate: true, | ||
| print: true, | ||
| expandQuery: false, | ||
| expandBody: true, | ||
| }, | ||
| options | ||
| ) | ||
|
|
||
| const features = inferFeatures(source, options) | ||
| const code = new CodeBuilder() | ||
|
|
||
| if (options.boilerplate) { | ||
| if (options.blocking) code.push('use reqwest::blocking::Client;') | ||
| else code.push('use tokio;').push('use reqwest::Client;') | ||
|
|
||
| if (features.fullMethod) code.push('reqwest::Client') | ||
| if (features.headers) code.push('use reqwest::header::HeaderMap;') | ||
| if (features.json) code.push('use serde_json::json;') | ||
| if (features.query || features.form) code.push('use maplit::hashmap;') | ||
|
|
||
| code.blank() | ||
| if (options.blocking) code.push('fn main() {') | ||
| else code.push('#[tokio::main]').push('async fn main() {') | ||
| code.indent() | ||
| } | ||
|
|
||
| code.push('let client = Client::new();').blank() | ||
|
|
||
| if (features.headers) { | ||
| code.push('let mut headers = HeaderMap::new();') | ||
| for (const [name, value] of Object.entries(source.headersObj)) { | ||
| code.push(str`headers.insert("${name}", "${value}".parse().unwrap());`) | ||
| } | ||
| code.blank() | ||
| } | ||
|
|
||
| if (features.query) { | ||
| code.push('let query = hashmap!{').indent() | ||
| for (const [name, value] of Object.entries(source.queryObj)) { | ||
| code.push(str`"${name}" => vec!${[].concat(value)},`) | ||
| } | ||
| code.unindent().push('};').blank() | ||
| } | ||
|
|
||
| if (features.form) { | ||
| code.push('let form = hashmap!{').indent() | ||
| for (const [name, value] of Object.entries(source.postData.paramsObj)) { | ||
| code.push(str`"${name}" => vec!${[].concat(value)},`) | ||
| } | ||
| code.unindent().push('};').blank() | ||
| } | ||
|
|
||
| if (features.json) { | ||
| code.push(str`let json = json!("${source.postData.jsonObj}");`).blank() | ||
| } | ||
|
|
||
| if (features.body) { | ||
| code.push(str`let body = "${source.postData.text}";`).blank() | ||
| } | ||
|
|
||
| code.push('let resp = client').indent() | ||
|
|
||
| const method = source.method | ||
| const url = options.expandQuery ? source.url : source.fullUrl | ||
|
|
||
| if (features.inlineMethod) code.push(`.${method.toLowerCase()}("${url}")`) | ||
| else if (features.fullMethod) code.push(`.request(Method::${method})`) | ||
| else code.push(`.post("${url}") //! Can't use method "${method}"`) | ||
|
|
||
| if (features.headers) code.push('.headers(headers)') | ||
| if (features.query) code.push('.query(&query)') | ||
| if (features.form) code.push('.form(&form)') | ||
| if (features.json) code.push('.json(&json)') | ||
| if (features.body) code.push('.body(body)') | ||
|
|
||
| if (options.blocking) code.push('.send()').push('.unwrap();') | ||
| else code.push('.send()').push('.await').push('.unwrap();') | ||
|
|
||
| code.unindent() | ||
|
|
||
| if (options.print) { | ||
| code.blank().push('println!("{:?}", resp);') | ||
| } | ||
|
|
||
| if (options.boilerplate) { | ||
| code.unindent().push('}').blank() | ||
| } | ||
|
|
||
| return code.join() | ||
| } | ||
|
|
||
| module.exports.info = { | ||
| key: 'reqwest', | ||
| title: 'Reqwest', | ||
| link: 'https://docs.rs/reqwest/', | ||
| description: 'HTTP Request using Reqwest library for Rust', | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| /** | ||
| * Turns data into a string, without adding quotes | ||
| * | ||
| * @param {any} data Any data to be stringified | ||
| * @returns {string} | ||
| */ | ||
| function stringify(data) { | ||
| if (typeof data === 'object') return JSON.stringify(data) | ||
| return String(data) | ||
| } | ||
|
|
||
| /** | ||
| * Escapes characters in the given string | ||
| * | ||
| * @param {string} data String to escape | ||
| * @returns {string} | ||
| */ | ||
| function escape(data) { | ||
| return JSON.stringify(data).slice(1, -1) | ||
| } | ||
|
|
||
| /** | ||
| * Looks like a reason to use a ES6 tag function first time in my life | ||
| * Also if you replace `parts` with `parts.raw`, you will avoid escaping characters in the template | ||
| * | ||
| * @example | ||
| * let test = { "foo": "bar" } | ||
| * str`unquoted ${test}, quoted "${test}"` | ||
| * // unquoted {"foo":"bar"}, quoted "{\"foo\":\"bar\"}" | ||
| * | ||
| * @param {string[]} parts Template literal string parts | ||
| * @param {...string} args Template literal expressions | ||
| * | ||
| * @returns {string} The same string but expressions are JSON-stringified | ||
| */ | ||
| function str(parts, ...args) { | ||
| let [res, ...rest] = parts | ||
| for (i = 0; i < rest.length; i++) { | ||
| let expr = stringify(args[i]) | ||
| let nextTmpl = rest[i] | ||
| if (res.endsWith('"') && nextTmpl.startsWith('"')) { | ||
| expr = escape(expr) | ||
| } | ||
| res += expr + nextTmpl | ||
| } | ||
| return res | ||
| } | ||
|
|
||
| module.exports = str |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| 'use strict' | ||
|
|
||
| module.exports = function (snippet, fixtures) {} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't need to do this in a PR, when they publish a release they'll handle this.