2019-10-19 21:39:53 +00:00
|
|
|
const changeCase = require('change-case');
|
|
|
|
|
2019-10-19 09:25:09 +00:00
|
|
|
// flatMap: https://gist.github.com/samgiles/762ee337dff48623e729
|
|
|
|
// [B](f: (A) ⇒ [B]): [B] ; Although the types in the arrays aren't strict (:
|
|
|
|
Array.prototype.flatMap = function(lambda) {
|
|
|
|
return Array.prototype.concat.apply([], this.map(lambda));
|
|
|
|
};
|
|
|
|
Array.prototype.groupBy = function(lambda) {
|
|
|
|
return Object.entries(this.reduce((agg, x) => {
|
|
|
|
const k = lambda(x);
|
|
|
|
(agg[k] = agg[k] || []).push(x);
|
|
|
|
return agg;
|
|
|
|
}, {}));
|
|
|
|
}
|
|
|
|
|
2019-10-23 07:39:40 +00:00
|
|
|
function preamble() {
|
|
|
|
return `// This file is automatically generated.
|
2019-10-25 16:47:45 +00:00
|
|
|
// Do not directly edit.`;
|
2019-10-23 07:39:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-19 09:25:09 +00:00
|
|
|
function capitalize(input) {
|
|
|
|
return input[0].toUpperCase() + input.slice(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
function decapitalize(input) {
|
|
|
|
return input[0].toLowerCase() + input.slice(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
function normalizeSchemaName(name) {
|
|
|
|
return name.replace(/DTO/ig, '');
|
|
|
|
}
|
|
|
|
|
|
|
|
function normalizeArgName(name) {
|
2019-10-19 21:39:53 +00:00
|
|
|
const tokens = name.split('_');
|
|
|
|
const argName = decapitalize(tokens.map(capitalize).join(''));
|
2019-10-19 09:25:09 +00:00
|
|
|
return 'base' === argName ? 'Base' : argName;
|
|
|
|
}
|
|
|
|
|
|
|
|
function normalizePropName(propName, schemaName, value) {
|
2019-10-19 21:39:53 +00:00
|
|
|
const out = changeCase.snakeCase(propName);
|
|
|
|
if ('type' === out)
|
|
|
|
return 'r#' + out;
|
|
|
|
return out;
|
|
|
|
// return propName;
|
|
|
|
// var tokens = propName.split('_');
|
|
|
|
// var name = tokens.map(capitalize).join('');
|
|
|
|
// if (name === schemaName)
|
|
|
|
// name += stringifyType(value);
|
|
|
|
// return name;
|
2019-10-19 09:25:09 +00:00
|
|
|
}
|
|
|
|
|
2019-10-19 21:39:53 +00:00
|
|
|
function stringifyType(prop, endpoint = null, optional = false, fullpath = true, owned = true) {
|
2019-10-19 09:25:09 +00:00
|
|
|
if (prop.anyOf) {
|
|
|
|
prop = prop.anyOf[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
let refType = prop['$ref'];
|
|
|
|
if (refType) {
|
2019-10-22 21:28:23 +00:00
|
|
|
return (!endpoint ? '' : changeCase.snakeCase(endpoint) + '::') +
|
2019-10-19 09:25:09 +00:00
|
|
|
normalizeSchemaName(refType.slice(refType.indexOf('.') + 1));
|
|
|
|
}
|
2019-10-19 21:39:53 +00:00
|
|
|
if (optional) {
|
|
|
|
return `Option<${stringifyType(prop, endpoint, false, fullpath)}>`;
|
|
|
|
}
|
2019-10-19 09:25:09 +00:00
|
|
|
switch (prop.type) {
|
2019-10-19 21:39:53 +00:00
|
|
|
case 'boolean': return 'bool';
|
|
|
|
case 'integer': return ('int32' === prop.format ? 'i32' : 'i64');
|
|
|
|
case 'number': return ('float' === prop.format ? 'f32' : 'f64');
|
|
|
|
case 'array':
|
|
|
|
const subprop = stringifyType(prop.items, endpoint, optional, fullpath, owned);
|
|
|
|
return (owned ? (fullpath ? 'std::vec::' : '') + `Vec<${subprop}>` : `&[${subprop}]`);
|
|
|
|
case 'string': return (owned ? 'String' : '&str');
|
2019-10-19 09:25:09 +00:00
|
|
|
case 'object':
|
2019-10-19 21:39:53 +00:00
|
|
|
return 'std::collections::HashMap<' + stringifyType(prop['x-key'], endpoint, optional, fullpath, owned) + ', ' +
|
|
|
|
stringifyType(prop.additionalProperties, endpoint, optional, fullpath, owned) + '>';
|
|
|
|
default: return prop.type;
|
2019-10-19 09:25:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function formatJsonProperty(name) {
|
2019-10-19 21:39:53 +00:00
|
|
|
return `#[serde(rename = "${name}")]`;
|
2019-10-19 09:25:09 +00:00
|
|
|
}
|
|
|
|
|
2019-10-19 21:39:53 +00:00
|
|
|
function formatQueryParamStringify(name, prop, ownedOk = false) {
|
2019-10-19 09:25:09 +00:00
|
|
|
switch (prop.type) {
|
2019-10-19 21:39:53 +00:00
|
|
|
case 'boolean': return `${name} ? "true" : "false"`;
|
|
|
|
case 'string': return name;
|
|
|
|
default: return (ownedOk ? '' : '&*') + `${name}.to_string()`;
|
2019-10-19 09:25:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function formatAddQueryParam(param) {
|
2019-10-19 21:39:53 +00:00
|
|
|
let k = `"${param.name}"`;
|
|
|
|
let name = changeCase.snakeCase(param.name);
|
|
|
|
let nc = param.required ? '' : `if let Some(${name}) = ${name} `;
|
2019-10-19 09:25:09 +00:00
|
|
|
let prop = param.schema;
|
|
|
|
switch (prop.type) {
|
2019-10-19 21:39:53 +00:00
|
|
|
case 'array': return `${nc}{ query_params.extend_pairs(${name}.iter()`
|
|
|
|
+ `.map(|w| (${k}, ${formatQueryParamStringify("w", prop, true)}))); }`;
|
2019-10-19 09:25:09 +00:00
|
|
|
case 'object': throw 'unsupported';
|
|
|
|
default:
|
2019-10-19 21:39:53 +00:00
|
|
|
return `${nc}{ query_params.append_pair(${k}, ${formatQueryParamStringify(name, prop)}); }`;
|
2019-10-19 09:25:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-19 21:39:53 +00:00
|
|
|
function formatRouteArgument(route, pathParams = []) {
|
|
|
|
if (!pathParams.length)
|
2019-10-22 04:45:38 +00:00
|
|
|
return `"${route}".to_owned()`;
|
2019-10-19 21:39:53 +00:00
|
|
|
|
|
|
|
route = route.replace(/\{\S+?\}/g, '{}');
|
|
|
|
const args = pathParams
|
|
|
|
.map(({name}) => name)
|
|
|
|
.map(changeCase.snakeCase)
|
|
|
|
.join(', ');
|
|
|
|
return `format!("${route}", ${args})`;
|
|
|
|
}
|
|
|
|
|
2019-10-19 09:25:09 +00:00
|
|
|
module.exports = {
|
2019-10-19 21:39:53 +00:00
|
|
|
changeCase,
|
2019-10-23 07:39:40 +00:00
|
|
|
preamble,
|
2019-10-19 09:25:09 +00:00
|
|
|
capitalize,
|
|
|
|
decapitalize,
|
|
|
|
normalizeSchemaName,
|
|
|
|
normalizeArgName,
|
|
|
|
normalizePropName,
|
|
|
|
stringifyType,
|
|
|
|
formatJsonProperty,
|
2019-10-19 21:39:53 +00:00
|
|
|
formatAddQueryParam,
|
|
|
|
formatRouteArgument,
|
2019-10-19 09:25:09 +00:00
|
|
|
};
|