add custom date formats support

This commit is contained in:
Ivan Smolin 2022-03-04 17:18:20 +03:00
parent e320bb3826
commit fb77840875
5 changed files with 106 additions and 8 deletions

View File

@ -0,0 +1,7 @@
package ru.touchin.codegen;
public class TINetowrkingCodegenConstants {
public static final String DATE_FORMAT = "x-custom-date-format";
public static final String DATE_FORMAT_NAME = "x-codegen-date-format-name";
public static final String IS_ISO8601_DATE = "x-codegen-is-iso8601-date";
}

View File

@ -32,6 +32,8 @@ public class TINetworkingCodegen extends DefaultCodegenConfig {
private String[] responseAs = new String[0];
protected String sourceFolder = "Classes" + File.separator + "Swaggers";
private Map<String, String> allCustomDateFormats = new HashMap<>();
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
@ -223,6 +225,10 @@ public class TINetworkingCodegen extends DefaultCodegenConfig {
sourceFolder,
projectName + "+Servers.swift"));
supportingFiles.add(new SupportingFile("APIDateFormat.mustache",
sourceFolder,
"APIDateFormat.swift"));
copyFistAllOfProperties = true;
}
@ -479,9 +485,58 @@ public class TINetworkingCodegen extends DefaultCodegenConfig {
}
}
for (CodegenProperty property : codegenModel.allVars) {
Map<String, Object> vendorExtensions = property.getVendorExtensions();
boolean containsCustomDateFormat = vendorExtensions.containsKey(TINetowrkingCodegenConstants.DATE_FORMAT);
if (property.getIsDate()
|| property.getIsDateTime()
&& !containsCustomDateFormat) {
vendorExtensions.put(TINetowrkingCodegenConstants.IS_ISO8601_DATE, true);
} else if (containsCustomDateFormat) {
String customDateFormat = (String) vendorExtensions.get(TINetowrkingCodegenConstants.DATE_FORMAT);
String dateFormatName = customDateFormat.replace(".", "_")
.replaceAll("[^A-Za-z0-9_]", "");
vendorExtensions.put(TINetowrkingCodegenConstants.DATE_FORMAT_NAME, dateFormatName);
}
}
return codegenModel;
}
@Override
public Map<String, Object> postProcessAllModels(Map<String, Object> processedModels) {
for (Object processedModel : processedModels.values()) {
Map<String, Object> modelMap = (Map<String, Object>) processedModel;
List<Map<String, Object>> modelsMap = (List<Map<String, Object>>) modelMap.get("models");
for (Map<String, Object> modelModelsMap : modelsMap) {
CodegenModel codegenModel = (CodegenModel) modelModelsMap.get("model");
for (CodegenProperty modelProperty : codegenModel.getAllVars()) {
String customDateFormat = (String) modelProperty.getVendorExtensions()
.get(TINetowrkingCodegenConstants.DATE_FORMAT);
if (customDateFormat != null) {
String dateFormatName = (String) modelProperty.getVendorExtensions()
.get(TINetowrkingCodegenConstants.DATE_FORMAT_NAME);
allCustomDateFormats.put(dateFormatName, customDateFormat);
}
}
}
}
return super.postProcessAllModels(processedModels);
}
@Override
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
Map<String, Object> supportingFileData = super.postProcessSupportingFileData(objs);
supportingFileData.put("apiDateFormats", allCustomDateFormats);
return supportingFileData;
}
protected void updateCodegenModelEnumVars(CodegenModel codegenModel) {
super.updateCodegenModelEnumVars(codegenModel);
for (CodegenProperty var : codegenModel.allVars) {
@ -502,12 +557,7 @@ public class TINetworkingCodegen extends DefaultCodegenConfig {
ArrayList<String> contentStatusCodes = new ArrayList<>();
for (CodegenResponse codegenResponse : codegenOperation.responses) {
Schema schema = (Schema) codegenResponse.getSchema();
String responseContentType = (String) schema.getExtensions().get("x-content-type");
if (Objects.equals(responseContentType, content.getContentType())) {
contentStatusCodes.add(codegenResponse.code);
}
contentStatusCodes.add(codegenResponse.code);
}
content.getContentExtensions()

View File

@ -0,0 +1,8 @@
import TIFoundationUtils
import Foundation
enum APIDateFormat: String, DateFormat {
{{#each apiDateFormats as |value key|}}
case {{key}} = "{{{value}}}"
{{/each}}
}

View File

@ -36,10 +36,10 @@ public extension EndpointRequest {
- parameter {{paramName}}: {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/parameters}}
*/
static func {{operationId}}({{#parameters}}{{paramName}}: {{#isEnum}}{{#isContainer}}{{{dataType}}}{{/isContainer}}{{^isContainer}}{{{datatypeWithEnum}}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{#hasMore}}, {{/hasMore}}{{/parameters}}{{#hasParams}}, {{/hasParams}}server: Server = .default) -> EndpointRequest<{{#parameters}}{{{dataType}}}{{/parameters}}, {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {
static func {{operationId}}({{#parameters}}{{paramName}}: {{#isEnum}}{{#isContainer}}{{{dataType}}}{{/isContainer}}{{^isContainer}}{{{datatypeWithEnum}}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{#hasMore}}, {{/hasMore}}{{/parameters}}{{#hasParams}}, {{/hasParams}}server: Server = .default) -> EndpointRequest<{{#parameters}}{{#isBodyParam}}{{{dataType}}}{{/isBodyParam}}{{/parameters}}{{^hasBodyParam}}EmptyBody{{/hasBodyParam}}, {{{returnType}}}> {
.init(templatePath: "{{{path}}}",
method: .init(rawValue: "{{httpMethod}}"),
body: body,
body: {{#hasBodyParam}}body{{/hasBodyParam}}{{^hasBodyParam}}EmptyBody(){{/hasBodyParam}},
acceptableStatusCodes: [{{contentExtensions.x-codegen-acceptable-status-codes}}],
server: server)
}

View File

@ -20,11 +20,44 @@ public {{#useModelClasses}}class{{/useModelClasses}}{{^useModelClasses}}struct{{
{{/allVars}}
{{#hasVars}}
private enum CodingKeys: String, CodingKey {
{{#allVars}}
case {{name}}
{{/allVars}}
}
public init({{#allVars}}{{name}}: {{{datatypeWithEnum}}}{{^required}}? = nil{{/required}}{{#hasMore}}, {{/hasMore}}{{/allVars}}) {
{{#allVars}}
self.{{name}} = {{name}}
{{/allVars}}
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
{{#allVars}}
{{#if vendorExtensions.x-codegen-is-iso8601-date}}
{{name}} = try container.decodeDate(forKey: .{{name}}, using: try decoder.userInfo.iso8601DateFormatter(for: .{{#isDate}}withFullDate{{/isDate}}{{#isDateTime}}withInternetDateTime{{/isDateTime}}){{^required}}, required: false{{/required}})
{{else if vendorExtensions.x-custom-date-format}}
{{name}} = try container.decodeDate(forKey: .{{name}}, using: try decoder.userInfo.dateFormatter(for: APIDateFormat.{{vendorExtensions.x-codegen-date-format-name}}){{^required}}, required: false{{/required}})
{{else}}
{{name}} = try container.decode({{{datatypeWithEnum}}}{{^required}}?{{/required}}.self, forKey: .{{name}}{{^required}}, required: false{{/required}})
{{/if}}
{{/allVars}}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
{{#allVars}}
{{#if vendorExtensions.x-codegen-is-iso8601-date}}
try container.encode(date: {{name}}, forKey: .{{name}}, using: try encoder.userInfo.iso8601DateFormatter(for: .{{#isDate}}withFullDate{{/isDate}}{{#isDateTime}}withInternetDateTime{{/isDateTime}}){{^required}}, required: false{{/required}})
{{else if vendorExtensions.x-custom-date-format}}
try container.encode(date: {{name}}, forKey: .{{name}}, using: try encoder.userInfo.dateFormatter(for: APIDateFormat.{{vendorExtensions.x-codegen-date-format-name}}){{^required}}, required: false{{/required}})
{{else}}
try container.encode({{name}}, forKey: .{{name}}{{^required}}, required: false{{/required}})
{{/if}}
{{/allVars}}
}
{{/hasVars}}
{{#additionalPropertiesType}}
public var additionalProperties: [String:{{{additionalPropertiesType}}}] = [:]