Compare commits

..

2 Commits

Author SHA1 Message Date
Elena Bobkova 29d3750f75 class fields added 2018-08-13 19:43:59 +03:00
Elena Bobkova 399697eafb service and service fields added to templates 2018-08-13 18:03:49 +03:00
78 changed files with 696 additions and 1353 deletions

View File

@ -1,30 +1,16 @@
/*
{%- set hasParent = parent is not null -%}
/**
* This code is autogenerated by Touch Instinct tools
*/
package {{ packageName }}.api;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.util.ObjectsCompat;
{%- if (storageAttributes is not null) %}
import androidx.room.Delete;
import androidx.room.Entity;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import androidx.room.Transaction;
import androidx.room.TypeConverter;
import androidx.room.TypeConverters;
import androidx.room.PrimaryKey;
import androidx.room.Ignore;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import io.reactivex.Flowable;
import io.reactivex.Single;
{%- endif %}
import com.bluelinelabs.logansquare.LoganSquare;
import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonObject;
import com.bluelinelabs.logansquare.JsonOptional;
import com.bluelinelabs.logansquare.NonNullJsonOptional;
import java.io.IOException;
import java.io.ObjectInputStream;
@ -41,125 +27,75 @@ import java.util.HashMap;
import org.joda.time.DateTime;
import ru.touchin.templates.ApiModel;
import ru.touchin.roboswag.core.utils.ObjectUtils;
import ru.touchin.templates.logansquare.LoganSquareJsonModel;
{%- if (description is not empty) %}
{% if (description is not empty) %}
/**
* {{ description }}
*/
{%- endif %}
{%- if (storageAttributes is not null) %}
{%- set attributeWas = false %}
@Entity(
{%- if (storageAttributes.tableName is not null) -%}
{%- set attributeWas = true -%}
tableName = "{{ storageAttributes.tableName }}"
{%- endif -%}
{%- if attributeWas and storageAttributes.primaryKeys is not empty -%}, {% endif %}
{%- if (storageAttributes.primaryKeys is not empty) -%}
{%- set attributeWas = true -%}
primaryKeys = { {%- for key in storageAttributes.primaryKeys -%} "{{- key -}}" {%- if not (loop.last) %}, {% endif -%} {%- endfor -%} }
{%- endif -%}
)
{%- set haveConverters = false -%}
{%- for field in fields -%}
{%- if (field.type.type.baseTypeName == "Array")
or (field.type.type.baseTypeName == "Map")
or (field.type.type.baseTypeName != "Bool"
and field.type.type.baseTypeName != "Int"
and field.type.type.baseTypeName != "Long"
and field.type.type.baseTypeName != "Double"
and field.type.type.baseTypeName != "String"
and field.type.storable != true) %}
{%- set haveConverters = true -%}
{%- endif -%}
{%- endfor -%}
{%- if haveConverters %}
@TypeConverters({{ type.baseTypeName }}.class)
{%- endif -%}
{%- endif %}
@JsonObject(serializeNullObjects = {{ default(serializeNulls, false) }})
{% endif -%}
@JsonObject(serializeNullObjects = true)
public class {% include 'blocks/class/classtype.twig' with { type: type } %} extends {% include 'blocks/class/supertype.twig' with { type: type, parent: parent } %} {
{%- include 'blocks/class/fields-converters.twig' -%}
{% include 'blocks/class/fields.twig' with { fields: fields } %}
public {{ type.baseTypeName }}() {
super();
}
{%- if (allFieldsOrdered is not empty) %}
//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 } %}
) {
{% if (allFieldsOrdered is not empty) %}
//TODO: if TItems instance of arrayList then new ArrayList
public {{ type.baseTypeName }}({%- include 'blocks/class/init-parameters-fields.twig' with { fields: allFieldsOrdered } -%}) {
super({%- include 'blocks/class/fields-super-initialization.twig' with { fields: superclassesFields } -%});
{%- include 'blocks/class/fields-initialization.twig' with { fields: fields, object: "this" } %}
}
{%- endif %}
{% include 'blocks/class/fields-getters-setters.twig' with { fields: fields } %}
{% endif %}
{%- include 'blocks/class/fields-getters-setters.twig' with { fields: fields } %}
//TODO: add check for collection if TypeParameter
//TODO: do not validate enums as ApiModel
@Override
public void validate() throws ValidationException {
super.validate();
{%- include 'blocks/class/fields-validate.twig' with { fields: fields } %}
}
//TODO: add check for collection if TypeParameter
//TODO: do not validate enums as ApiModel
@Override
public void validate() throws ValidationException {
super.validate();
{%- include 'blocks/class/fields-validate.twig' with { fields: fields } %}
}
protected void copyTo(@NonNull final {% include 'blocks/class/classtype.twig' with { type: type } %} destination) {
{%- if parent is not null %}
super.copyTo(destination);
{%- endif %}
{%- include 'blocks/class/fields-initialization.twig' with { fields: fields, object: "destination" } %}
}
protected void copyTo(@NonNull final {% include 'blocks/class/classtype.twig' with { type: type } %} destination) {
{%- if parent is not null %}
super.copyTo(destination);
{%- endif %}
{%- include 'blocks/class/fields-initialization.twig' with { fields: fields, object: "destination" } %}
}
@NonNull
public {% include 'blocks/class/classtype.twig' with { type: type } %} copy() {
final {% include 'blocks/class/classtype.twig' with { type: type } %} result = new {% include 'blocks/class/classtype.twig' with { type: type } %}();
this.copyTo(result);
return result;
}
@NonNull
public {% include 'blocks/class/classtype.twig' with { type: type } %} copy() {
final {% include 'blocks/class/classtype.twig' with { type: type } %} result = new {% include 'blocks/class/classtype.twig' with { type: type } %}();
this.copyTo(result);
return result;
}
{%- if (fields is not empty) %}
public int hashCode() {
return ObjectsCompat.hash({%- if parent is not null -%}super.hashCode(), {% endif -%}{%- include 'blocks/class/fields-super-initialization.twig' with { fields: fields } -%});
}
public int hashCode() {
return ObjectUtils.hashCode({%- if parent is not null -%}super.hashCode(), {% endif -%}{%- include 'blocks/class/fields-super-initialization.twig' with { fields: fields } -%});
}
@SuppressWarnings("unchecked")
public boolean equals(@Nullable final Object object) {
if (this == object) {
return true;
}
if (object == null || getClass() != object.getClass()) {
return false;
}
final {% include 'blocks/class/classtype.twig' with { type: type } %} that = ({% include 'blocks/class/classtype.twig' with { type: type } %}) object;
return {% if parent is not null -%}super.equals(that)
&& {% endif -%}
{%- include 'blocks/class/fields-equals.twig' with { fields: fields } -%};
}
if (this == object) {
return true;
}
if (object == null || getClass() != object.getClass()) {
return false;
}
final {% include 'blocks/class/classtype.twig' with { type: type } %} that = ({% include 'blocks/class/classtype.twig' with { type: type } %}) object;
return {% if parent is not null -%}super.equals(that)
&& {% endif -%}
{%- include 'blocks/class/fields-equals.twig' with { fields: fields } -%};
}
private void writeObject(@NonNull final ObjectOutputStream outputStream) throws IOException {
{%- include 'blocks/class/fields-write-object.twig' with { fields: fields } %}
}
private void writeObject(@NonNull final ObjectOutputStream outputStream) throws IOException {
{%- include 'blocks/class/fields-write-object.twig' with { fields: fields } %}
}
@SuppressWarnings("unchecked")
private void readObject(@NonNull final ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
{%- include 'blocks/class/fields-read-object.twig' with { fields: fields } %}
}
{%- endif %}
{%- include 'blocks/class/dao.twig' %}
@SuppressWarnings("unchecked")
private void readObject(@NonNull final ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
{%- include 'blocks/class/fields-read-object.twig' with { fields: fields } %}
}
}

View File

@ -1,13 +1,10 @@
/*
{%- import 'utils.twig' as utils -%}
/**
* This code is autogenerated by Touch Instinct tools
*/
package {{ packageName }}.api;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
{%- if storable %}
import androidx.room.TypeConverter;
{%- endif %}
import android.support.annotation.NonNull;
import com.bluelinelabs.logansquare.annotation.JsonEnum;
{%- if valuesTypes == "STRING" %}
@ -24,9 +21,6 @@ import ru.touchin.templates.logansquare.LoganSquareEnumConverter;
*/
@JsonEnum
public enum {{ name }} {
{%- include 'blocks/enum/cases.twig' with { values: values } %}
{%- include 'blocks/enum/converters.twig' %}
{% include 'blocks/enum/cases.twig' with { values: values } %}
}

View File

@ -1,9 +1,9 @@
/*
/**
* This code is autogenerated by Touch Instinct tools
*/
package {{ packageName }}.api;
import androidx.annotation.NonNull;
import android.support.annotation.NonNull;
import io.reactivex.Single;
import retrofit2.http.Body;

View File

@ -1,38 +0,0 @@
{%- import '../../utils.twig' as utils -%}
{%- if (storageAttributes is not null) %}
@androidx.room.Dao
public interface Dao {
@NonNull
@Query("SELECT * FROM {{ default(storageAttributes.tableName, type.baseTypeName) }}")
List<{{ type.baseTypeName }}> get();
@NonNull
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(@NonNull final Iterable<{{ type.baseTypeName }}> list);
@NonNull
@Delete
void delete(@NonNull final Iterable<{{ type.baseTypeName }}> list);
@Query("DELETE FROM {{ default(storageAttributes.tableName, type.baseTypeName) }}")
void clear();
}
@androidx.room.Dao
public interface ReactiveDao extends Dao {
@NonNull
@Query("SELECT * FROM {{ default(storageAttributes.tableName, type.baseTypeName) }}")
Flowable<List<{{ type.baseTypeName }}>> observe();
@NonNull
@Query("SELECT * FROM {{ default(storageAttributes.tableName, type.baseTypeName) }}")
Single<List<{{ type.baseTypeName }}>> getSingle();
}
{%- endif -%}

View File

