Compare commits

...

40 Commits

Author SHA1 Message Date
Vladimir Shefer d34a8734f3
Merge pull request #94 from TouchInstinct/feature/bugfix
Fix compile error in DateFactory
2020-09-28 14:07:40 +03:00
Vladimir Shefer 399c9f0abc Fix compile error in DateFactory 2020-09-28 13:32:08 +03:00
Vladimir Shefer c942c39307
Merge pull request #93 from TouchInstinct/feature/java-time
DafeFactory new generation for JavaTime
2020-09-22 13:15:24 +03:00
Vladimir Shefer 015b256631 Replace tabs with spaces 2020-09-17 14:29:23 +03:00
Vladimir Shefer 318fe3d491 DafeFactory new generation for JavaTime 2020-08-27 19:05:26 +03:00
Vladimir Shefer 206f13d4a9
Merge pull request #92 from TouchInstinct/feature/java-time
Fix DateFactory pattern search
2020-08-26 13:43:08 +03:00
Vladimir Shefer 6ac5219c96 Fix DateFactory pattern search 2020-08-24 19:31:34 +03:00
Vladimir Shefer 1f60055793
Merge pull request #91 from TouchInstinct/fix/replace-typename-with-canonicalName
Replace .typeName with .canonicalName
2020-08-18 13:48:31 +03:00
Vladimir Shefer 6213910a50 Replace MutableSet with Set parameter 2020-08-17 11:29:43 +03:00
Vladimir Shefer 26803fd6f6 Replace .typeName with .simpleName.
Method .typeName available since 28 api level, when 21+ api is used
2020-08-17 11:21:59 +03:00
Vladimir Shefer 3fd2ec9a4f
Merge pull request #90 from TouchInstinct/feature/return-list
Format response type in Swift
2020-07-17 13:51:59 +03:00
Vladimir Shefer 321e4021be Format response type in Swift
Now not only the class name could be the response type, but also array type. So `-> Single<A[]>` should be formated as -> Single<[A]>
2020-07-16 15:39:23 +03:00
Victor Shabanov 773bdecd72
Merge pull request #89 from TouchInstinct/feature/swift_module_generation
Add public visibility for swift module
2019-10-17 17:43:42 +03:00
Victor Shabanov 15a7ce9ed4 Fix protocol method declaration for swift module 2019-10-17 15:40:59 +03:00
Victor Shabanov b47d064fe9 Add public visibility for swift module 2019-10-17 15:19:04 +03:00
Oleg fec4299959
Merge pull request #88 from TouchInstinct/feature/color_type_patterns
feature/color_type_patterns
2019-10-14 14:49:27 +03:00
Oleg Kuznetsov c5272f2031 added ColorAdapter class 2019-10-11 21:06:08 +03:00
Oleg Kuznetsov 546113ca93 added HexColor annotation 2019-10-11 21:05:46 +03:00
Ivan Babkin e240e2de6c
Merge pull request #86 from TouchInstinct/fix/swift_date_templates
Update swift date templates
2019-09-10 14:25:01 +03:00
Ivan Babkin 714d68f4c4 Fix date field name 2019-09-09 16:43:41 +03:00
Ivan Babkin c2c853206f Finish dateFormats support 2019-09-09 16:40:04 +03:00
Ivan Babkin f6fc7c3dce Ignore dateFormat if dateFormats exists 2019-09-09 14:34:33 +03:00
Malik Khiraev 81e8ddcb87
Merge pull request #87 from TouchInstinct/feature/date-patterns
Feature/date patterns
2019-08-07 18:26:17 +03:00
Malik 06783d2ad3 Fix error message 2019-08-07 18:07:13 +03:00
Malik d7a1aad672 New line 2019-08-07 18:02:09 +03:00
Malik fd24198675 Review 2019-08-07 18:00:17 +03:00
Malik 04cf0d7c52 Fix a type 2019-08-01 18:02:15 +03:00
Ivan Babkin 3e196020d9 Update swift date templates 2019-08-01 16:33:19 +03:00
Malik 93995f8ce1 Add adapters, annotation and a factory to process date patterns 2019-08-01 14:46:31 +03:00
Alexander Buntakov 2cdfec1a6b
Merge pull request #85 from TouchInstinct/fix/optional_fields_check
kotlin-server: optional fields check first
2019-07-23 17:14:39 +03:00
Elena Bobkova 580ecda701 optional fields check first 2019-07-23 17:13:08 +03:00
Elena Bobkova 1d1fc57e5d
Merge pull request #84 from TouchInstinct/feature/date_formats
date formats updated
2019-07-22 16:29:18 +03:00
Elena Bobkova 12563ef313 date formats updated 2019-07-22 16:17:52 +03:00
Alexander Buntakov fd1b708930
Merge pull request #83 from TouchInstinct/feature/web_documentation_date
date template for web documentation
2019-07-22 13:32:38 +03:00
Elena Bobkova 2a6141d3f2 date template for web documentation 2019-07-22 13:31:21 +03:00
Alexander Buntakov f7e4d590f6
Merge pull request #82 from TouchInstinct/feature/kotli_server_local_date
Feature/kotlin server local date
2019-07-22 13:28:38 +03:00
Elena Bobkova b97fb00ea4 date format condition added 2019-07-22 13:26:15 +03:00
Elena Bobkova 0adb5c1ebe datetime check reverted 2019-07-22 13:23:50 +03:00
Elena Bobkova d5f4f3b21a imports fixed 2019-07-22 13:23:41 +03:00
Elena Bobkova 2f15259a60 date template added 2019-07-19 18:45:34 +03:00
28 changed files with 275 additions and 78 deletions