@ -1,134 +0,0 @@
{%- import '../../utils.twig' as utils -%}
{%- if (storageAttributes is not null) -%}
{% set converters = [] %}
{%- for field in fields -%}
{%- if not (field.type.type.baseTypeName in converters) -%}
{%- if field.type.type.baseTypeName == "Array" %}
@TypeConverter
@Nullable
public static String serialize{{ field.type.type.itemsType.baseTypeName }}List(@Nullable final {{ utils.formatValueType(field.type.type, true, true) }} value) {
if (value == null) {
return null;
}
try {
return LoganSquare.serialize(value, {{ utils.formatValueType(field.type.type.itemsType, true, true) }}.class);
} catch (final IOException exception) {
return null;
}
}
@TypeConverter
@Nullable
public static {{ utils.formatValueType(field.type.type, true, true) }} deserialize{{ field.type.type.itemsType.baseTypeName }}List(@Nullable final String value) {
if (value == null) {
return null;
}
try {
return LoganSquare.parseList(value, {{ utils.formatValueType(field.type.type.itemsType, true, true) }}.class);
} catch (final IOException exception) {
return null;
}
}
{%- set converters = merge(converters, field.type.type.itemsType.baseTypeName) -%}
{%- elseif field.type.type.baseTypeName == "Map" %}
@TypeConverter
@Nullable
public static String serialize{{ field.type.type.valuesType.baseTypeName }}Map(@Nullable final {{ utils.formatValueType(field.type.type, true, true) }} value) {
if (value == null) {
return null;
}
try {
return LoganSquare.serialize(value), {{ utils.formatValueType(field.type.type.valuesType, true, true) }};
} catch (final IOException exception) {
return null;
}
}
@TypeConverter
@Nullable
public static {{ utils.formatValueType(field.type.type, true, true) }} deserialize{{ field.type.type.valuesType.baseTypeName }}Map(@Nullable final String value) {
if (value == null) {
return null;
}
try {
return LoganSquare.parseMap(value, {{ utils.formatValueType(field.type.type.valuesType, true, true) }}.class);
} catch (final IOException exception) {
return null;
}
}
{%- set converters = merge(converters, field.type.type.valuesType.baseTypeName) -%}
{%- elseif field.type.type.baseTypeName == "DateTime" %}
@TypeConverter
@Nullable
public static String serialize{{ field.type.type.baseTypeName }}(@Nullable final {{ utils.formatValueType(field.type.type, true, true) }} value) {
if (value == null) {
return null;
}
return value.toString();
}
@TypeConverter
@Nullable
public static {{ utils.formatValueType(field.type.type, true, true) }} deserialize{{ field.type.type.baseTypeName }}(@Nullable final String value) {
if (value == null) {
return null;
}
try {
return DateTime.parse(value);
} catch (final Exception exception) {
return null;
}
}
{%- set converters = merge(converters, field.type.type.baseTypeName) -%}
{%- elseif field.type.type.baseTypeName != "Bool"
and field.type.type.baseTypeName != "Int"
and field.type.type.baseTypeName != "Long"
and field.type.type.baseTypeName != "Double"
and field.type.type.baseTypeName != "String"
and field.type.storable != true %}
@TypeConverter
@Nullable
public static String serialize{{ field.type.type.baseTypeName }}(@Nullable final {{ utils.formatValueType(field.type.type, true, true) }} value) {
if (value == null) {
return null;
}
try {
return LoganSquare.serialize(value);
} catch (final IOException exception) {
return null;
}
}
@TypeConverter
@Nullable
public static {{ utils.formatValueType(field.type.type, true, true) }} deserialize{{ field.type.type.baseTypeName }}(@Nullable final String value) {
if (value == null) {
return null;
}
try {
return LoganSquare.parse(value, {{ utils.formatValueType(field.type.type, true, true) }}.class);
} catch (final IOException exception) {
return null;
}
}
{%- set converters = merge(converters, field.type.type.baseTypeName) -%}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
{%- endif -%}

View File

@ -1,4 +1,5 @@
{%- import '../../utils.twig' as utils -%}
{%- for field in fields -%}
ObjectsCompat.equals(this.{{ field.name }}, that.{{ field.name }}) {%- if not (loop.last) %}
&& {% endif %}
{{ utils.formatEquals(field.name, field.type.type.baseTypeName, field.optional) }} {%- if not (loop.last) %}
&& {% endif %}
{%- endfor -%}

View File

@ -1,32 +1,24 @@
{%- import '../../utils.twig' as utils -%}
{%- if fields is not empty -%}
{%- for field in fields %}
{% if (field.description is not empty) %}
{% if (field.description is not empty) %}
/**
* {{ field.description }}
*/
{%- endif %}
* {{ field.description }}
*/
{% endif -%}
{{ utils.writeNullCheckAnnotation(field.type.type.baseTypeName, field.nullable, field.optional) }}
public {{ utils.formatValueType(field.type.type, field.nullable, field.optional) }} {% if (field.type.type.baseTypeName == "Bool") and (field.name matches "^is[A-Z,0-9].*") -%}{{ field.name }}{%- else -%}get{{ capitalize(field.name) }}{%- endif -%}() {
{%- if field.nullable or field.optional %}
if (this.{{ field.name }} == null) {
return null;
}
{%- endif %}
{%- if field.type.type.baseTypeName == "Array" %}
return Collections.unmodifiableList(this.{{ field.name }});
{%- elseif field.type.type.baseTypeName == "Map" %}
return Collections.unmodifiableMap(this.{{ field.name }});
{%- else %}
return this.{{ field.name }};
{%- endif %}
}
{% if (field.description is not empty) %}
public {{ utils.formatValueType(field.type.type, field.nullable, field.optional) }} {% if (field.type.type.baseTypeName == "Bool") and (field.name matches "^is[A-Z,0-9].*") -%}{{ field.name }}{%- else -%}get{{ utils.capitalize(field.name) }}{%- endif -%}() {
{{ utils.formatValueGetter(field.name, field.type.type, field.nullable) }}
}
{% if (field.description is not empty) %}
/**
* {{ field.description }}
*/
{%- endif %}
public void set{{ capitalize(field.name) }}({{ utils.writeNullCheckAnnotation(field.type.type.baseTypeName, field.nullable, field.optional) }} final {{ utils.formatValueType(field.type.type, field.nullable, field.optional) }} {{ field.name }}) {
this.{{ field.name }} = {{ field.name }};
}
{%- endfor -%}
* {{ field.description }}
*/
{% endif -%}
public void set{{ utils.capitalize(field.name) }}({{ utils.writeNullCheckAnnotation(field.type.type.baseTypeName, field.nullable, field.optional) }} final {{ utils.formatValueType(field.type.type, field.nullable, field.optional) }} {{ field.name }}) {
{{ utils.formatValueSetter("this", field.name, field.type.type.baseTypeName, field.nullable ) }}
}
{% endfor -%}
{%- endif -%}

View File

@ -1,3 +1,4 @@
{%- import '../../utils.twig' as utils -%}
{%- for field in fields %}
{{ object }}.{{ field.name }} = {{ field.name }};
{{ utils.formatValueSetter(object, field.name, field.type.type.baseTypeName, field.nullable ) }}
{%- endfor -%}

View File

@ -1,18 +1,4 @@
{%- import '../../utils.twig' as utils -%}
{% for field in fields %}
{%- if field.nullable or field.optional %}
this.{{ field.name }} = ({{ utils.formatValueType(field.type.type, field.nullable, field.optional) }}) inputStream.readObject();
{%- elseif field.type.type.baseTypeName == "Int" %}
this.{{ field.name }} = inputStream.readInt();
{%- elseif field.type.type.baseTypeName == "Long" %}
this.{{ field.name }} = inputStream.readLong();
{%- elseif field.type.type.baseTypeName == "Double" %}
this.{{ field.name }} = inputStream.readDouble();
{%- elseif field.type.type.baseTypeName == "String" %}
this.{{ field.name }} = inputStream.readUTF();
{%- elseif field.type.type.baseTypeName == "Bool" %}
this.{{ field.name }} = inputStream.readBoolean();
{%- else %}
this.{{ field.name }} = ({{ utils.formatValueType(field.type.type, field.nullable, field.optional) }}) inputStream.readObject();
{%- endif -%}
{%- endfor -%}
this.{{ field.name }} = {{ utils.formatReadObject(field.type.type, field.nullable, field.optional) }};
{%- endfor -%}

View File

@ -1,44 +1,4 @@
{%- import '../../utils.twig' as utils -%}
{%- for field in fields %}
{%- if not (field.nullable or field.optional)
and field.type.type.baseTypeName != "Int"
and field.type.type.baseTypeName != "Long"
and field.type.type.baseTypeName != "Double"
and field.type.type.baseTypeName != "Bool" %}
validateNotNull(this.{{ field.name }});
{%- endif %}
{%- if field.type.type.baseTypeName == "Map" %}
{%- if field.nullable or field.optional %}
if (this.{{ field.name }} != null) {
validateCollection(this.{{ field.name }}.values(), CollectionValidationRule.EXCEPTION_IF_ANY_INVALID);
}
{%- else %}
validateCollection(this.{{ field.name }}.values(), CollectionValidationRule.EXCEPTION_IF_ANY_INVALID);
{%- endif %}
{%- elseif field.type.type.baseTypeName == "Array" %}
{%- if field.nullable or field.optional %}
if (this.{{ field.name }} != null) {
validateCollection(this.{{ field.name }}, CollectionValidationRule.EXCEPTION_IF_ANY_INVALID);
}
{%- else %}
validateCollection(this.{{ field.name }}, CollectionValidationRule.EXCEPTION_IF_ANY_INVALID);
{%- endif %}
{%- elseif field.type.type.baseTypeName != "Int"
and field.type.type.baseTypeName != "Long"
and field.type.type.baseTypeName != "Double"
and field.type.type.baseTypeName != "Bool"
and field.type.type.baseTypeName != "String"
and field.type.type.baseTypeName != "Decimal"
and field.type.type.baseTypeName != "DateTime"
and (field.type.values is empty) %}
if (this.{{ field.name }} instanceof ApiModel) {
{%- if field.nullable or field.optional %}
if (this.{{ field.name }} != null) {
((ApiModel) this.{{ field.name }}).validate();
}
{%- else %}
((ApiModel) this.{{ field.name }}).validate();
{%- endif %}
}
{%- endif -%}
{% for field in fields -%}
{{ utils.formatValidateObject(concat("this.", field.name), field.type, field.type.type, field.nullable, field.optional) }}
{%- endfor -%}

View File

@ -1,17 +1,4 @@
{%- import '../../utils.twig' as utils -%}
{% for field in fields %}
{%- if field.nullable or field.optional %}
outputStream.writeObject(this.{{ field.name }});
{%- elseif field.type.type.baseTypeName == "Int" %}
outputStream.writeInt(this.{{ field.name }});
{%- elseif field.type.type.baseTypeName == "Long" %}
outputStream.writeLong(this.{{ field.name }});
{%- elseif field.type.type.baseTypeName == "Double" %}
outputStream.writeDouble(this.{{ field.name }});
{%- elseif field.type.type.baseTypeName == "String" %}
outputStream.writeUTF(this.{{ field.name }});
{%- elseif field.type.type.baseTypeName == "Bool" %}
outputStream.writeBoolean(this.{{ field.name }});
{%- else %}
outputStream.writeObject(this.{{ field.name }});
{%- endif -%}
{%- endfor -%}
outputStream.{{ utils.formatWriteObject(field.name, field.type.type, field.nullable, field.optional) }};
{%- endfor -%}

View File

@ -1,23 +1,14 @@
{%- import '../../utils.twig' as utils -%}
{%- for field in fields %}
{%- if (field.description is not empty) %}
/**
* {{ field.description }}
*/
{%- endif %}
{{ utils.writeNullCheckAnnotation(field.type.type.baseTypeName, field.nullable, field.optional) }}
{%- if (storageAttributes is not null) %}
{%- if (field.type.storable) %}
@TypeConverters({{ field.type.type.baseTypeName }}.class)
{%- endif %}
{%- if (field.autoGenerate) %}
@PrimaryKey(autoGenerate = true)
{%- endif %}
{%- endif %}
{%- if (storageAttributes is null) or (field.autoGenerate != true) %}
{%- if fields is not empty -%}
{% for field in fields %}
{% if (field.description is not empty) %}
/**
* {{ field.description }}
*/
{% endif -%}
@JsonField(name = "{{ field.jsonName }}")
{%- endif %}
private {{ utils.formatValueType(field.type.type, field.nullable, field.optional) }} {{ field.name }};
{%- endfor -%}
{{ utils.writeNullCheckAnnotation(field.type.type.baseTypeName, field.nullable, field.optional) }}
private {{ utils.formatValueType(field.type.type, field.nullable, field.optional) }} {{ field.name }} {%- if field.optional %} = {{ utils.formatOptionalValueType(field.type.type, field.nullable) }}.empty(){% endif %};
{% endfor -%}
{% endif %}

View File

@ -1,7 +1,7 @@
{%- import '../../utils.twig' as utils -%}
{%- 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 %}
{%- 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 %}
{%- endfor -%}
{%- endif -%}
{%- endif -%}

View File

@ -2,7 +2,7 @@
{%- if typeParameters is not empty -%}
<
{%- for typeParameter in typeParameters %}
{{- utils.formatValueType(typeParameter, true, true) -}}{%- if not (loop.last) %}, {% endif %}
{{- utils.formatSimpleValueType(typeParameter) -}}{%- if not (loop.last) %}, {% endif %}
{%- endfor -%}
>
{%- endif -%}
{%- endif -%}

View File

@ -1,11 +1,10 @@
{%- import '../../utils.twig' as utils -%}
{%- for value in values %}
{%- if (value.description is not empty) %}
{% if (value.description is not empty) %}
/**
* {{ value.description }}
*/
{%- endif %}
* {{ value.description }}
*/
{% endif -%}
{%- if valuesTypes == "STRING" %}
@JsonStringValue("{{ value.value }}")
{%- elseif valuesTypes == "INT" %}

View File

@ -1,22 +0,0 @@
{%- if storable %}
@TypeConverter
@Nullable
public static String serialize(@Nullable final {{ name }} value) {
if (value == null) {
return null;
}
return value.name();
}
@TypeConverter
@Nullable
public static {{ name }} deserialize(@Nullable final String value) {
if (value == null) {
return null;
}
return {{ name }}.valueOf(value);
}
{%- endif -%}

View File

@ -4,4 +4,4 @@
*/
@NonNull
@POST("{{ method.url }}")
Single<BaseResponse<{{ method.responseType.type.typeName }}>> {{ lower(method.name) }}(@NonNull @Body {{ method.bodyType.type.typeName }} {{ lower(method.bodyType.type.typeName) }});
Single<BaseResponse<{{ method.responseType.type.typeName }}>> {{ utils.decapitalize(method.name) }}(@NonNull @Body {{ method.bodyType.type.typeName }} {{ utils.decapitalize(method.bodyType.type.typeName) }});

View File

@ -1,3 +1,19 @@
{% macro decapitalize(text) %}
{{- concat(slice(text, 0, 1) | lower, slice(text, 1, text | length)) -}}
{% endmacro %}
{% macro capitalize(text) %}
{{- concat(slice(text, 0, 1) | upper, slice(text, 1, text | length)) -}}
{% endmacro %}
{% macro enumType(valuesTypes) %}
{%- if valuesTypes == "STRING" -%}
String
{%- elseif valuesTypes == "INT" -%}
Int
{%- endif -%}
{% endmacro %}
{% macro parentClassType(parent) %}
{%- if parent is not null %}
{{- parent.type.baseTypeName -}}
@ -7,30 +23,257 @@ LoganSquareJsonModel
{% endmacro %}
{% macro writeNullCheckAnnotation(baseTypeName, nullable, optional) %}
{%- if nullable or optional -%}
{%- if optional -%}
@NonNull
{%- elseif nullable -%}
@Nullable
{%- elseif not (baseTypeName == "Int" or baseTypeName == "Long" or baseTypeName == "Double" or baseTypeName == "Bool") -%}
@NonNull
{%- endif -%}
{% endmacro %}
{% macro formatValueType(valueType, nullable, optional) %}
{% macro formatNonOptionalValueType(valueType, tryUsePrimitive) %}
{% import _self as self %}
{%- if valueType.baseTypeName == "Int" -%}
{%- if nullable or optional -%}Integer{%- else -%}int{%- endif -%}
{%- if tryUsePrimitive -%}int{%- else -%}Integer{%- endif -%}
{%- elseif valueType.baseTypeName == "Long" -%}
{%- if nullable or optional -%}Long{%- else -%}long{%- endif -%}
{%- if tryUsePrimitive -%}long{%- else -%}Long{%- endif -%}
{%- elseif valueType.baseTypeName == "Double" -%}
{%- if nullable or optional -%}Double{%- else -%}double{%- endif -%}
{%- elseif valueType.baseTypeName == "Bool" -%}
{%- if nullable or optional -%}Boolean{%- else -%}boolean{%- endif -%}
{%- if tryUsePrimitive -%}double{%- else -%}Double{%- endif -%}
{%- elseif valueType.baseTypeName == "Decimal" -%}
BigDecimal
{%- elseif valueType.baseTypeName == "Bool" -%}
{%- if tryUsePrimitive -%}boolean{%- else -%}Boolean{%- endif -%}
{%- elseif valueType.baseTypeName == "Map" -%}
Map<{{ self.formatValueType(valueType.keysType, true, true) }}, {{ self.formatValueType(valueType.valuesType, true, true) }}>
Map<{{ self.formatNonOptionalValueType(valueType.keysType, false) }}, {{ self.formatNonOptionalValueType(valueType.valuesType, false) }}>
{%- elseif valueType.baseTypeName == "Array" -%}
List<{{ self.formatValueType(valueType.itemsType, true, true) }}>
List<{{ self.formatNonOptionalValueType(valueType.itemsType, false) }}>
{%- else -%}
{{ valueType.baseTypeName }}
{%- endif -%}
{% endmacro %}
{% macro formatOptionalValueType(valueType, nullable) %}
{% import _self as self %}
{%- if nullable -%} JsonOptional {%- else -%} NonNullJsonOptional {%- endif -%}
{% endmacro %}
{% macro formatValueType(valueType, nullable, optional) %}
{% import _self as self %}
{%- if optional -%}
{{ self.formatOptionalValueType(valueType, nullable) }}<{{ self.formatNonOptionalValueType(valueType, false) }}>
{%- else -%}
{{ self.formatNonOptionalValueType(valueType, not nullable) }}
{%- endif -%}
{% endmacro %}
{% macro formatSimpleValueType(valueType) %}
{%- import _self as self -%}
{{- self.formatValueType(valueType, true, false) -}}
{% endmacro %}
{% macro formatNullableValueSetter(fieldName, valueType, nullable) %}
{%- if valueType == "List" -%}
{%- if nullable -%}
{{ fieldName }} != null ? new ArrayList<>({{ fieldName }}) : null
{%- else -%}
new ArrayList<>({{ fieldName }})
{%- endif -%}
{%- elseif valueType == "Map" -%}
{%- if nullable -%}
{{ fieldName }} != null ? new HashMap<>({{ fieldName }}) : null
{%- else -%}
new HashMap<>({{ fieldName }})
{%- endif -%}
{%- else -%}
{{ fieldName }}
{%- endif -%}
{% endmacro %}
{% macro formatValueSetter(object, fieldName, valueType, nullable) %}
{% import _self as self %}
{%- if nullable -%}
{{ object }}.{{ fieldName }} = {{ self.formatNullableValueSetter(fieldName, valueType, nullable)}};
{%- else -%}
{{ object }}.{{ fieldName }} = {{ fieldName }};
{%- endif -%}
{% endmacro %}
{% macro formatNullableValueGetter(fieldName, valueType, nullable) %}
{%- if valueType == "List" -%}
{%- if nullable -%}
{{ fieldName }} != null ? Collections.unmodifiableList({{ fieldName }}) : null
{%- else -%}
Collections.unmodifiableList({{ fieldName }})
{%- endif -%}
{%- elseif valueType == "Map" -%}
{%- if nullable -%}
{{ fieldName }} != null ? Collections.unmodifiableMap({{ fieldName }}) : null
{%- else -%}
Collections.unmodifiableMap({{ fieldName }})
{%- endif -%}
{%- else -%}
{{ fieldName }}
{%- endif -%}
{% endmacro %}
{% macro formatValueGetter(fieldName, valueType, nullable) %}
{% import _self as self %}
{%- if nullable -%}
return {{ self.formatNullableValueGetter(fieldName, valueType, nullable) }};
{%- else -%}
return this.{{ fieldName }};
{%- endif -%}
{% endmacro %}
{% macro formatEquals(fieldName, valueType, optional) %}
{%- if valueType == "List" -%}
ObjectUtils.isCollectionsEquals({{ fieldName }}{%- if optional -%} .get() {%- endif -%}, that.{{ fieldName }}{%- if optional -%} .get() {%- endif -%})
{%- elseif valueType == "Map" -%}
ObjectUtils.isMapsEquals({{ fieldName }}{%- if optional -%} .get() {%- endif -%}, that.{{ fieldName }}{%- if optional -%} .get() {%- endif -%})
{%- else -%}
ObjectUtils.equals({{ fieldName }}, that.{{ fieldName }})
{%- endif -%}
{% endmacro %}
{% macro escapeIfNeeded(expr) %}
{%- if expr == "default" -%}
`{{ expr }}`
{%- else -%}
{{ expr }}
{%- endif -%}
{% endmacro %}
{% macro mappingFromMapForField(field) %}
{%- if field.type.type.baseTypeName == "DateTime" -%}
map.value("{{ field.jsonName }}", using: {{ field.name -}}Transform)
{%- else -%}
map.value("{{ field.jsonName }}")
{%- endif -%}
{% endmacro %}
{% macro mappingToMapForField(field) %}
{%- if field.type.type.baseTypeName == "DateTime" -%}
(map["{{ field.jsonName }}"], {{ field.name -}}Transform)
{%- else -%}
map["{{ field.jsonName }}"]
{%- endif -%}
{% endmacro %}
{% macro formatWriteObject(fieldName, valueType, nullable, optional) %}
{%- if nullable or optional -%}
writeObject({{ fieldName }})
{%- else -%}
{%- if valueType.baseTypeName == "Int" -%}
writeInt({{ fieldName }})
{%- elseif valueType.baseTypeName == "Long" -%}
writeLong({{ fieldName }})
{%- elseif valueType.baseTypeName == "Double" -%}
writeDouble({{ fieldName }})
{%- elseif valueType.baseTypeName == "String" -%}
writeUTF({{ fieldName }})
{%- elseif valueType.baseTypeName == "Bool" -%}
writeBoolean({{ fieldName }})
{%- else -%}
writeObject({{ fieldName }})
{%- endif -%}
{%- endif -%}
{% endmacro %}
{% macro formatReadObject(valueType, nullable, optional) %}
{% import _self as self %}
{%- if nullable or optional -%}
({{ self.formatValueType(valueType, nullable, optional) }}) inputStream.readObject()
{%- else -%}
{%- if valueType.baseTypeName == "Int" -%}
inputStream.readInt()
{%- elseif valueType.baseTypeName == "Long" -%}
inputStream.readLong()
{%- elseif valueType.baseTypeName == "Double" -%}
inputStream.readDouble()
{%- elseif valueType.baseTypeName == "String" -%}
inputStream.readUTF()
{%- elseif valueType.baseTypeName == "Bool" -%}
inputStream.readBoolean()
{%- else -%}
({{ self.formatValueType(valueType, nullable, optional) }}) inputStream.readObject()
{%- endif -%}
{%- endif -%}
{% endmacro %}
{% macro formatValidateObject(object, valueTopType, valueType, nullable, optional) %}
{% import _self as self %}
{%- if not nullable
and valueType.baseTypeName != "Int"
and valueType.baseTypeName != "Long"
and valueType.baseTypeName != "Double"
and valueType.baseTypeName != "Bool" %}
{%- if optional %}
if (!{{ object }}.isEmpty()) {
validateNotNull({{ object }}.get());
}
{%- else %}
validateNotNull({{ object }});
{%- endif -%}
{%- endif -%}
{%- if valueType.baseTypeName == "Map" %}
{%- if optional %}
if ({{ object }}.get() != null) {
validateCollection({{ object }}.get().values(), CollectionValidationRule.EXCEPTION_IF_ANY_INVALID);
}
{%- else -%}
{%- if nullable %}
if ({{ object }} != null) {
validateCollection({{ object }}.values(), CollectionValidationRule.EXCEPTION_IF_ANY_INVALID);
}
{%- else %}
validateCollection({{ object }}.values(), CollectionValidationRule.EXCEPTION_IF_ANY_INVALID);
{%- endif -%}
{%- endif -%}
{%- elseif valueType.baseTypeName == "Array" %}
{%- if optional %}
if ({{ object }}.get() != null) {
validateCollection({{ object }}.get(), CollectionValidationRule.EXCEPTION_IF_ANY_INVALID);
}
{%- else %}
{%- if nullable %}
if ({{ object }} != null) {
validateCollection({{ object }}, CollectionValidationRule.EXCEPTION_IF_ANY_INVALID);
}
{%- else %}
validateCollection({{ object }}, CollectionValidationRule.EXCEPTION_IF_ANY_INVALID);
{%- endif -%}
{%- endif -%}
{%- elseif valueType.baseTypeName != "Int"
and valueType.baseTypeName != "Long"
and valueType.baseTypeName != "Double"
and valueType.baseTypeName != "Bool"
and valueType.baseTypeName != "String"
and valueType.baseTypeName != "Decimal"
and valueType.baseTypeName != "DateTime"
and (valueTopType.values is empty) %}
{%- if valueTopType.allFieldsOrdered is empty %}
if ({{ object }} instanceof ApiModel) {
((ApiModel) {{ object }}{%- if optional -%} .get() {%- endif -%}).validate();
} else if ({{ object }} instanceof List) {
validateCollection(((List) {{ object }}), CollectionValidationRule.EXCEPTION_IF_ANY_INVALID);
} else if ({{ object }} instanceof Map) {
validateCollection(((Map) {{ object }}).values(), CollectionValidationRule.EXCEPTION_IF_ANY_INVALID);
}
{%- elseif optional %}
if ({{ object }}.get() != null) {
{{ object }}.get().validate();
}
{%- elseif nullable %}
if ({{ object }} != null) {
{{ object }}.validate();
}
{%- else -%}
{{ object }}.validate();
{%- endif -%}
{%- endif -%}
{% endmacro %}