View File

@ -95,10 +95,10 @@ public class {% include 'blocks/class/classtype.twig' with { type: type } %} ext
}
{%- if (allFieldsOrdered is not empty) %}
//TODO: if TItems instance of arrayList then new ArrayList
{%- if (storageAttributes is not null) %}
@Ignore
{%- endif %}
//TODO: if TItems instance of arrayList then new ArrayList
{%- if (storageAttributes is not null) %}
@Ignore
{%- endif %}
public {{ type.baseTypeName }}(
{%- include 'blocks/class/init-parameters-fields.twig' with { fields: allFieldsOrdered } %}
) {

View File

@ -2,6 +2,6 @@
{%- if fields is not empty -%}
{%- for field in fields %}
{{ utils.writeNullCheckAnnotation(field.type.type.baseTypeName, field.nullable, field.optional) }} final {{ utils.formatValueType(field.type.type, field.nullable, field.optional) }} {{ field.name }} {%- if not (loop.last) %}, {% endif %}
{{ utils.writeNullCheckAnnotation(field.type.type.baseTypeName, field.nullable, field.optional) }} final {{ utils.formatValueType(field.type.type, field.nullable, field.optional) }} {{ field.name }} {%- if not (loop.last) %}, {% endif %}
{%- endfor -%}
{%- endif -%}

View File

@ -0,0 +1,44 @@
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonEncodingException
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import java.util.Arrays
abstract class AbstractCalendarJsonAdapter<T, FORMATTER>(
private val formats: Array<String>
) : JsonAdapter<T>() {
companion object {
private const val CANT_FIND_ANY_FORMATTERS = "Can't find any DateTimeFormatter"
}
private val formatters = formats.map(::createFormatter)
abstract fun createFormatter(pattern: String): FORMATTER
override fun fromJson(reader: JsonReader): T? {
val dateTimeString = reader.nextString()
formatters.forEachIndexed { index, dateTimeFormatter ->
try {
return fromJsonInner(dateTimeString, dateTimeFormatter)
} catch (e: IllegalArgumentException) {
if (index == formatters.lastIndex) {
throw JsonEncodingException("$dateTimeString doesn't fit any of the formats ${Arrays.toString(formats)}")
}
}
}
throw IllegalArgumentException(CANT_FIND_ANY_FORMATTERS)
}
override fun toJson(writer: JsonWriter, value: T?) {
if (formatters.isEmpty()) throw IllegalArgumentException(CANT_FIND_ANY_FORMATTERS)
value?.let {
writer.value(toJsonInner(value, formatters.first()))
} ?: throw JsonEncodingException("Value can't be null")
}
abstract fun fromJsonInner(value: String, dateTimeFormatter: FORMATTER): T
abstract fun toJsonInner(value: T?, dateTimeFormatter: FORMATTER): String?
}

View File

@ -0,0 +1,14 @@
import java.time.format.DateTimeFormatter
import java.time.temporal.TemporalAccessor
abstract class AbstractJavaTimeJsonAdapter<T : TemporalAccessor>(
formats: Array<String>
) : AbstractCalendarJsonAdapter<T, DateTimeFormatter>(formats) {
override fun createFormatter(pattern: String): DateTimeFormatter = DateTimeFormatter.ofPattern(pattern)
override fun toJsonInner(value: T?, dateTimeFormatter: DateTimeFormatter): String? {
value ?: return null
return dateTimeFormatter.format(value)
}
}

View File

@ -0,0 +1,8 @@
import org.joda.time.format.DateTimeFormat
import org.joda.time.format.DateTimeFormatter
abstract class AbstractJodaTimeJsonAdapter<T>(
formats: Array<String>
) : AbstractCalendarJsonAdapter<T, DateTimeFormatter>(formats) {
override fun createFormatter(pattern: String): DateTimeFormatter = DateTimeFormat.forPattern(pattern)
}

View File

@ -0,0 +1,14 @@
import android.graphics.Color
import com.squareup.moshi.FromJson
import com.squareup.moshi.ToJson
class ColorAdapter {
@ToJson
fun toJson(@HexColor color: Int): String = "#${Integer.toHexString(color)}"
@FromJson
@HexColor
fun fromJson(color: String): Int = Color.parseColor(color)
}

View File

@ -0,0 +1,22 @@
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.Moshi
import java.lang.reflect.Type
class DateFactory : JsonAdapter.Factory {
override fun create(type: Type, annotations: Set<out Annotation>, moshi: Moshi): JsonAdapter<*>? {
val typeName: String = when(type) {
is Class<*> -> type.canonicalName ?: type.toString()
else -> type.toString()
}
return getCalendarAdapter(typeName, getPatterns(annotations))
}
private fun getPatterns(annotations: Set<out Annotation>) = annotations
.mapNotNull { it as? Format }
.firstOrNull()
?.patterns
?: throw IllegalArgumentException("You should use Format annotation for DateTime and LocalDate fields")
}

View File

@ -0,0 +1,16 @@
import org.joda.time.DateTime
import org.joda.time.format.DateTimeFormatter
class DateTimeJodaTimeJsonAdapter(
formats: Array<String>
) : AbstractJodaTimeJsonAdapter<DateTime>(formats) {
override fun fromJsonInner(value: String, dateTimeFormatter: DateTimeFormatter): DateTime {
return DateTime.parse(value, dateTimeFormatter)
}
override fun toJsonInner(value: DateTime?, dateTimeFormatter: DateTimeFormatter): String? {
return value?.toString(dateTimeFormatter)
}
}

View File

@ -0,0 +1,5 @@
import com.squareup.moshi.JsonQualifier
@JsonQualifier
@Target(AnnotationTarget.FIELD)
annotation class Format(val patterns: Array<String>)

View File

@ -0,0 +1,5 @@
import com.squareup.moshi.JsonQualifier
@JsonQualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class HexColor

View File

@ -0,0 +1,12 @@
import java.time.LocalDate
import java.time.format.DateTimeFormatter
class LocalDateJavaTimeJsonAdapter(
formats: Array<String>
) : AbstractJavaTimeJsonAdapter<LocalDate>(formats) {
override fun fromJsonInner(value: String, dateTimeFormatter: DateTimeFormatter): LocalDate {
return LocalDate.parse(value, dateTimeFormatter)
}
}

View File

@ -0,0 +1,16 @@
import org.joda.time.LocalDate
import org.joda.time.format.DateTimeFormatter
class LocalDateJodaTimeJsonAdapter(
formats: Array<String>
) : AbstractJodaTimeJsonAdapter<LocalDate>(formats) {
override fun fromJsonInner(value: String, dateTimeFormatter: DateTimeFormatter): LocalDate {
return LocalDate.parse(value, dateTimeFormatter)
}
override fun toJsonInner(value: LocalDate?, dateTimeFormatter: DateTimeFormatter): String? {
return value?.toString(dateTimeFormatter)
}
}

View File

@ -0,0 +1,13 @@
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
class ZonedDateTimeJavaTimeJsonAdapter(
formats: Array<String>
) : AbstractJavaTimeJsonAdapter<ZonedDateTime>(formats) {
override fun fromJsonInner(value: String, dateTimeFormatter: DateTimeFormatter): ZonedDateTime {
return ZonedDateTime.parse(value, dateTimeFormatter)
}
}

View File

@ -9,6 +9,7 @@ import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.annotation.JsonFormat
import java.math.BigDecimal
import java.time.LocalDate
import java.time.ZonedDateTime
{% if (description is not empty) -%}

View File

@ -4,10 +4,13 @@
{%- if field.type.type.baseTypeName == "DateTime" %}
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "{{ utils.getDateFormat(field) }}", timezone = "utc")
{%- endif %}
{%- if field.nullable %}
@JsonInclude(JsonInclude.Include.ALWAYS)
{%- elseif field.optional %}
{%- if field.type.type.baseTypeName == "Date" %}
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "{{ utils.getDateFormat(field) }}")
{%- endif %}
{%- if field.optional %}
@JsonInclude(JsonInclude.Include.NON_NULL)
{%- elseif field.nullable %}
@JsonInclude(JsonInclude.Include.ALWAYS)
{%- endif %}
{% if not (field in superclassesFields) %}val {% endif %}{{ field.name }}: {{ utils.formatValueType(field.type.type, field.nullable, field.optional) }}{{ utils.writeNullCheckMark(field.nullable, field.optional) }} {%- if not (loop.last) %},{% endif %}{{ utils.addDescription(field) }}
{%- endfor -%}

View File

@ -14,6 +14,8 @@
Boolean
{%- elseif valueType.baseTypeName == "DateTime" -%}
ZonedDateTime
{%- elseif valueType.baseTypeName == "Date" -%}
LocalDate
{%- elseif valueType.baseTypeName == "Decimal" -%}
BigDecimal
{%- elseif valueType.baseTypeName == "Map" -%}

View File

@ -6,28 +6,28 @@
import LeadKit
import SwiftDate
enum ApiDateFormat: String, DateFormat {
public enum ApiDateFormat: String, DateFormat {
{% for format in dateFormats -%}
case {{ format.name }} = "{{ format.format }}"
{% endfor %}
var dateToStringFormat: DateToStringStyles {
public var dateToStringFormat: DateToStringStyles {
return .custom(rawValue)
}
var stringToDateFormat: StringToDateStyles {
public var stringToDateFormat: StringToDateStyles {
return .custom(rawValue)
}
}
final class ApiDateFormattingService: DateFormattingService, Singleton {
public final class ApiDateFormattingService: DateFormattingService, Singleton {
typealias DateFormatType = ApiDateFormat
public typealias DateFormatType = ApiDateFormat
var currentRegion: Region = .local
public static let shared = ApiDateFormattingService()
static let shared = ApiDateFormattingService()
public var currentRegion: Region = .local
private init() {}

View File

@ -3,11 +3,11 @@
import LeadKit
import Foundation
enum ApiNumberFormat: NumberFormat {
public enum ApiNumberFormat: NumberFormat {
case decimal
var numberFormatter: NumberFormatter {
public var numberFormatter: NumberFormatter {
let numberFormatter = NumberFormatter()
numberFormatter.decimalSeparator = "."
numberFormatter.minimumIntegerDigits = 1
@ -17,17 +17,17 @@ enum ApiNumberFormat: NumberFormat {
}
}
final class ApiNumberFormattingService: NumberFormattingService, Singleton {
public final class ApiNumberFormattingService: NumberFormattingService, Singleton {
typealias NumberFormatType = ApiNumberFormat
public typealias NumberFormatType = ApiNumberFormat
let formatters = computedFormatters
public static let shared = ApiNumberFormattingService()
static let shared = ApiNumberFormattingService()
public let formatters = computedFormatters
private init() {}
func decimalNumber(from string: String, format: ApiNumberFormat) -> NSDecimalNumber? {
public func decimalNumber(from string: String, format: ApiNumberFormat) -> NSDecimalNumber? {
guard let number = number(from: string, format: format) else {
return nil
}
@ -37,7 +37,7 @@ final class ApiNumberFormattingService: NumberFormattingService, Singleton {
extension ApiNumberFormattingService {
static func decimalNumber(from string: String, format: ApiNumberFormat) -> NSDecimalNumber? {
public static func decimalNumber(from string: String, format: ApiNumberFormat) -> NSDecimalNumber? {
return shared.decimalNumber(from: string, format: format)
}
}

View File

@ -14,12 +14,12 @@ import SwiftDate
import LeadKit
/// {{ description }}
{% if (not hasChilds) -%}final {% endif %}class {{ classType }}: {{ parentClassType }} {
public {% if (not hasChilds) -%}final {% endif %}class {{ classType }}: {{ parentClassType }} {
{% include 'blocks/class/coding-keys.twig' with { fields: fields } %}
{% include 'blocks/class/fields.twig' with { fields: fields } %}
// MARK: - Initializers
{% if (hasParent and (fields is empty)) %} override {% endif %}init({%- include 'blocks/class/init-parameters-fields.twig' with { fields: allFieldsOrdered } -%}) {
public {% if (hasParent and (fields is empty)) %} override {% endif %}init({%- include 'blocks/class/init-parameters-fields.twig' with { fields: allFieldsOrdered } -%}) {
{%- include 'blocks/class/fields-initialization.twig' with { fields: fields } -%}
{% if hasParent %}
super.init({%- include 'blocks/class/fields-super-initialization.twig' with { fields: superclassesFields } -%})
@ -27,7 +27,7 @@ import LeadKit
}
{% if hasParent or fields is not empty %}
required init(from decoder: Decoder) throws {
public required init(from decoder: Decoder) throws {
{%- if fields is not empty %}
{% include 'blocks/class/fields-initialization-from-decoder.twig' with { fields: fields} %}
{%- endif -%}
@ -37,7 +37,7 @@ import LeadKit
}
{% endif %}
{% if hasParent -%}override {% endif %}func encode(to encoder: Encoder) throws {
public {% if hasParent -%}override {% endif %}func encode(to encoder: Encoder) throws {
{%- if fields is not empty %}
{% include 'blocks/class/fields-encode-to-encoder.twig' with { fields: fields} %}
{%- endif -%}
@ -47,7 +47,7 @@ import LeadKit
}
{% if classAndFieldsHaveNotGenericsOrNonEqutableCollections -%}
func isEqual(to other: {{ classType }}?) -> Bool {
public func isEqual(to other: {{ classType }}?) -> Bool {
{% if (fields is empty) and (not hasParent) %}
return false
{% else %}
@ -64,7 +64,7 @@ import LeadKit
{%- if (not hasChilds) and classAndFieldsHaveNotGenericsOrNonEqutableCollections -%}
extension {{ type.baseTypeName }}: Equatable {
static func ==(lhs: {{ classType }}, rhs: {{ classType }}) -> Bool {
public static func ==(lhs: {{ classType }}, rhs: {{ classType }}) -> Bool {
return lhs.isEqual(to: rhs)
}
}
@ -74,7 +74,7 @@ extension {{ type.baseTypeName }}: Equatable {
{%- if classAndFieldsHaveNotGenericsOrNonEqutableCollections -%}
extension {{ type.baseTypeName }} {
static let new{{ type.baseTypeName }} = {{ type.baseTypeName }}({%- include 'blocks/class/fields-initialization-default-values.twig' with { fields: allFieldsOrdered } -%})
public static let new{{ type.baseTypeName }} = {{ type.baseTypeName }}({%- include 'blocks/class/fields-initialization-default-values.twig' with { fields: allFieldsOrdered } -%})
{% include 'blocks/class/copy-declaration.twig' with { hasChilds: hasChilds, type: type, fields: allFieldsOrdered } %}
}

View File

@ -6,7 +6,7 @@
{% for value in values -%}
/// - {{ utils.decapitalize(value.name) }}: {{ value.description }}
{% endfor -%}
enum {{ name }}: {{ enumutils.enumType(valuesTypes) }}, Codable, RawRepresentable, CaseIterable {
public enum {{ name }}: {{ enumutils.enumType(valuesTypes) }}, Codable, RawRepresentable, CaseIterable {
{% include 'blocks/enum/cases.twig' with { values: values } %}
}
{{ "\n" }}

View File

@ -5,7 +5,7 @@ import Alamofire
{% set serviceName = concat(networkServiceName, "NetworkService") -%}
{% set protocolName = concat(networkServiceName, "NetworkProtocol") -%}
protocol {{ protocolName }} {
public protocol {{ protocolName }} {
func apiRequest<T: Decodable>(with parametersSingle: Single<ApiRequestParameters>, additionalValidStatusCodes: Set<Int>, decoder: JSONDecoder) -> Single<T>
func deferredApiRequestParameters(relativeUrl: String,
@ -19,25 +19,25 @@ protocol {{ protocolName }} {
{% endfor %}
}
class {{ serviceName }}: NetworkService, {{ protocolName }} {
open class {{ serviceName }}: NetworkService, {{ protocolName }} {
static let apiBaseUrl = "{{ apiUrl }}"
public static let apiBaseUrl = "{{ apiUrl }}"
convenience init() {
public convenience init() {
self.init(configuration: NetworkServiceConfiguration(baseUrl: {{ serviceName }}.apiBaseUrl))
}
func apiRequest<T: Decodable>(with parametersSingle: Single<ApiRequestParameters>, additionalValidStatusCodes: Set<Int> = [], decoder: JSONDecoder = JSONDecoder()) -> Single<T> {
open func apiRequest<T: Decodable>(with parametersSingle: Single<ApiRequestParameters>, additionalValidStatusCodes: Set<Int> = [], decoder: JSONDecoder = JSONDecoder()) -> Single<T> {
return parametersSingle.flatMap {
self.rxRequest(with: $0, additionalValidStatusCodes: additionalValidStatusCodes, decoder: decoder).map { $0.model }.asSingle()
}
}
func deferredApiRequestParameters(relativeUrl: String,
method: HTTPMethod = .get,
parameters: Parameters? = nil,
requestEncoding: ParameterEncoding? = nil,
requestHeaders: HTTPHeaders? = nil) -> Single<ApiRequestParameters> {
open func deferredApiRequestParameters(relativeUrl: String,
method: HTTPMethod = .get,
parameters: Parameters? = nil,
requestEncoding: ParameterEncoding? = nil,
requestHeaders: HTTPHeaders? = nil) -> Single<ApiRequestParameters> {
return .deferredJust {
self.configuration.apiRequestParameters(relativeUrl: relativeUrl,
method: method,

View File

@ -1,6 +1,6 @@
{%- import '../../macroses/common.utils.twig' as utils -%}
func copy{%- if hasChilds -%}{{ type.baseTypeName }}{%- endif -%}With({%- include '../class/nullable-parameters-fields.twig' with { fields: allFieldsOrdered } -%}) -> {{ type.baseTypeName }} {
public func copy{%- if hasChilds -%}{{ type.baseTypeName }}{%- endif -%}With({%- include '../class/nullable-parameters-fields.twig' with { fields: allFieldsOrdered } -%}) -> {{ type.baseTypeName }} {
return {{ type.baseTypeName }}({% include '../class/fields-optional-initialization.twig' with { fields: allFieldsOrdered } %})
}
@ -14,7 +14,7 @@
{% if containsOptionalFields %}
func copy{%- if hasChilds -%}{{ type.baseTypeName }}{%- endif -%}Without({%- include '../class/bool-parameters-fields.twig' with { fields: allFieldsOrdered } -%}) -> {{ type.baseTypeName }} {
public func copy{%- if hasChilds -%}{{ type.baseTypeName }}{%- endif -%}Without({%- include '../class/bool-parameters-fields.twig' with { fields: allFieldsOrdered } -%}) -> {{ type.baseTypeName }} {
return {{ type.baseTypeName }}({%- include '../class/fields-without-initialization.twig' with { fields: allFieldsOrdered } -%})
}
{% endif %}

View File

@ -4,6 +4,6 @@
// MARK: - Fields
{% for field in fields %}
/// {{ field.description }}
let {{ field.name }}: {{ utils.formatNullableOrOptional(utils.formatValueType(field.type.type), field.nullable, field.optional) }}
public let {{ field.name }}: {{ utils.formatNullableOrOptional(utils.formatValueType(field.type.type), field.nullable, field.optional) }}
{% endfor -%}
{% endif %}

View File

@ -9,4 +9,4 @@
{%- set funcName = utils.decapitalize(method.name) -%}
{{ isStatic ? "static " : "" }}func {{ funcName }}({%- if hasBody -%}{{ bodyParamName }}: {{ bodyTypeName }},{{ " " }}{%- endif -%}requestEncoding: ParameterEncoding?, requestHeaders: HTTPHeaders?, additionalValidStatusCodes: Set<Int>) -> Single<{{ method.responseType.type.typeName }}>
{{ isStatic ? "static " : "" }}func {{ funcName }}({%- if hasBody -%}{{ bodyParamName }}: {{ bodyTypeName }},{{ " " }}{%- endif -%}requestEncoding: ParameterEncoding?, requestHeaders: HTTPHeaders?, additionalValidStatusCodes: Set<Int>) -> Single<{{ utils.formatValueType(method.apiResponseType) }}>

View File

@ -11,10 +11,10 @@
{%- set funcName = utils.decapitalize(method.name) -%}
/// {{ method.description }}
{{ isStatic ? "static " : "" }}func {{ funcName }}({%- if hasBody -%}{{ bodyParamName }}: {{ bodyTypeName }},{{ "\n " }}{%- endif -%}
public {{ isStatic ? "static " : "" }}func {{ funcName }}({%- if hasBody -%}{{ bodyParamName }}: {{ bodyTypeName }},{{ "\n " }}{%- endif -%}
requestEncoding: ParameterEncoding? = nil,
requestHeaders: HTTPHeaders? = nil,
additionalValidStatusCodes: Set<Int> = []) -> Single<{{ method.responseType.type.typeName }}> {
additionalValidStatusCodes: Set<Int> = []) -> Single<{{ utils.formatValueType(method.apiResponseType) }}> {
{% if isStatic -%}
return shared.{{ funcName }}({%- if hasBody -%}{{ bodyParamName }}: {{ bodyParamName }},{{ "\n " }}{%- endif -%}

View File

@ -12,40 +12,42 @@
{% macro formatValueType(valueType) %}
{%- import _self as self -%}
{%- set baseTypeName = valueType.baseTypeName -%}
{%- if valueType.baseTypeName == "Array" -%}
{%- if baseTypeName == "Array" -%}
[{{ self.formatValueType(valueType.itemsType) }}]
{%- elseif valueType.baseTypeName == "Map" -%}
{%- elseif baseTypeName == "Map" -%}
[{{ self.formatValueType(valueType.keysType) }}: {{ self.formatValueType(valueType.valuesType) }}]
{%- elseif valueType.baseTypeName == "DateTime" or valueType.baseTypeName == "DateTimeTimestamp" -%}
{%- elseif baseTypeName == "Date" or baseTypeName == "DateTime" or baseTypeName == "DateTimeTimestamp" -%}
DateInRegion
{%- elseif valueType.baseTypeName == "Long" -%}
{%- elseif baseTypeName == "Long" -%}
Int64
{%- elseif valueType.baseTypeName == "Decimal" or valueType.baseTypeName == "StringDecimal" -%}
{%- elseif baseTypeName == "Decimal" or baseTypeName == "StringDecimal" -%}
NSDecimalNumber
{%- elseif valueType.baseTypeName == "Url" -%}
{%- elseif baseTypeName == "Url" -%}
URL
{%- elseif valueType.baseTypeName == "Color" -%}
{%- elseif baseTypeName == "Color" -%}
UIColor
{%- else -%}
{{ valueType.baseTypeName }}
{{ baseTypeName }}
{%- endif -%}
{% endmacro %}
{% macro formatEncodingValue(field, isStrongLinkCaptured) %}
{%- import _self as self -%}
{%- set baseTypeName = field.type.type.baseTypeName -%}
{%- if field.type.type.baseTypeName == "DateTime" -%}
{%- if baseTypeName == "Date" or baseTypeName == "DateTime" -%}
{{- self.formatEncodingDate(field) -}}
{%- elseif field.type.type.baseTypeName == "StringDecimal" -%}
{%- elseif baseTypeName == "StringDecimal" -%}
{{- self.formatEncodingStringDecimal(field) -}}
{%- elseif field.type.type.baseTypeName == "Decimal" -%}
{%- elseif baseTypeName == "Decimal" -%}
{{ self.formatFieldName(field, isStrongLinkCaptured) -}}.decimalValue
{%- elseif field.type.type.baseTypeName == "DateTimeTimestamp" -%}
{%- elseif baseTypeName == "DateTimeTimestamp" -%}
Int({{ self.formatFieldName(field, isStrongLinkCaptured) -}}.timeIntervalSince1970)
{%- elseif field.type.type.baseTypeName == "Color" -%}
{%- elseif baseTypeName == "Color" -%}
{{ self.formatFieldName(field, isStrongLinkCaptured) -}}.hexString
{%- elseif field.type.type.baseTypeName == "Url" -%}
{%- elseif baseTypeName == "Url" -%}
{{ self.formatFieldName(field, isStrongLinkCaptured) -}}.absoluteString
{%- else -%}
{{ field.name }}
@ -63,7 +65,11 @@
{% endmacro %}
{%- macro formatEncodingDate(field) -%}
ApiDateFormattingService.string(from: {{ field.name -}}, format: .{{- dateFormatToName(field.type.dateFormat) -}})
{%- if field.type.dateFormats is not empty -%}
ApiDateFormattingService.string(from: {{ field.name -}}, format: .{{- dateFormatToName(field.type.dateFormats[0]) -}})
{%- else -%}
ApiDateFormattingService.string(from: {{ field.name -}}, format: .{{- dateFormatToName(field.type.dateFormat) -}})
{%- endif -%}
{%- endmacro -%}
{%- macro formatEncodingStringDecimal(field) -%}
@ -73,7 +79,7 @@
{% macro encodeIfPresent(field) %}
{%- import _self as self -%}
{%- set baseTypeName = field.type.type.baseTypeName -%}
{% if baseTypeName == "DateTime" or baseTypeName == "DateTimeTimestamp" or baseTypeName == "StringDecimal" %}
{% if baseTypeName == "Date" or baseTypeName == "DateTime" or baseTypeName == "DateTimeTimestamp" or baseTypeName == "StringDecimal" %}
if let {{ field.name }} = {{ field.name }} {
try container.encode({{- self.formatEncodingValue(field, true) -}}, forKey: .{{- field.name -}})
}
@ -101,12 +107,12 @@
{% macro decodeFromContainer(field) %}
{%- import _self as self -%}
{%- import 'complexField.utils.twig' as complexFieldUtils -%}
{%- if field.type.type.baseTypeName == "Color" or field.type.type.baseTypeName == "DateTime" or field.type.type.baseTypeName == "StringDecimal" or field.type.type.baseTypeName == "Url" -%}
{%- set baseTypeName = field.type.type.baseTypeName -%}
{%- if baseTypeName == "Color" or baseTypeName == "Date" or baseTypeName == "DateTime" or baseTypeName == "StringDecimal" or baseTypeName == "Url" -%}
{{ complexFieldUtils.decodeComplexField(field, "String") -}}
{%- elseif field.type.type.baseTypeName == "DateTimeTimestamp" -%}
{%- elseif baseTypeName == "DateTimeTimestamp" -%}
{{ complexFieldUtils.decodeComplexField(field, "Int") -}}
{%- elseif field.type.type.baseTypeName == "Decimal" -%}
{%- elseif baseTypeName == "Decimal" -%}
{{ complexFieldUtils.decodeComplexField(field, "Decimal") -}}
{%- else -%}
self.{{ field.name }} = try container.{{- self.formatOptionalDecode(field) -}}({{ self.formatValueType(field.type.type) }}.self, forKey: .{{ field.name }})
@ -148,7 +154,7 @@
[:]
{%- elseif baseTypeName == "String" -%}
""
{%- elseif baseTypeName == "DateTime" or baseTypeName == "DateTimeTimestamp" -%}
{%- elseif baseTypeName == "Date" or baseTypeName == "DateTime" or baseTypeName == "DateTimeTimestamp" -%}
Date().inDefaultRegion()
{%- elseif baseTypeName == "Double" -%}
0.0

View File

@ -14,21 +14,21 @@
{% macro initExpr(field) %}
{%- import _self as self -%}
{%- if field.type.type.baseTypeName == "DateTime" -%}
{%- set dateTimeInit = "ApiDateFormattingService.date(from: %s, format: .%s, parsedIn: nil)"|format(field.name, dateFormatToName(field.type.dateFormat)) -%}
{{ self.decodeThrowableField(field, dateTimeInit, 'init?(string:format:fromRegion:) returned nil') -}}
{%- elseif field.type.type.baseTypeName == "Color" -%}
{%- set baseTypeName = field.type.type.baseTypeName -%}
{%- if baseTypeName == "Date" or baseTypeName == "DateTime" -%}
{{ self.commonDateInit(field) -}}
{%- elseif baseTypeName == "Color" -%}
{%- set colorInit = "UIColor(hexString: %s)"|format(field.name) -%}
{{ self.decodeThrowableField(field, colorInit, 'Unable to decode color from hex string') -}}
{%- elseif field.type.type.baseTypeName == "Url" -%}
{%- elseif baseTypeName == "Url" -%}
{%- set urlInit = "URL(string: %s)"|format(field.name) -%}
{{ self.decodeThrowableField(field, urlInit, 'Unable to decode URL from string') -}}
{%- elseif field.type.type.baseTypeName == "StringDecimal" -%}
{%- elseif baseTypeName == "StringDecimal" -%}
{%- set stringDecimalInit = "ApiNumberFormattingService.decimalNumber(from: %s, format: .decimal)"|format(field.name) -%}
{{- self.decodeThrowableField(field, stringDecimalInit, 'Unable to decode decimal from string') -}}
{%- elseif field.type.type.baseTypeName == "DateTimeTimestamp" -%}
{%- elseif baseTypeName == "DateTimeTimestamp" -%}
self.{{ field.name }} = DateInRegion(seconds: TimeInterval({{ field.name }}))
{%- elseif field.type.type.baseTypeName == "Decimal" -%}
{%- elseif baseTypeName == "Decimal" -%}
self.{{ field.name }} = NSDecimalNumber(decimal: {{ field.name }})
{%- endif -%}
{% endmacro %}
@ -39,4 +39,20 @@
} else {
throw LeadKitError.failedToDecode(reason: "{{ errorMessage }}")
}
{%- endmacro -%}
{%- macro commonDateInit(field) -%}
{%- import _self as self -%}
{%- if field.type.dateFormats is not empty -%}
{%- set formattedDateFormats = [] -%}
{%- for dateFormat in field.type.dateFormats -%}
{%- set formattedDateFormats = formattedDateFormats|merge([".%s"|format(dateFormatToName(dateFormat))]) -%}
{%- endfor -%}
{%- set dateFormatsString = formattedDateFormats|join(', ') -%}
{%- set dateInit = "ApiDateFormattingService.date(from: %s, formats: [%s], parsedIn: nil)"|format(field.name, dateFormatsString) -%}
{{- self.decodeThrowableField(field, dateInit, "Unable to decode date from string") -}}
{%- else -%}
{%- set dateInit = "ApiDateFormattingService.date(from: %s, format: .%s, parsedIn: nil)"|format(field.name, dateFormatToName(field.type.dateFormat)) -%}
{{- self.decodeThrowableField(field, dateInit, "Unable to decode date from string") -}}
{%- endif -%}
{%- endmacro -%}

View File

@ -42,8 +42,8 @@
<div>{{ field.jsonName }}</div>
<div>
{{ self.formatValueType(field.type.type, field.nullable, objectsLinks, useAnchors) }}
{%- if field.type.type.typeName == "DateTime" -%}
&nbsp;({{ field.type.dateFormat }})
{%- if field.type.type.typeName in ["DateTime", "Date"] -%}
&nbsp;({{ field.type.allDateFormats|join(', ') }})
{%- endif -%}
</div>
<div>{{ field.description | escape }}</div>