View File

@ -1,44 +0,0 @@
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

@ -1,14 +0,0 @@
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

@ -1,8 +0,0 @@
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

@ -1,14 +0,0 @@
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

@ -1,22 +0,0 @@
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

@ -1,16 +0,0 @@
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

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

View File

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

View File

@ -1,12 +0,0 @@
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

@ -1,16 +0,0 @@
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

@ -1,13 +0,0 @@
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

@ -1,22 +0,0 @@
/*
* This code is autogenerated by Touch Instinct tools
*/
@file:Suppress("UnusedImports")
package {{ packageName }}.api
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) -%}
/**
* {{ description }}
*/
{% endif -%}
open class {% include 'blocks/class/classtype.twig' with { type: type } %} (
{%- include 'blocks/class/constructor-fields-info.twig' with { fields: allFieldsOrdered, superclassesFields: superclassesFields } %}
){% include 'blocks/class/supertype.twig' with { type: type, parent: parent } %} {%- include 'blocks/class/fields-super-initialization.twig' with { fields: superclassesFields } %}

View File

@ -1,18 +0,0 @@
{%- import 'utils.twig' as utils -%}
/*
* This code is autogenerated by Touch Instinct tools
*/
package {{ packageName }}.api
import com.fasterxml.jackson.annotation.JsonValue
/**
* {{ description }}
*/
enum class {{ name }}(val code: {{ utils.formatEnumValueType(valuesTypes) }}, val description: String) {
{% include 'blocks/enum/cases.twig' with { valuesTypes: valuesTypes, values: values } %}
@JsonValue
fun toValue() = code
}

View File

@ -1 +0,0 @@
{{- type.baseTypeName -}}{%- include 'type-parameters.twig' with { typeParameters: type.typeParameters } -%}

View File

@ -1,16 +0,0 @@
{%- import '../../utils.twig' as utils -%}
{%- for field in fields %}
{%- if field.type.type.baseTypeName == "DateTime" %}
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "{{ utils.getDateFormat(field) }}", timezone = "utc")
{%- endif %}
{%- 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

@ -1,7 +0,0 @@
{%- if fields is not empty -%}
(
{%- for field in fields -%}
{{ field.name }} {%- if not (loop.last) %}, {% endif %}
{%- endfor -%}
)
{%- endif -%}

View File

@ -1,3 +0,0 @@
{%- import '../../utils.twig' as utils -%}
{{- utils.parentClassType(parent) -}}{%- include 'type-parameters.twig' with { typeParameters: type.parentTypeParameters } -%}

View File

@ -1,8 +0,0 @@
{%- import '../../utils.twig' as utils -%}
{%- if typeParameters is not empty -%}
<
{%- for typeParameter in typeParameters %}
{{- utils.formatValueType(typeParameter, true, true) -}}{%- if not (loop.last) %}, {% endif %}
{%- endfor -%}
>
{%- endif -%}

View File

@ -1,4 +0,0 @@
{%- import '../../utils.twig' as utils -%}
{%- for value in values %}
{{ value.nameUpperCaseWithUnderscope }}({{ utils.formatEnumValue(valuesTypes, value) }}, "{{ value.description }}"){%- if not (loop.last) %},{% else %};{% endif %}
{%- endfor -%}

View File

@ -1,44 +0,0 @@
{% macro parentClassType(parent) %}
{%- if parent is not null %} : {{ parent.type.baseTypeName }}{%- endif -%}
{% endmacro %}
{% macro writeNullCheckMark(nullable, optional) %}
{%- if nullable or optional -%}
?
{%- endif -%}
{% endmacro %}
{% macro formatValueType(valueType, nullable, optional) %}
{% import _self as self %}
{%- if valueType.baseTypeName == "Bool" -%}
Boolean
{%- elseif valueType.baseTypeName == "DateTime" -%}
ZonedDateTime
{%- elseif valueType.baseTypeName == "Date" -%}
LocalDate
{%- elseif valueType.baseTypeName == "Decimal" -%}
BigDecimal
{%- elseif valueType.baseTypeName == "Map" -%}
Map<{{ self.formatValueType(valueType.keysType, true, true) }}, {{ self.formatValueType(valueType.valuesType, true, true) }}>
{%- elseif valueType.baseTypeName == "Array" -%}
List<{{ self.formatValueType(valueType.itemsType, true, true) }}>
{%- else -%}
{% include 'blocks/class/classtype.twig' with { type: valueType } %}
{%- endif -%}
{% endmacro %}
{% macro formatEnumValueType(valuesTypes) %}
{%- if valuesTypes == "STRING" -%}String{%- elseif valuesTypes == "INT" -%}Int{%- endif -%}
{% endmacro %}
{% macro formatEnumValue(valuesTypes, value) %}
{%- if valuesTypes == "STRING" -%}"{{ value.value }}"{%- elseif valuesTypes == "INT" -%}{{ value.value }}{%- endif -%}
{% endmacro %}
{% macro addDescription(field) %}
{%- if (field.description is not empty) %} // {{ field.description }}{%- endif -%}
{% endmacro %}
{%- macro getDateFormat(field) -%}
{{ field.type.dateFormat|replace({'Z':'X'}) }}
{%- endmacro -%}

View File

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

View File

@ -1,45 +0,0 @@
{%- import 'macroses/common.utils.twig' as utils -%}
import LeadKit
import Foundation
public enum ApiNumberFormat: NumberFormat {
case decimal
public var numberFormatter: NumberFormatter {
let numberFormatter = NumberFormatter()
numberFormatter.decimalSeparator = "."
numberFormatter.minimumIntegerDigits = 1
numberFormatter.maximumFractionDigits = 16
return numberFormatter
}
}
public final class ApiNumberFormattingService: NumberFormattingService, Singleton {
public typealias NumberFormatType = ApiNumberFormat
public static let shared = ApiNumberFormattingService()
public let formatters = computedFormatters
private init() {}
public func decimalNumber(from string: String, format: ApiNumberFormat) -> NSDecimalNumber? {
guard let number = number(from: string, format: format) else {
return nil
}
return NSDecimalNumber(decimal: number.decimalValue)
}
}
extension ApiNumberFormattingService {
public static func decimalNumber(from string: String, format: ApiNumberFormat) -> NSDecimalNumber? {
return shared.decimalNumber(from: string, format: format)
}
}
{{ "\n" }}

View File

@ -7,19 +7,20 @@
{%- set hasGenerics = utils.valueTypeHasGenerics(type) != null %}
{%- for field in allFieldsOrdered -%}
{%- set fieldsHasGenericsOrNonEqutableCollections = default(fieldsHasGenericsOrNonEqutableCollections, false) or (utils.hasGenericsOrNonEqutableCollections(field.type) != null) -%}
{%- set classAndFieldsHaveNotGenericsOrNonEqutableCollections = (not hasGenerics) and (not fieldsHasGenericsOrNonEqutableCollections) -%}
{%- endfor -%}
import SwiftDate
import LeadKit
/// {{ description }}
public {% if (not hasChilds) -%}final {% endif %}class {{ classType }}: {{ parentClassType }} {
{% 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
public {% if (hasParent and (fields is empty)) %} override {% endif %}init({%- include 'blocks/class/init-parameters-fields.twig' with { fields: allFieldsOrdered } -%}) {
{% 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 +28,7 @@ public {% if (not hasChilds) -%}final {% endif %}class {{ classType }}: {{ paren
}
{% if hasParent or fields is not empty %}
public required init(from decoder: Decoder) throws {
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 +38,7 @@ public {% if (not hasChilds) -%}final {% endif %}class {{ classType }}: {{ paren
}
{% endif %}
public {% if hasParent -%}override {% endif %}func encode(to encoder: Encoder) throws {
{% 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 -%}
@ -46,8 +47,8 @@ public {% if (not hasChilds) -%}final {% endif %}class {{ classType }}: {{ paren
{%- endif %}
}
{% if classAndFieldsHaveNotGenericsOrNonEqutableCollections -%}
public func isEqual(to other: {{ classType }}?) -> Bool {
{% if (not hasGenerics) and (not fieldsHasGenericsOrNonEqutableCollections) -%}
func isEqual(to other: {{ classType }}?) -> Bool {
{% if (fields is empty) and (not hasParent) %}
return false
{% else %}
@ -55,28 +56,33 @@ public {% if (not hasChilds) -%}final {% endif %}class {{ classType }}: {{ paren
return false
}
return{%- if hasParent %} super.isEqual(to: other){%- endif %}{%- if (fields is not empty) and hasParent %} &&{% endif %} {% include 'blocks/class/fields-equal.twig' with { fields: fields } %} {% endif %}
}
return{%- if hasParent %} super.isEqual(to: other){%- endif %}{%- if (fields is not empty) and hasParent %} &&{% endif %} {% include 'blocks/class/fields-equal.twig' with { fields: fields } %}
{% endif %}
}{{ "\n" }}
{%- endif %}
}
{{ "\n" }}
{%- if (not hasChilds) and classAndFieldsHaveNotGenericsOrNonEqutableCollections -%}
{%- if (not hasChilds) and (not hasGenerics) and (not fieldsHasGenericsOrNonEqutableCollections) -%}
extension {{ type.baseTypeName }}: Equatable {
public static func ==(lhs: {{ classType }}, rhs: {{ classType }}) -> Bool {
static func ==(lhs: {{ classType }}, rhs: {{ classType }}) -> Bool {
return lhs.isEqual(to: rhs)
}
}
{{ "\n" }}
{%- endif -%}
{%- if classAndFieldsHaveNotGenericsOrNonEqutableCollections -%}
{%- if not hasGenerics -%}
extension {{ type.baseTypeName }} {
public static let new{{ type.baseTypeName }} = {{ type.baseTypeName }}({%- include 'blocks/class/fields-initialization-default-values.twig' with { fields: allFieldsOrdered } -%})
static let new{{ type.baseTypeName }} = {{ type.baseTypeName }}({%- include 'blocks/class/fields-initialization-default-values.twig' with { fields: allFieldsOrdered } -%})
func copy{%- if hasChilds -%}{{ type.baseTypeName }}{%- endif -%}With({%- include 'blocks/class/nullable-parameters-fields.twig' with { fields: allFieldsOrdered } -%}) -> {{ type.baseTypeName }} {
return {{ type.baseTypeName }}({%- include 'blocks/class/fields-optional-initialization.twig' with { fields: allFieldsOrdered } -%})
}
{% include 'blocks/class/copy-declaration.twig' with { hasChilds: hasChilds, type: type, fields: allFieldsOrdered } %}
}
{{ "\n" }}
{%- endif -%}

View File

@ -1,12 +1,17 @@
{%- import 'macroses/common.utils.twig' as utils -%}
{%- import 'macroses/enum.utils.twig' as enumutils -%}
import Foundation
/// {{ description }}
///
{% for value in values -%}
/// - {{ utils.decapitalize(value.name) }}: {{ value.description }}
{% endfor -%}
public enum {{ name }}: {{ enumutils.enumType(valuesTypes) }}, Codable, RawRepresentable, CaseIterable {
enum {{ name }}: {{ enumutils.enumType(valuesTypes) }}, Codable, RawRepresentable {
{% include 'blocks/enum/all-items.twig' %}
{% include 'blocks/enum/cases.twig' with { values: values } %}
}
{{ "\n" }}
{{ "\n" }}

View File

@ -8,6 +8,7 @@ extension {{ serviceName }} {
{% for method in methods %}
{%- include 'blocks/method/method-func.twig' with { method: method, isStatic: false } %}
{% endfor %}
}
@ -15,5 +16,7 @@ extension Singleton where Self: {{ serviceName }} {
{% for method in methods %}
{%- include 'blocks/method/method-func.twig' with { method: method, isStatic: true } %}
{% endfor %}
}
{{ "\n" }}

View File

@ -3,48 +3,29 @@ import RxSwift
import Alamofire
{% set serviceName = concat(networkServiceName, "NetworkService") -%}
{% set protocolName = concat(networkServiceName, "NetworkProtocol") -%}
class {{ serviceName }}: NetworkService {
public protocol {{ protocolName }} {
static let apiBaseUrl = "{{ apiUrl }}"
func apiRequest<T: Decodable>(with parametersSingle: Single<ApiRequestParameters>, additionalValidStatusCodes: Set<Int>, decoder: JSONDecoder) -> Single<T>
func deferredApiRequestParameters(relativeUrl: String,
method: HTTPMethod,
parameters: Parameters?,
requestEncoding: ParameterEncoding?,
requestHeaders: HTTPHeaders?) -> Single<ApiRequestParameters>
{% for method in methods %}
{%- include 'blocks/method/method-declaration.twig' with { method: method, isStatic: false } -%}
{% endfor %}
}
open class {{ serviceName }}: NetworkService, {{ protocolName }} {
public static let apiBaseUrl = "{{ apiUrl }}"
public convenience init() {
convenience init() {
self.init(configuration: NetworkServiceConfiguration(baseUrl: {{ serviceName }}.apiBaseUrl))
}
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 apiRequest<T: Decodable>(with parameters: ApiRequestParameters, decoder: JSONDecoder = JSONDecoder()) -> Single<T> {
return rxRequest(with: parameters, decoder: decoder).map { $0.model }.asSingle()
}
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,
parameters: parameters,
requestEncoding: requestEncoding,
requestHeaders: requestHeaders)
}
func apiRequestParameters(relativeUrl: String,
method: HTTPMethod = .get,
parameters: Parameters? = nil,
requestEncoding: ParameterEncoding? = nil,
requestHeaders: HTTPHeaders? = nil) -> ApiRequestParameters {
return configuration.apiRequestParameters(relativeUrl: relativeUrl,
method: method,
parameters: parameters,
requestEncoding: requestEncoding,
requestHeaders: requestHeaders)
}
}
{{ "\n" }}

View File

@ -1,13 +0,0 @@
{%- import '../../macroses/common.utils.twig' as utils -%}
{%- if fields is not empty -%}
{%- set nullableOptionalFields = [] -%}
{%- for field in fields -%}
{%- if field.nullable or field.optional -%}
{%- set nullableOptionalFields = nullableOptionalFields|merge([field]) -%}
{%- endif -%}
{%- endfor -%}
{%- for field in nullableOptionalFields -%}
{{ field.name }}: Bool = false{%- if not (loop.last) %}, {% endif %}
{%- endfor -%}
{%- endif -%}

View File

@ -1,20 +0,0 @@
{%- import '../../macroses/common.utils.twig' as utils -%}
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 } %})
}
{%- if allFieldsOrdered is not empty -%}
{%- for field in allFieldsOrdered -%}
{%- if field.nullable or field.optional -%}
{%- set containsOptionalFields = true -%}
{%- endif -%}
{%- endfor -%}
{%- endif -%}
{% if containsOptionalFields %}
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

@ -1,11 +0,0 @@
{%- import '../../macroses/common.utils.twig' as utils -%}
{%- if fields is not empty -%}
{%- for field in fields -%}
{%- if field.nullable or field.optional -%}
{{ field.name }}: {{ field.name }} ? nil : self.{{ field.name }}{%- if not (loop.last) %}, {% endif %}
{%- else -%}
{{ field.name }}: self.{{ field.name }}{%- if not (loop.last) %}, {% endif %}
{%- endif -%}
{%- endfor -%}
{%- endif -%}

View File

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

View File

@ -0,0 +1,8 @@
{% import '../../macroses/common.utils.twig' as utils -%}
static var allItems: [{{ name }}] {
{{ " " }}return [
{%- for value in values -%}
.{{ utils.decapitalize(value.name) }}{%- if not (loop.last) -%}, {% endif -%}
{%- endfor -%}
]
{{ " " }}}

View File

@ -1,12 +0,0 @@
{%- import '../../macroses/common.utils.twig' as utils -%}
{%- if (method.bodyType is not null) -%}
{%- set bodyParamName = utils.decapitalize(method.bodyType.type.typeName) -%}
{%- set bodyTypeName = method.bodyType.type.typeName -%}
{%- set hasBody = true -%}
{%- endif -%}
{%- set funcName = utils.decapitalize(method.name) -%}
{{ isStatic ? "static " : "" }}func {{ funcName }}({%- if hasBody -%}{{ bodyParamName }}: {{ bodyTypeName }},{{ " " }}{%- endif -%}requestEncoding: ParameterEncoding?, requestHeaders: HTTPHeaders?, additionalValidStatusCodes: Set<Int>) -> Single<{{ utils.formatValueType(method.apiResponseType) }}>

View File

@ -11,24 +11,21 @@
{%- set funcName = utils.decapitalize(method.name) -%}
/// {{ method.description }}
public {{ isStatic ? "static " : "" }}func {{ funcName }}({%- if hasBody -%}{{ bodyParamName }}: {{ bodyTypeName }},{{ "\n " }}{%- endif -%}
{{ isStatic ? "static " : "" }}func {{ funcName }}({%- if hasBody -%}{{ bodyParamName }}: {{ bodyTypeName }},{{ "\n " }}{%- endif -%}
requestEncoding: ParameterEncoding? = nil,
requestHeaders: HTTPHeaders? = nil,
additionalValidStatusCodes: Set<Int> = []) -> Single<{{ utils.formatValueType(method.apiResponseType) }}> {
requestHeaders: HTTPHeaders? = nil) -> Single<{{ method.responseType.type.typeName }}> {
{% if isStatic -%}
return shared.{{ funcName }}({%- if hasBody -%}{{ bodyParamName }}: {{ bodyParamName }},{{ "\n " }}{%- endif -%}
requestEncoding: requestEncoding,
requestHeaders: requestHeaders,
additionalValidStatusCodes: additionalValidStatusCodes)
requestHeaders: requestHeaders)
{%- else -%}
let parameters = deferredApiRequestParameters(relativeUrl: "{{ method.url }}",
let parameters = apiRequestParameters(relativeUrl: "{{ method.url }}",
method: .{{ methodType }},
parameters: {% if hasBody -%}{{ bodyParamName }}.toJSON(){%- else -%}nil{%- endif -%},
requestEncoding: requestEncoding,
requestHeaders: requestHeaders)
return apiRequest(with: parameters, additionalValidStatusCodes: additionalValidStatusCodes, decoder: JSONDecoder())
return apiRequest(with: parameters)
{%- endif %}
}

View File

@ -12,79 +12,40 @@
{% macro formatValueType(valueType) %}
{%- import _self as self -%}
{%- set baseTypeName = valueType.baseTypeName -%}
{%- if baseTypeName == "Array" -%}
{%- if valueType.baseTypeName == "Array" -%}
[{{ self.formatValueType(valueType.itemsType) }}]
{%- elseif baseTypeName == "Map" -%}
{%- elseif valueType.baseTypeName == "Map" -%}
[{{ self.formatValueType(valueType.keysType) }}: {{ self.formatValueType(valueType.valuesType) }}]
{%- elseif baseTypeName == "Date" or baseTypeName == "DateTime" or baseTypeName == "DateTimeTimestamp" -%}
{%- elseif valueType.baseTypeName == "DateTime" -%}
DateInRegion
{%- elseif baseTypeName == "Long" -%}
{%- elseif valueType.baseTypeName == "Long" -%}
Int64
{%- elseif baseTypeName == "Decimal" or baseTypeName == "StringDecimal" -%}
{%- elseif valueType.baseTypeName == "Decimal" -%}
NSDecimalNumber
{%- elseif baseTypeName == "Url" -%}
URL
{%- elseif baseTypeName == "Color" -%}
UIColor
{%- else -%}
{{ baseTypeName }}
{{ valueType.baseTypeName }}
{%- endif -%}
{% endmacro %}
{% macro formatEncodingValue(field, isStrongLinkCaptured) %}
{%- import _self as self -%}
{%- set baseTypeName = field.type.type.baseTypeName -%}
{%- if baseTypeName == "Date" or baseTypeName == "DateTime" -%}
{{- self.formatEncodingDate(field) -}}
{%- elseif baseTypeName == "StringDecimal" -%}
{{- self.formatEncodingStringDecimal(field) -}}
{%- elseif baseTypeName == "Decimal" -%}
{{ self.formatFieldName(field, isStrongLinkCaptured) -}}.decimalValue
{%- elseif baseTypeName == "DateTimeTimestamp" -%}
Int({{ self.formatFieldName(field, isStrongLinkCaptured) -}}.timeIntervalSince1970)
{%- elseif baseTypeName == "Color" -%}
{{ self.formatFieldName(field, isStrongLinkCaptured) -}}.hexString
{%- elseif baseTypeName == "Url" -%}
{{ self.formatFieldName(field, isStrongLinkCaptured) -}}.absoluteString
{%- else -%}
{{ field.name }}
{%- endif -%}
{% endmacro %}
{% macro formatFieldName(field, isStrongLinkCaptured) %}
{% macro formatEncodingValue(field) %}
{%- import _self as self -%}
{%- if isStrongLinkCaptured -%}
{{ field.name }}
{%- else -%}
{%- if field.type.type.baseTypeName == "DateTime" -%}
ApiDateFormattingService.string(from: {{ self.formatNullableOrOptional(field.name, field.nullable, field.optional) -}}, format: .{{ dateFormatToName(field.type.dateFormat) }})
{%- elseif field.type.type.baseTypeName == "Decimal" -%}
{{ self.formatNullableOrOptional(field.name, field.nullable, field.optional) -}}
.decimalValue
{%- else -%}
{{ field.name }}
{%- endif -%}
{% endmacro %}
{%- macro formatEncodingDate(field) -%}
{%- if field.type.dateFormats is not empty -%}
ApiDateFormattingService.string(from: {{ field.name -}}, format: .{{- dateFormatToName(field.type.dateFormats[0]) -}})
{% macro escapeIfNeeded(expr) %}
{%- if expr == "default" -%}
`{{ expr }}`
{%- else -%}
ApiDateFormattingService.string(from: {{ field.name -}}, format: .{{- dateFormatToName(field.type.dateFormat) -}})
{%- endif -%}
{%- endmacro -%}
{%- macro formatEncodingStringDecimal(field) -%}
ApiNumberFormattingService.string(from: {{ field.name -}}, format: .decimal)
{%- endmacro -%}
{% macro encodeIfPresent(field) %}
{%- import _self as self -%}
{%- set baseTypeName = field.type.type.baseTypeName -%}
{% 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 -}})
}
{%- else -%}
try container.encodeIfPresent({{- self.formatEncodingValue(field, false) -}}, forKey: .{{- field.name -}})
{{ expr }}
{%- endif -%}
{% endmacro %}
@ -92,33 +53,45 @@
{%- import _self as self -%}
{%- if field.optional -%}
{{ self.encodeIfPresent(field) -}}
try container.encodeIfPresent({{ self.formatEncodingValue(field) }}, forKey: .{{ field.name }})
{%- elseif field.nullable -%}
if let {{ field.name }} = {{ field.name }} {
try container.encode({{- self.formatEncodingValue(field, true) -}}, forKey: .{{- field.name -}})
if let value = {{ self.formatEncodingValue(field) }} {
try container.encode(value, forKey: .{{ field.name }})
} else {
try container.encodeNil(forKey: .{{- field.name -}})
try container.encodeNil(forKey: .{{ field.name }})
}
{%- else -%}
try container.encode({{- self.formatEncodingValue(field, false) -}}, forKey: .{{- field.name -}})
try container.encode({{ self.formatEncodingValue(field) }}, forKey: .{{ field.name }})
{%- endif -%}
{% endmacro %}
{% macro decodeFromContainer(field) %}
{%- import _self as self -%}
{%- import 'complexField.utils.twig' as complexFieldUtils -%}
{%- 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 baseTypeName == "DateTimeTimestamp" -%}
{{ complexFieldUtils.decodeComplexField(field, "Int") -}}
{%- elseif baseTypeName == "Decimal" -%}
{{ complexFieldUtils.decodeComplexField(field, "Decimal") -}}
{% if field.type.type.baseTypeName == "DateTime" %}
{{ self.decodeComplexField(field, "String") }}
{% elseif field.type.type.baseTypeName == "Decimal" %}
{{ self.decodeComplexField(field, "Decimal") }}
{%- else -%}
self.{{ field.name }} = try container.{{- self.formatOptionalDecode(field) -}}({{ self.formatValueType(field.type.type) }}.self, forKey: .{{ field.name }})
{%- endif -%}
{% endmacro %}
{% macro decodeComplexField(field, decodingType) %}
{%- import _self as self -%}
{%- if field.optional or field.nullable -%}
if let {{ field.name }} = try container.decodeIfPresent({{ decodingType }}.self, forKey: .{{ field.name }}) {
{{ self.initExpr(field) }}
} else {
self.{{ field.name }} = nil
}
{%- else -%}
let {{ field.name }} = try container.decode({{ decodingType }}.self, forKey: .{{ field.name }})
{{ self.initExpr(field) }}
{%- endif -%}
{% endmacro %}
{% macro formatOptionalDecode(field) %}
{%- if field.optional or field.nullable -%}
decodeIfPresent
@ -127,20 +100,24 @@
{%- endif -%}
{% endmacro %}
{% macro initExpr(field) %}
{%- if field.type.type.baseTypeName == "DateTime" -%}
if let date = ApiDateFormattingService.date(from: {{ field.name }}, format: .{{ dateFormatToName(field.type.dateFormat) }}, parsedIn: nil) {
self.{{ field.name }} = date
} else {
throw LeadKitError.failedToDecode(reason: "init?(string:format:fromRegion:) returned nil")
}
{%- elseif field.type.type.baseTypeName == "Decimal" -%}
self.{{ field.name }} = NSDecimalNumber(decimal: {{ field.name }})
{%- endif -%}
{% endmacro %}
{% macro enumValueName(value) %}
{%- import _self as self -%}
{{- self.decapitalize(value.name) -}}
{%- endmacro %}
{% macro escapeIfNeeded(expr) %}
{%- if expr == "default" or expr == "operator" -%}
`{{ expr }}`
{%- else -%}
{{ expr }}
{%- endif -%}
{% endmacro %}
{% macro defaultValueForField(field) %}
{%- set nullable = field.nullable -%}
{%- set optional = field.optional -%}
@ -154,7 +131,7 @@
[:]
{%- elseif baseTypeName == "String" -%}
""
{%- elseif baseTypeName == "Date" or baseTypeName == "DateTime" or baseTypeName == "DateTimeTimestamp" -%}
{%- elseif baseTypeName == "DateTime" -%}
Date().inDefaultRegion()
{%- elseif baseTypeName == "Double" -%}
0.0
@ -162,12 +139,8 @@
0
{%- elseif baseTypeName == "Bool" -%}
false
{%- elseif baseTypeName == "Decimal" or baseTypeName == "StringDecimal" -%}
{%- elseif baseTypeName == "Decimal" -%}
.zero
{%- elseif baseTypeName == "Color" -%}
.clear
{%- elseif baseTypeName == "Url" -%}
URL(string: "https://example.com")!
{%- elseif (field.type.values is not null) -%}
{%- import _self as self -%}

View File

@ -1,58 +0,0 @@
{% macro decodeComplexField(field, decodingType) %}
{%- import _self as self -%}
{%- if field.optional or field.nullable -%}
if let {{ field.name }} = try container.decodeIfPresent({{- decodingType -}}.self, forKey: .{{- field.name -}}) {
{{ self.initExpr(field) }}
} else {
self.{{ field.name }} = nil
}
{%- else -%}
let {{ field.name }} = try container.decode({{- decodingType -}}.self, forKey: .{{- field.name -}})
{{ self.initExpr(field) }}
{%- endif -%}
{% endmacro %}
{% macro initExpr(field) %}
{%- import _self as self -%}
{%- 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 baseTypeName == "Url" -%}
{%- set urlInit = "URL(string: %s)"|format(field.name) -%}
{{ self.decodeThrowableField(field, urlInit, 'Unable to decode URL from string') -}}
{%- 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 baseTypeName == "DateTimeTimestamp" -%}
self.{{ field.name }} = DateInRegion(seconds: TimeInterval({{ field.name }}))
{%- elseif baseTypeName == "Decimal" -%}
self.{{ field.name }} = NSDecimalNumber(decimal: {{ field.name }})
{%- endif -%}
{% endmacro %}
{%- macro decodeThrowableField(field, init, errorMessage) -%}
if let value = {{ init }} {
self.{{ field.name }} = value
} 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

@ -2,13 +2,11 @@
<body class="main-page">
<div class="aside aside-left">
<div class="aside__container">
<div class="header">
{%- include 'blocks/menu-header.html.twig' %}
</div>
<div class="content">
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
</div>
<div class="header">
<div class="title">{{ pageTitle }}</div>
</div>
<div class="content">
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
</div>
</div>
@ -25,12 +23,7 @@
{% if author is not empty %}
<h2>{{ author }}</h2>
{% endif %}
<p>Версия: {{ version }}</p>
{% if buildVersion|length %}
<p>Сборка: {{ buildVersion }}</p>
{% endif %}
<p>Версия {{ version }}</p>
<p>{{ "now"|date("dd.MM.YYYY") }}</p>
</div>
<h2 class="main-title">
@ -110,7 +103,7 @@
<div class="page-data section-helper">
<h2 class="subtitle" id="{{ methodGroup.sectionTitle }}">{{ methodGroup.title }}</h2>
{% if methodGroup.description is not null %}
<p>{{ methodGroup.description | escape }}</p>
<p>{{ methodGroup.description }}</p>
{% endif %}
{% if methodGroup.baseUrl is not empty %}
<p>BaseUrl: {{ methodGroup.baseUrl }}</p>

View File

@ -1,7 +1,7 @@
<h2 class="subtitle" id="{{ structure.type.baseTypeName }}">{{ structure.type.baseTypeName }}</h2>
<h3>Описание</h3>
<p class="sub-header">{{ structure.description | escape }}</p>
<p class="sub-header">{{ structure.description }}</p>
<h3>Структура данных</h3>
<div class="table">
@ -11,12 +11,15 @@
<div>Тип поля</div>
<div class="text-centered">Описание</div>
<div>Обязательность</div>
<div>Сервис</div>
<div>Название поля сервиса</div>
</div>
{% for field in structure.allFieldsUnordered -%}
{%- include 'field-row.html.twig' with {
field: field,
objectsLinks: objectsLinks,
useAnchors: useAnchors
useAnchors: useAnchors,
useServiceField: true
} %}
{%- endfor %}
</div>

View File

@ -1 +0,0 @@
{{- type.baseTypeName -}}{%- include 'type-parameters.twig' with { typeParameters: type.typeParameters } -%}

View File

@ -1,7 +1,7 @@
<h2 class="subtitle" id="{{ structure.name }}">{{ structure.name }}</h2>
<h3>Описание</h3>
<p class="sub-header">{{ structure.description | escape }}</p>
<p class="sub-header">{{ structure.description }}</p>
<h3>Возможные значения</h3>
<div class="table table--small">
@ -13,7 +13,7 @@
{% for value in structure.values %}
<div class="row-body">
<div>{{ value.value }}</div>
<div>{{ value.description | escape }}</div>
<div>{{ value.description }}</div>
</div>
{% endfor %}
</div>

View File

@ -28,9 +28,9 @@
{%- if link is not null -%}
<a class="info" href="{{ link }}">{{- utils.formatNullableClassType(valueType, nullable) -}}</a>
<a class="info" href="{{ link }}">{{- utils.formatNullable(valueType.typeName, nullable) -}}</a>
{%- else -%}
{{- utils.formatNullableClassType(valueType, nullable) -}}
{{- utils.formatNullable(valueType.typeName, nullable) -}}
{%- endif -%}
{%- endif -%}
{%- endmacro -%}
@ -41,11 +41,12 @@
<div class="row-body">
<div>{{ field.jsonName }}</div>
<div>
{{ self.formatValueType(field.type.type, field.nullable, objectsLinks, useAnchors) }}
{%- if field.type.type.typeName in ["DateTime", "Date"] -%}
&nbsp;({{ field.type.allDateFormats|join(', ') }})
{%- endif -%}
{{ self.formatValueType(field.type.type, field.nullable, objectsLinks, useAnchors) }}
</div>
<div>{{ field.description | escape }}</div>
<div>{{ field.description }}</div>
<div>{{ utils.optionalDescription(field.optional) }}</div>
{% if useServiceField %}
<div>{{ field.service }}</div>
<div>{{ field.serviceField }}</div>
{% endif %}
</div>

View File

@ -31,7 +31,8 @@
{%- include 'field-row.html.twig' with {
field: field,
objectsLinks: objectsLinks,
useAnchors: useAnchors
useAnchors: useAnchors,
useServiceField: false
} %}
{% endfor %}
</div>

View File

@ -1,4 +1,4 @@
<ul class="navigation">
<menu class="main">
{%- if mainMenu.indexMenuItem is not null %}
<li {%- if mainMenu.indexMenuItem.active %} class="active" {%- endif -%}><a href="{{ mainMenu.indexMenuItem.path }}">Общие принципы построения API</a></li>
@ -29,12 +29,7 @@
{% endif %}
{%- if mainMenu.allContents is not null %}
<li {%- if mainMenu.allContents.active %} class="active" {%- endif -%}>
<a href="{{ mainMenu.allContents.path }}">Версия для печати</a>
{% if buildVersion|length %}
<a href="/{{ pageTitle|replace({ " ": "_" }) }}__v{{ version }}.b{{ buildVersion }}.pdf" target="_blank" class="btn">Скачать PDF</a>
{% endif %}
</li>
<li {%- if mainMenu.allContents.active %} class="active" {%- endif -%}><a href="{{ mainMenu.allContents.path }}">Версия для печати</a></li>
{% endif %}
</ul>
</menu>

View File

@ -1,6 +0,0 @@
<div class="title">
{{ pageTitle }}&ensp;
<span class="title__hint">{{ "now"|date("dd.MM.YYYY") }}</span><span
class="title__hint">Версия:&nbsp;{{ version }}</span>{% if buildVersion|length %}<span
class="title__hint">Сборка:&nbsp;{{ buildVersion }}</span>{% endif %}
</div>

View File

@ -1,4 +1,4 @@
<h2 class="subtitle" id="{{ method.anchorPath }}">{{ method.description | escape }}</h2>
<h2 class="subtitle" id="{{ method.anchorPath }}">{{ method.description }}</h2>
<h3>Метод</h3>
<p class="sub-header">{{ method.type }} {{ method.url }}</p>
@ -23,7 +23,8 @@
{%- include 'field-row.html.twig' with {
field: field,
objectsLinks: objectsLinks,
useAnchors: useAnchors
useAnchors: useAnchors,
useServiceField: false
} %}
{%- endfor %}
</div>
@ -45,7 +46,8 @@
{%- include 'field-row.html.twig' with {
field: field,
objectsLinks: objectsLinks,
useAnchors: useAnchors
useAnchors: useAnchors,
useServiceField: false
} %}
{%- endfor %}
</div>
@ -66,7 +68,8 @@
{%- include 'field-row.html.twig' with {
field: field,
objectsLinks: objectsLinks,
useAnchors: useAnchors
useAnchors: useAnchors,
useServiceField: false
} %}
{%- endfor %}
</div>
@ -120,7 +123,7 @@
{% else %}
{% for value in method.errorsEnumeration.values -%}
{%- if value.value in method.errorsEnumeration.allowedValues %}
<p class="sub-header">#Код {{ value.value }}{{ value.description | escape }}</p>
<p class="sub-header">#Код {{ value.value }}{{ value.description }}</p>
{%- endif -%}
{%- endfor %}
{% endif %}
@ -130,7 +133,7 @@
<p class="sub-header">Результат отсутствует</p>
{% else %}
{% if method.booleanResponseDescription is not empty %}
<p>{{ method.booleanResponseDescription | escape }}. Тип Boolean.</p>
<p>{{ method.booleanResponseDescription }}. Тип Boolean.</p>
{% elseif method.responseFields is not empty %}
<p>Объект следующей структуры:</p>
@ -141,12 +144,15 @@
<div>Тип</div>
<div class="text-centered">Описание</div>
<div>Обязательность</div>
<div>Сервис</div>
<div>Название поля сервиса</div>
</div>
{% for field in method.responseFields -%}
{%- include 'field-row.html.twig' with {
field: field,
objectsLinks: objectsLinks,
useAnchors: useAnchors
useAnchors: useAnchors,
useServiceField: true
} %}
{%- endfor %}
</div>
@ -168,7 +174,8 @@
{%- include 'field-row.html.twig' with {
field: field,
objectsLinks: objectsLinks,
useAnchors: useAnchors
useAnchors: useAnchors,
useServiceField: false
} %}
{%- endfor %}
</div>

View File

@ -1,4 +1,4 @@
<script src="{{ jsFolderPath }}/jquery.min.js"></script>
<script src="{{ jsFolderPath }}/split.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="https://unpkg.com/split.js/split.min.js"></script>
<script type="text/javascript" src="{{ jsFolderPath }}/main.js?v=1.02"></script>
<script type="text/javascript" src="{{ jsFolderPath }}/searchItems.js?v=1.00"></script>

View File

@ -1,8 +1,8 @@
<li {%- if menu.active %} class="active" {%- endif -%}>
<a href="{{ first(menu.items).path }}">{{ menuTitle }}</a>
<ul class="child">
<menu class="child">
{% for item in menu.items %}
<li {%- if item.active %} class="active" {%- endif -%}><a href="{{ item.path }}">{{ item.title }}</a></li>
{% endfor %}
</ul>
</menu>
</li>

View File

@ -1,8 +0,0 @@
{%- import '../utils.twig' as utils -%}
{%- if typeParameters is not empty -%}
&lt;
{%- for typeParameter in typeParameters %}
{{- typeParameter.baseTypeName -}}{%- if not (loop.last) %}, {% endif %}
{%- endfor -%}
&gt;
{%- endif -%}

View File

@ -19,7 +19,7 @@
{
"result": <span class="text-digit">null</span>
"error_code": <span class="text-digit">{{ outOfDateError.value }}</span>,
"error_message": <span class="text-digit">"{{ outOfDateError.description | escape }}"</span>
"error_message": <span class="text-digit">"{{ outOfDateError.description }}"</span>
}
</div>
</div>

View File

@ -25,48 +25,37 @@ body {
display: flex;
}
.btn {
padding: 1rem 1.15rem;
border: 0;
background-color: #0ca9e6;
color: white;
font-size: 1.42rem;
line-height: 1;
font-weight: 500;
.gutter {
cursor: col-resize;
background-image: url("../images/vertical-split.png");
background-color: transparent;
background-repeat: no-repeat;
background-position: 50% 200px;
}
.gutter {
z-index: 10;
cursor: col-resize;
.gutter:hover {
background-color: #333c47;
}
.aside {
display: inline-block;
vertical-align: top;
font-size: 14px;
position: relative;
}
.aside__container {
position: fixed;
overflow-y: auto;
max-height: 100vh;
width: inherit;
min-width: inherit;
}
.header {
min-height: 7rem;
height: 7rem;
font-size: 14px;
}
.content {
min-height: calc(100vh - 7rem);
font-size: 14px;
line-height: 1rem;
}
.aside-left {
min-width: 315px;
min-width: 300px;
}
.aside-left .header {
@ -75,10 +64,6 @@ body {
border-bottom: 1px solid #2b333e;
}
.aside-right .content {
min-height: calc(100vh - 7rem);
}
.logo img {
height: 3.6em;
margin: .7em 0 0 2em;
@ -171,30 +156,19 @@ body {
background-color: #222933;
}
.navigation a {
menu li {
cursor: pointer;
color: inherit;
text-decoration: none;
width: 100%;
}
.navigation .btn {
vertical-align: middle;
color: #fff;
width: auto;
}
.aside-left ul.navigation {
.aside-left menu.main {
list-style: none;
margin: 0;
background: #2b333e;
padding: 0 0 2.2rem;
}
.aside-left ul.navigation li {
display: flex;
align-items: center;
justify-content: space-between;
.aside-left menu.main li a {
display: block;
line-height: 4rem;
vertical-align: middle;
padding-left: 3.57rem;
@ -208,31 +182,27 @@ body {
white-space: nowrap;
}
.aside-left ul.navigation > li:hover,
.aside-left ul.navigation > li.active {
.aside-left menu.main > li a:hover,
.aside-left menu.main > li.active a {
background-color: #222933;
padding-left: 3.14rem;
border-left: 0.43rem solid #0ca9e6;
color: white;
color: white
}
.aside-left ul.navigation > li:first-child + li.active {
.aside-left menu.main > li:first-child + li.active {
margin-top: 0;
}
.aside-left ul.secondary {
.aside-left menu.secondary {
list-style: none;
margin: 0;
padding: 3.57rem 0 3.57rem 3.57rem;
padding: 3.57rem 0 3.57rem 6.28rem;
}
.aside-left ul.secondary a {
text-decoration: none;
color: inherit;
}
.aside-left ul.secondary li {
.aside-left menu.secondary li a {
line-height: 2.64rem;
vertical-align: middle;
font-size: 1.42rem;
color: #0ca9e6;
text-decoration: none;
@ -241,42 +211,37 @@ body {
text-overflow: ellipsis;
white-space: nowrap;
padding-right: 1.42rem;
display: inline-block;
width: 100%;
}
.aside-left ul.secondary > li:not(.active):hover {
.aside-left menu.secondary > li:not(.active) > a:hover {
opacity: 0.8;
}
.aside-left ul.secondary > li.active {
.aside-left menu.secondary > li.active > a {
color: white
}
.aside-left ul.secondary > li.active ul.child {
.aside-left menu.secondary > li.active menu.child {
display: block;
}
.aside-left ul.child {
.aside-left menu.child {
display: none;
list-style: none;
margin: 6px 0;
padding: 0 0 0 1.5rem;
padding: 0 3.75rem 0 1.57rem;
border-left: 1px solid #fff;
min-width: 205px;
width: auto;
}
.aside-left ul.child > a {
text-decoration: none;
color: inherit;
}
.aside-left ul.child > li {
.aside-left menu.child > li > a {
color: #7a7f85;
padding-right: 0
}
.aside-left ul.child > li.active {
.aside-left menu.child > li.active > a {
color: #fff;
}
@ -295,21 +260,12 @@ body {
.title {
font-size: 2rem;
line-height: 2.4rem;
padding: 2.2rem 1.42rem 1.42rem 3.57rem;
padding-top: 2.2rem;
color: white;
padding-left: 4rem;
font-weight: 700;
}
.title__hint {
font-size: 1.42rem;
font-weight: 400;
color: #7a7f85;
}
.title__hint:not(:first-child) {
margin-left: 10px;
}
.aside-right .content {
padding: 1rem;
}
@ -406,11 +362,6 @@ body {
line-height: 2rem;
}
.table .btn {
width: 100%;
margin-top: 1.71rem;
}
.row-header {
display: table-row;
}
@ -624,6 +575,17 @@ body {
background-color: #f4f6f9;
}
.btn {
background-color: #0ca9e6;
border: 0;
color: white;
font-size: 1.42rem;
padding: 1.15rem;
width: 100%;
margin-top: 1.71rem;
font-weight: 500;
}
.part-example-response > .text-response {
display: inline-block;
width: calc(100% - 16rem);
@ -641,7 +603,7 @@ span.text-string {
}
a.show-example-response {
color: #0ca9e6;
color: #0275eb;
cursor: pointer;
}
@ -753,7 +715,6 @@ ol {
.main-page {
display: block;
min-width: 0;
background-color: #ffffff;
}

View File

@ -1,44 +1,42 @@
{%- include 'blocks/head.html.twig' with { title: pageTitle, cssFolderPath: cssFolderPath } %}
<body class="main-page">
<div class="aside aside-left">
<div class="aside__container">
<div class="header">
{%- include 'blocks/menu-header.html.twig' %}
</div>
<div class="content">
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
</div>
</div>
</div>
<div class="aside aside-right">
{%- include 'blocks/header.html.twig' with {
imagesFolderPath: imagesFolderPath,
methodsPath: methodsPath,
relativeToRootPath: relativeToRootPath
} %}
<div class="content">
<div class="page-data">
<div class="table">
<div class="part-table">
<div class="row-header">
<div>Код ошибки</div>
<div>Текстовое описание ошибки</div>
</div>
{% for errorValue in errorType.values %}
<div class="row-body">
<div>{{ errorValue.value }}</div>
<div>{{ errorValue.description | escape }}</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{%- include 'blocks/scripts.html.twig' with { jsFolderPath: jsFolderPath } %}
</body>
{%- include 'blocks/head.html.twig' with { title: pageTitle, cssFolderPath: cssFolderPath } %}
<body class="main-page">
<div class="aside aside-left">
<div class="header">
<div class="title">{{ pageTitle }}</div>
</div>
<div class="content">
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
</div>
</div>
<div class="aside aside-right">
{%- include 'blocks/header.html.twig' with {
imagesFolderPath: imagesFolderPath,
methodsPath: methodsPath,
relativeToRootPath: relativeToRootPath
} %}
<div class="content">
<div class="page-data">
<div class="table">
<div class="part-table">
<div class="row-header">
<div>Код ошибки</div>
<div>Текстовое описание ошибки</div>
</div>
{% for errorValue in errorType.values %}
<div class="row-body">
<div>{{ errorValue.value }}</div>
<div>{{ errorValue.description }}</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{%- include 'blocks/scripts.html.twig' with { jsFolderPath: jsFolderPath } %}
</body>
</html>

View File

@ -2,13 +2,11 @@
<body class="main-page">
<div class="aside aside-left">
<div class="aside__container">
<div class="header">
{%- include 'blocks/menu-header.html.twig' %}
</div>
<div class="content">
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
</div>
<div class="header">
<div class="title">{{ pageTitle }}</div>
</div>
<div class="content">
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
</div>
</div>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -2,23 +2,22 @@
<body class="main-page">
<div class="aside aside-left">
<div class="aside__container">
<div class="header">
{%- include 'blocks/menu-header.html.twig' %}
</div>
<div class="content">
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
<div class="header">
<div class="title">{{ pageTitle }}</div>
</div>
<div class="content">
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
<menu class="secondary">
{% for menu in menus %}
{% include 'blocks/secondary-menu.html.twig' with {
menu: menu,
menuTitle: menu.title,
activeItemTypeName: name
} %}
{% endfor %}
</menu>
<ul class="secondary">
{% for menu in menus %}
{% include 'blocks/secondary-menu.html.twig' with {
menu: menu,
menuTitle: menu.title,
activeItemTypeName: name
} %}
{% endfor %}
</ul>
</div>
</div>
</div>

View File

@ -2,19 +2,18 @@
<body class="main-page">
<div class="aside aside-left">
<div class="aside__container">
<div class="header">
{%- include 'blocks/menu-header.html.twig' %}
</div>
<div class="content">
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
<div class="header">
<div class="title">{{ pageTitle }}</div>
</div>
<div class="content">
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
<menu class="secondary">
<li><a>Android</a></li>
<li class="active"><a>iOS</a></li>
<li><a>Windows Phone</a></li>
</menu>
<ul class="secondary">
<li><a>Android</a></li>
<li class="active"><a>iOS</a></li>
<li><a>Windows Phone</a></li>
</ul>
</div>
</div>
</div>

View File

@ -2,25 +2,24 @@
<body class="main-page">
<div class="aside aside-left">
<div class="aside__container">
<div class="header">
{%- include 'blocks/menu-header.html.twig' %}
</div>
<div class="content">
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
<div class="header">
<div class="title">{{ pageTitle }}</div>
</div>
<div class="content">
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
<menu class="secondary">
{% include 'blocks/secondary-menu.html.twig' with {
menu: enumsMenu,
menuTitle: "Перечисления",
activeItemTypeName: name
} %}
{% include 'blocks/secondary-menu.html.twig' with {
menu: classesMenu,
menuTitle: "Объекты"
} %}
</menu>
<ul class="secondary">
{% include 'blocks/secondary-menu.html.twig' with {
menu: enumsMenu,
menuTitle: "Перечисления",
activeItemTypeName: name
} %}
{% include 'blocks/secondary-menu.html.twig' with {
menu: classesMenu,
menuTitle: "Объекты"
} %}
</ul>
</div>
</div>
</div>

View File

@ -2,25 +2,24 @@
<body class="main-page">
<div class="aside aside-left">
<div class="aside__container">
<div class="header">
{%- include 'blocks/menu-header.html.twig' %}
</div>
<div class="content">
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
<div class="header">
<div class="title">{{ pageTitle }}</div>
</div>
<div class="content">
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
<menu class="secondary">
{% include 'blocks/secondary-menu.html.twig' with {
menu: enumsMenu,
menuTitle: "Перечисления",
activeItemTypeName: name
} %}
{% include 'blocks/secondary-menu.html.twig' with {
menu: classesMenu,
menuTitle: "Объекты"
} %}
</menu>
<ul class="secondary">
{% include 'blocks/secondary-menu.html.twig' with {
menu: enumsMenu,
menuTitle: "Перечисления",
activeItemTypeName: name
} %}
{% include 'blocks/secondary-menu.html.twig' with {
menu: classesMenu,
menuTitle: "Объекты"
} %}
</ul>
</div>
</div>
</div>

View File

@ -2,13 +2,11 @@
<body class="main-page">
<div class="aside aside-left">
<div class="aside__container">
<div class="header">
{%- include 'blocks/menu-header.html.twig' %}
</div>
<div class="content">
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
</div>
<div class="header">
<div class="title">{{ pageTitle }}</div>
</div>
<div class="content">
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
</div>
</div>

View File

@ -2,10 +2,6 @@
{{- expr -}}{%- if nullable -%}?{%- endif -%}
{% endmacro %}
{% macro formatNullableClassType(valueType, nullable) %}
{% include 'blocks/classtype.twig' with { type: valueType } %}{%- if nullable -%}?{%- endif -%}
{% endmacro %}
{% macro optionalDescription(optional) %}
{%- if optional -%}Нет{%- else -%}Да{%- endif -%}
{% endmacro %}

View File

@ -2,13 +2,11 @@
<body class="main-page">
<div class="aside aside-left">
<div class="aside__container">
<div class="header">
{%- include 'blocks/menu-header.html.twig' %}
</div>
<div class="content">
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
</div>
<div class="header">
<div class="title">{{ pageTitle }}</div>
</div>
<div class="content">
{%- include 'blocks/main-menu.html.twig' with { mainMenu: mainMenu } %}
</div>
</div>