diff --git a/.mapping.json b/.mapping.json index 57a5c6d81..3f7479c05 100644 --- a/.mapping.json +++ b/.mapping.json @@ -16419,6 +16419,7 @@ "client/ios/DivKit/Templates/TemplateError.swift":"divkit/public/client/ios/DivKit/Templates/TemplateError.swift", "client/ios/DivKit/Templates/TemplateToType.swift":"divkit/public/client/ios/DivKit/Templates/TemplateToType.swift", "client/ios/DivKit/Templates/TemplateValue.swift":"divkit/public/client/ios/DivKit/Templates/TemplateValue.swift", + "client/ios/DivKit/Templates/UntypedDivTemplateResolver.swift":"divkit/public/client/ios/DivKit/Templates/UntypedDivTemplateResolver.swift", "client/ios/DivKit/Timers/DivTimerAction.swift":"divkit/public/client/ios/DivKit/Timers/DivTimerAction.swift", "client/ios/DivKit/Timers/DivTimerController.swift":"divkit/public/client/ios/DivKit/Timers/DivTimerController.swift", "client/ios/DivKit/Timers/DivTimerStorage.swift":"divkit/public/client/ios/DivKit/Timers/DivTimerStorage.swift", @@ -16982,6 +16983,7 @@ "client/ios/DivKitTests/Actions/ScrollActionHandlerTests.swift":"divkit/public/client/ios/DivKitTests/Actions/ScrollActionHandlerTests.swift", "client/ios/DivKitTests/Actions/SetStoredValueActionHandlerTests.swift":"divkit/public/client/ios/DivKitTests/Actions/SetStoredValueActionHandlerTests.swift", "client/ios/DivKitTests/Actions/SubmitActionHandlerTests.swift":"divkit/public/client/ios/DivKitTests/Actions/SubmitActionHandlerTests.swift", + "client/ios/DivKitTests/DictionarySerializationBehaviorTests.swift":"divkit/public/client/ios/DivKitTests/DictionarySerializationBehaviorTests.swift", "client/ios/DivKitTests/DivBlockModelingContextTests.swift":"divkit/public/client/ios/DivKitTests/DivBlockModelingContextTests.swift", "client/ios/DivKitTests/DivBlockStateStorageTests.swift":"divkit/public/client/ios/DivKitTests/DivBlockStateStorageTests.swift", "client/ios/DivKitTests/DivDataParsingTests.swift":"divkit/public/client/ios/DivKitTests/DivDataParsingTests.swift", diff --git a/api_generator/api_generator/generators/swift/generator.py b/api_generator/api_generator/generators/swift/generator.py index 87775c484..b6a216d3d 100644 --- a/api_generator/api_generator/generators/swift/generator.py +++ b/api_generator/api_generator/generators/swift/generator.py @@ -150,8 +150,11 @@ class SwiftGenerator(Generator): def __entity_enumeration_extensions_declaration(self, entity_enumeration: EntityEnumeration) -> List[str]: access_modifier = self._access_level.value args_decl = swift_template_deserializable_args_decl(entity_enumeration.mode) + context_arg = '' if entity_enumeration.mode.is_template else ', context: ParsingContext' deserializable_extension = Text(f'extension {entity_enumeration.prefixed_declaration} {{') - deserializable_extension += f' {access_modifier}init(dictionary: [String: Any]{args_decl}) throws {{' + deserializable_extension += ( + f' {access_modifier}init(dictionary: [String: Any]{args_decl}{context_arg}) throws {{' + ) body = Text() if entity_enumeration.mode.is_template: body += 'let receivedType = try dictionary.getField("type") as String' @@ -164,8 +167,9 @@ class SwiftGenerator(Generator): obj_t = entity[1].prefixed_declaration if entity[1] is not None else utils.capitalize_camel_case(entity[0]) low_name = utils.lower_camel_case(name) args = swift_template_deserializable_args(entity_enumeration.mode) + context_param = '' if entity_enumeration.mode.is_template else ', context: context' body += f'case {obj_t}.type:' - body += f' self = .{low_name}(try {obj_t}(dictionary: dictionary{args}))' + body += f' self = .{low_name}(try {obj_t}(dictionary: dictionary{args}{context_param}))' body += 'default:' args = f'field: "{entity_enumeration.name}", representation: dictionary' body += f' throw DeserializationError.invalidFieldRepresentation({args})' @@ -194,7 +198,10 @@ class SwiftGenerator(Generator): equatable_extension = str(equatable_extension) if self.generate_serialization: - if entity_enumeration.mode is GenerationMode.NORMAL_WITHOUT_TEMPLATES: + if entity_enumeration.mode in [ + GenerationMode.NORMAL_WITHOUT_TEMPLATES, + GenerationMode.NORMAL_WITH_TEMPLATES, + ]: result = [deserializable_extension, equatable_extension] elif entity_enumeration.mode.is_template: result = [deserializable_extension] @@ -252,8 +259,12 @@ class SwiftGenerator(Generator): result += validator_decl.indented() result += EMPTY - if self.generate_serialization and (entity.generation_mode is GenerationMode.NORMAL_WITHOUT_TEMPLATES or - entity.generation_mode.is_template): + if self.generate_serialization and ( + entity.generation_mode in [ + GenerationMode.NORMAL_WITHOUT_TEMPLATES, + GenerationMode.NORMAL_WITH_TEMPLATES, + ] or entity.generation_mode.is_template + ): result += entity.deserializing_constructor_declaration.indented() result += EMPTY diff --git a/api_generator/api_generator/generators/swift/swift_entities.py b/api_generator/api_generator/generators/swift/swift_entities.py index fcfe9ebdb..4caab2a85 100644 --- a/api_generator/api_generator/generators/swift/swift_entities.py +++ b/api_generator/api_generator/generators/swift/swift_entities.py @@ -122,16 +122,21 @@ class SwiftEntity(Entity): def deserializing_constructor_declaration(self) -> Text: props = self.instance_properties_swift args_decl = swift_template_deserializable_args_decl(self.generation_mode) + context_arg = '' if self.generation_mode.is_template else ', context: ParsingContext' if not props: - return Text(f'public init(dictionary: [String: Any]{args_decl}) throws {{}}') - result = Text(f'public convenience init(dictionary: [String: Any]{args_decl}) throws {{') + return Text(f'public init(dictionary: [String: Any]{args_decl}{context_arg}) throws {{}}') + result = Text(f'public convenience init(dictionary: [String: Any]{args_decl}{context_arg}) throws {{') lines = Text('self.init(') for prop in props: tail = '' if prop == props[-1] else ',' if prop.name == PARENT_PROPERTY.name: lines += f' {prop.declaration_name}: dictionary["type"] as? String{tail}' else: - lines += f' {prop.declaration_name}: dictionary.{prop.deserialization_expression}{tail}' + throw_prefix = '' if self.generation_mode.is_template else 'try ' + lines += ( + f' {prop.declaration_name}: ' + f'{throw_prefix}dictionary.{prop.deserialization_expression_for_mode(self.generation_mode)}{tail}' + ) lines += ')' result += lines.indented() result += '}' @@ -587,19 +592,54 @@ class SwiftProperty(Property): @property def deserialization_expression(self) -> str: + return self.deserialization_expression_for_mode(self.mode) + + def deserialization_expression_for_mode(self, mode: GenerationMode) -> str: + is_normal_mode = mode in [ + GenerationMode.NORMAL_WITH_TEMPLATES, + GenerationMode.NORMAL_WITHOUT_TEMPLATES, + ] + if is_normal_mode and self.property_type.can_be_templated: + validator_arg_string = self.validator_arg(entity_name='Self', mode=mode) + declaration_mode = SwiftProperty.SwiftMode(value=mode, use_expressions=False) + + if isinstance(self.property_type, Array): + item_type = cast(SwiftPropertyType, self.property_type.property_type).prefixed_declaration( + declaration_mode + ) + optional_suffix = 'Optional' if self.parsed_value_is_optional else '' + expr = ( + f'"{self.dict_field}", transform: ' + f'{{ (dict: [String: Any]) in try? {item_type}(dictionary: dict, context: context) }}' + f'{validator_arg_string}' + ) + return f'get{optional_suffix}Array({expr})' + + value_type = cast(SwiftPropertyType, self.property_type).prefixed_declaration( + declaration_mode + ) + optional_suffix = 'Optional' if self.parsed_value_is_optional else '' + expr = ( + f'"{self.dict_field}", transform: ' + f'{{ (dict: [String: Any]) in try {value_type}(dictionary: dict, context: context) }}' + f'{validator_arg_string}' + ) + return f'get{optional_suffix}Field({expr})' + if isinstance(self.property_type, Array): type_suffix = 'Array' else: type_suffix = 'Field' if self.property_type.can_be_templated: - template_to_type_arg = swift_template_deserializable_args(self.mode) + template_to_type_arg = swift_template_deserializable_args(mode) else: template_to_type_arg = '' - optional_suffix = 'Optional' if self.parsed_value_is_optional or self.mode.is_template else '' + optional_suffix = 'Optional' if self.parsed_value_is_optional or mode.is_template else '' expression_suffix = 'Expression' if self.supports_expressions else '' - validator_arg_string = self.validator_arg(entity_name='Self', mode=self.mode) + validator_arg_string = self.validator_arg(entity_name='Self', mode=mode) transformed = cast(SwiftPropertyType, self.property_type).transform_arg - expr = f'"{self.dict_field}"{template_to_type_arg}{transformed}{validator_arg_string}' + context_arg = ', context: context' if is_normal_mode else '' + expr = f'"{self.dict_field}"{template_to_type_arg}{transformed}{validator_arg_string}{context_arg}' return f'get{optional_suffix}{expression_suffix}{type_suffix}({expr})' def add_default_value_to(self, declaration: str, public_default_value: bool = False) -> str: diff --git a/api_generator/tests/references/not_templates_swift/Entity.swift b/api_generator/tests/references/not_templates_swift/Entity.swift index 06a1cf3bf..41c161223 100644 --- a/api_generator/tests/references/not_templates_swift/Entity.swift +++ b/api_generator/tests/references/not_templates_swift/Entity.swift @@ -71,47 +71,47 @@ public enum Entity: Sendable { } extension Entity { - public init(dictionary: [String: Any]) throws { + public init(dictionary: [String: Any], context: ParsingContext) throws { let blockType = try dictionary.getField("type") as String switch blockType { case EntityWithArray.type: - self = .entityWithArray(try EntityWithArray(dictionary: dictionary)) + self = .entityWithArray(try EntityWithArray(dictionary: dictionary, context: context)) case EntityWithArrayOfEnums.type: - self = .entityWithArrayOfEnums(try EntityWithArrayOfEnums(dictionary: dictionary)) + self = .entityWithArrayOfEnums(try EntityWithArrayOfEnums(dictionary: dictionary, context: context)) case EntityWithArrayOfExpressions.type: - self = .entityWithArrayOfExpressions(try EntityWithArrayOfExpressions(dictionary: dictionary)) + self = .entityWithArrayOfExpressions(try EntityWithArrayOfExpressions(dictionary: dictionary, context: context)) case EntityWithArrayOfNestedItems.type: - self = .entityWithArrayOfNestedItems(try EntityWithArrayOfNestedItems(dictionary: dictionary)) + self = .entityWithArrayOfNestedItems(try EntityWithArrayOfNestedItems(dictionary: dictionary, context: context)) case EntityWithArrayWithTransform.type: - self = .entityWithArrayWithTransform(try EntityWithArrayWithTransform(dictionary: dictionary)) + self = .entityWithArrayWithTransform(try EntityWithArrayWithTransform(dictionary: dictionary, context: context)) case EntityWithComplexProperty.type: - self = .entityWithComplexProperty(try EntityWithComplexProperty(dictionary: dictionary)) + self = .entityWithComplexProperty(try EntityWithComplexProperty(dictionary: dictionary, context: context)) case EntityWithComplexPropertyWithDefaultValue.type: - self = .entityWithComplexPropertyWithDefaultValue(try EntityWithComplexPropertyWithDefaultValue(dictionary: dictionary)) + self = .entityWithComplexPropertyWithDefaultValue(try EntityWithComplexPropertyWithDefaultValue(dictionary: dictionary, context: context)) case EntityWithEntityProperty.type: - self = .entityWithEntityProperty(try EntityWithEntityProperty(dictionary: dictionary)) + self = .entityWithEntityProperty(try EntityWithEntityProperty(dictionary: dictionary, context: context)) case EntityWithOptionalComplexProperty.type: - self = .entityWithOptionalComplexProperty(try EntityWithOptionalComplexProperty(dictionary: dictionary)) + self = .entityWithOptionalComplexProperty(try EntityWithOptionalComplexProperty(dictionary: dictionary, context: context)) case EntityWithOptionalProperty.type: - self = .entityWithOptionalProperty(try EntityWithOptionalProperty(dictionary: dictionary)) + self = .entityWithOptionalProperty(try EntityWithOptionalProperty(dictionary: dictionary, context: context)) case EntityWithOptionalStringEnumProperty.type: - self = .entityWithOptionalStringEnumProperty(try EntityWithOptionalStringEnumProperty(dictionary: dictionary)) + self = .entityWithOptionalStringEnumProperty(try EntityWithOptionalStringEnumProperty(dictionary: dictionary, context: context)) case EntityWithPropertyWithDefaultValue.type: - self = .entityWithPropertyWithDefaultValue(try EntityWithPropertyWithDefaultValue(dictionary: dictionary)) + self = .entityWithPropertyWithDefaultValue(try EntityWithPropertyWithDefaultValue(dictionary: dictionary, context: context)) case EntityWithRawArray.type: - self = .entityWithRawArray(try EntityWithRawArray(dictionary: dictionary)) + self = .entityWithRawArray(try EntityWithRawArray(dictionary: dictionary, context: context)) case EntityWithRequiredProperty.type: - self = .entityWithRequiredProperty(try EntityWithRequiredProperty(dictionary: dictionary)) + self = .entityWithRequiredProperty(try EntityWithRequiredProperty(dictionary: dictionary, context: context)) case EntityWithSimpleProperties.type: - self = .entityWithSimpleProperties(try EntityWithSimpleProperties(dictionary: dictionary)) + self = .entityWithSimpleProperties(try EntityWithSimpleProperties(dictionary: dictionary, context: context)) case EntityWithStringArrayProperty.type: - self = .entityWithStringArrayProperty(try EntityWithStringArrayProperty(dictionary: dictionary)) + self = .entityWithStringArrayProperty(try EntityWithStringArrayProperty(dictionary: dictionary, context: context)) case EntityWithStringEnumProperty.type: - self = .entityWithStringEnumProperty(try EntityWithStringEnumProperty(dictionary: dictionary)) + self = .entityWithStringEnumProperty(try EntityWithStringEnumProperty(dictionary: dictionary, context: context)) case EntityWithStringEnumPropertyWithDefaultValue.type: - self = .entityWithStringEnumPropertyWithDefaultValue(try EntityWithStringEnumPropertyWithDefaultValue(dictionary: dictionary)) + self = .entityWithStringEnumPropertyWithDefaultValue(try EntityWithStringEnumPropertyWithDefaultValue(dictionary: dictionary, context: context)) case EntityWithoutProperties.type: - self = .entityWithoutProperties(try EntityWithoutProperties(dictionary: dictionary)) + self = .entityWithoutProperties(try EntityWithoutProperties(dictionary: dictionary, context: context)) default: throw DeserializationError.invalidFieldRepresentation(field: "entity", representation: dictionary) } diff --git a/api_generator/tests/references/not_templates_swift/EntityWithArray.swift b/api_generator/tests/references/not_templates_swift/EntityWithArray.swift index 41126260a..0d5376df9 100644 --- a/api_generator/tests/references/not_templates_swift/EntityWithArray.swift +++ b/api_generator/tests/references/not_templates_swift/EntityWithArray.swift @@ -11,6 +11,12 @@ public final class EntityWithArray: Sendable { static let arrayValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + array: try dictionary.getArray("array", transform: { (dict: [String: Any]) in try? Entity(dictionary: dict, context: context) }, validator: Self.arrayValidator) + ) + } + init( array: [Entity] ) { diff --git a/api_generator/tests/references/not_templates_swift/EntityWithArrayOfEnums.swift b/api_generator/tests/references/not_templates_swift/EntityWithArrayOfEnums.swift index 9acf6b6a7..2e91185ee 100644 --- a/api_generator/tests/references/not_templates_swift/EntityWithArrayOfEnums.swift +++ b/api_generator/tests/references/not_templates_swift/EntityWithArrayOfEnums.swift @@ -17,6 +17,12 @@ public final class EntityWithArrayOfEnums: Sendable { static let itemsValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + items: try dictionary.getArray("items", validator: Self.itemsValidator, context: context) + ) + } + init( items: [Item] ) { diff --git a/api_generator/tests/references/not_templates_swift/EntityWithArrayOfExpressions.swift b/api_generator/tests/references/not_templates_swift/EntityWithArrayOfExpressions.swift index a88f7ba8e..f903cbef2 100644 --- a/api_generator/tests/references/not_templates_swift/EntityWithArrayOfExpressions.swift +++ b/api_generator/tests/references/not_templates_swift/EntityWithArrayOfExpressions.swift @@ -15,6 +15,12 @@ public final class EntityWithArrayOfExpressions: Sendable { static let itemsValidator: AnyArrayValueValidator> = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + items: try dictionary.getExpressionArray("items", validator: Self.itemsValidator, context: context) + ) + } + init( items: [Expression] ) { diff --git a/api_generator/tests/references/not_templates_swift/EntityWithArrayOfNestedItems.swift b/api_generator/tests/references/not_templates_swift/EntityWithArrayOfNestedItems.swift index 265f2fdf1..2edd1e5fc 100644 --- a/api_generator/tests/references/not_templates_swift/EntityWithArrayOfNestedItems.swift +++ b/api_generator/tests/references/not_templates_swift/EntityWithArrayOfNestedItems.swift @@ -13,6 +13,13 @@ public final class EntityWithArrayOfNestedItems: Sendable { resolver.resolveString(property) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + entity: try dictionary.getField("entity", transform: { (dict: [String: Any]) in try Entity(dictionary: dict, context: context) }), + property: try dictionary.getExpressionField("property", context: context) + ) + } + init( entity: Entity, property: Expression @@ -28,6 +35,12 @@ public final class EntityWithArrayOfNestedItems: Sendable { static let itemsValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + items: try dictionary.getArray("items", transform: { (dict: [String: Any]) in try? EntityWithArrayOfNestedItems.Item(dictionary: dict, context: context) }, validator: Self.itemsValidator) + ) + } + init( items: [Item] ) { diff --git a/api_generator/tests/references/not_templates_swift/EntityWithArrayWithTransform.swift b/api_generator/tests/references/not_templates_swift/EntityWithArrayWithTransform.swift index 463e958bb..a79a22e8c 100644 --- a/api_generator/tests/references/not_templates_swift/EntityWithArrayWithTransform.swift +++ b/api_generator/tests/references/not_templates_swift/EntityWithArrayWithTransform.swift @@ -15,6 +15,12 @@ public final class EntityWithArrayWithTransform: Sendable { static let arrayValidator: AnyArrayValueValidator> = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + array: try dictionary.getExpressionArray("array", transform: Color.color(withHexString:), validator: Self.arrayValidator, context: context) + ) + } + init( array: [Expression] ) { diff --git a/api_generator/tests/references/not_templates_swift/EntityWithComplexProperty.swift b/api_generator/tests/references/not_templates_swift/EntityWithComplexProperty.swift index 0425c48c3..d7e0b31da 100644 --- a/api_generator/tests/references/not_templates_swift/EntityWithComplexProperty.swift +++ b/api_generator/tests/references/not_templates_swift/EntityWithComplexProperty.swift @@ -12,6 +12,12 @@ public final class EntityWithComplexProperty: Sendable { resolver.resolveUrl(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", transform: URL.makeFromNonEncodedString, context: context) + ) + } + init( value: Expression ) { @@ -22,6 +28,12 @@ public final class EntityWithComplexProperty: Sendable { public static let type: String = "entity_with_complex_property" public let property: Property + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getField("property", transform: { (dict: [String: Any]) in try EntityWithComplexProperty.Property(dictionary: dict, context: context) }) + ) + } + init( property: Property ) { diff --git a/api_generator/tests/references/not_templates_swift/EntityWithComplexPropertyWithDefaultValue.swift b/api_generator/tests/references/not_templates_swift/EntityWithComplexPropertyWithDefaultValue.swift index 9c2f09b50..5604612c1 100644 --- a/api_generator/tests/references/not_templates_swift/EntityWithComplexPropertyWithDefaultValue.swift +++ b/api_generator/tests/references/not_templates_swift/EntityWithComplexPropertyWithDefaultValue.swift @@ -12,6 +12,12 @@ public final class EntityWithComplexPropertyWithDefaultValue: Sendable { resolver.resolveString(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( value: Expression ) { @@ -22,6 +28,12 @@ public final class EntityWithComplexPropertyWithDefaultValue: Sendable { public static let type: String = "entity_with_complex_property_with_default_value" public let property: Property // default value: EntityWithComplexPropertyWithDefaultValue.Property(value: .value("Default text")) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getOptionalField("property", transform: { (dict: [String: Any]) in try EntityWithComplexPropertyWithDefaultValue.Property(dictionary: dict, context: context) }) + ) + } + init( property: Property? = nil ) { diff --git a/api_generator/tests/references/not_templates_swift/EntityWithEntityProperty.swift b/api_generator/tests/references/not_templates_swift/EntityWithEntityProperty.swift index fb15cf0bf..2e313f576 100644 --- a/api_generator/tests/references/not_templates_swift/EntityWithEntityProperty.swift +++ b/api_generator/tests/references/not_templates_swift/EntityWithEntityProperty.swift @@ -8,6 +8,12 @@ public final class EntityWithEntityProperty: Sendable { public static let type: String = "entity_with_entity_property" public let entity: Entity // default value: .entityWithStringEnumProperty(EntityWithStringEnumProperty(property: .value(.second))) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + entity: try dictionary.getOptionalField("entity", transform: { (dict: [String: Any]) in try Entity(dictionary: dict, context: context) }) + ) + } + init( entity: Entity? = nil ) { diff --git a/api_generator/tests/references/not_templates_swift/EntityWithJsonProperty.swift b/api_generator/tests/references/not_templates_swift/EntityWithJsonProperty.swift index f2e7d0c84..baf97523d 100644 --- a/api_generator/tests/references/not_templates_swift/EntityWithJsonProperty.swift +++ b/api_generator/tests/references/not_templates_swift/EntityWithJsonProperty.swift @@ -8,6 +8,12 @@ public final class EntityWithJsonProperty: @unchecked Sendable { public static let type: String = "entity_with_json_property" public let jsonProperty: [String: Any] // default value: { "key": "value", "items": [ "value" ] } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + jsonProperty: try dictionary.getOptionalField("json_property", context: context) + ) + } + init( jsonProperty: [String: Any]? = nil ) { diff --git a/api_generator/tests/references/not_templates_swift/EntityWithOptionalComplexProperty.swift b/api_generator/tests/references/not_templates_swift/EntityWithOptionalComplexProperty.swift index 5c87b30cb..1326e71ba 100644 --- a/api_generator/tests/references/not_templates_swift/EntityWithOptionalComplexProperty.swift +++ b/api_generator/tests/references/not_templates_swift/EntityWithOptionalComplexProperty.swift @@ -12,6 +12,12 @@ public final class EntityWithOptionalComplexProperty: Sendable { resolver.resolveUrl(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", transform: URL.makeFromNonEncodedString, context: context) + ) + } + init( value: Expression ) { @@ -22,6 +28,12 @@ public final class EntityWithOptionalComplexProperty: Sendable { public static let type: String = "entity_with_optional_complex_property" public let property: Property? + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getOptionalField("property", transform: { (dict: [String: Any]) in try EntityWithOptionalComplexProperty.Property(dictionary: dict, context: context) }) + ) + } + init( property: Property? = nil ) { diff --git a/api_generator/tests/references/not_templates_swift/EntityWithOptionalProperty.swift b/api_generator/tests/references/not_templates_swift/EntityWithOptionalProperty.swift index 1ddc12970..c6535a88a 100644 --- a/api_generator/tests/references/not_templates_swift/EntityWithOptionalProperty.swift +++ b/api_generator/tests/references/not_templates_swift/EntityWithOptionalProperty.swift @@ -12,6 +12,12 @@ public final class EntityWithOptionalProperty: Sendable { resolver.resolveString(property) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getOptionalExpressionField("property", context: context) + ) + } + init( property: Expression? = nil ) { diff --git a/api_generator/tests/references/not_templates_swift/EntityWithOptionalStringEnumProperty.swift b/api_generator/tests/references/not_templates_swift/EntityWithOptionalStringEnumProperty.swift index 38b52723f..e0952eeb5 100644 --- a/api_generator/tests/references/not_templates_swift/EntityWithOptionalStringEnumProperty.swift +++ b/api_generator/tests/references/not_templates_swift/EntityWithOptionalStringEnumProperty.swift @@ -18,6 +18,12 @@ public final class EntityWithOptionalStringEnumProperty: Sendable { resolver.resolveEnum(property) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getOptionalExpressionField("property", context: context) + ) + } + init( property: Expression? = nil ) { diff --git a/api_generator/tests/references/not_templates_swift/EntityWithPropertyWithDefaultValue.swift b/api_generator/tests/references/not_templates_swift/EntityWithPropertyWithDefaultValue.swift index fa5bdc94b..a025f47a8 100644 --- a/api_generator/tests/references/not_templates_swift/EntityWithPropertyWithDefaultValue.swift +++ b/api_generator/tests/references/not_templates_swift/EntityWithPropertyWithDefaultValue.swift @@ -28,6 +28,14 @@ public final class EntityWithPropertyWithDefaultValue: Sendable { static let urlValidator: AnyValueValidator = makeURLValidator(schemes: ["https"]) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + int: try dictionary.getOptionalExpressionField("int", validator: Self.intValidator, context: context), + nonOptional: try dictionary.getExpressionField("non_optional", context: context), + url: try dictionary.getOptionalExpressionField("url", transform: URL.makeFromNonEncodedString, validator: Self.urlValidator, context: context) + ) + } + init( int: Expression? = nil, nonOptional: Expression, @@ -58,6 +66,14 @@ public final class EntityWithPropertyWithDefaultValue: Sendable { static let urlValidator: AnyValueValidator = makeURLValidator(schemes: ["https"]) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + int: try dictionary.getOptionalExpressionField("int", validator: Self.intValidator, context: context), + nested: try dictionary.getOptionalField("nested", transform: { (dict: [String: Any]) in try EntityWithPropertyWithDefaultValue.Nested(dictionary: dict, context: context) }), + url: try dictionary.getOptionalExpressionField("url", transform: URL.makeFromNonEncodedString, validator: Self.urlValidator, context: context) + ) + } + init( int: Expression? = nil, nested: Nested? = nil, diff --git a/api_generator/tests/references/not_templates_swift/EntityWithRawArray.swift b/api_generator/tests/references/not_templates_swift/EntityWithRawArray.swift index 13d5b3b6f..ff66a4977 100644 --- a/api_generator/tests/references/not_templates_swift/EntityWithRawArray.swift +++ b/api_generator/tests/references/not_templates_swift/EntityWithRawArray.swift @@ -12,6 +12,12 @@ public final class EntityWithRawArray: @unchecked Sendable { resolver.resolveArray(array) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + array: try dictionary.getExpressionField("array", context: context) + ) + } + init( array: Expression<[Any]> ) { diff --git a/api_generator/tests/references/not_templates_swift/EntityWithRequiredProperty.swift b/api_generator/tests/references/not_templates_swift/EntityWithRequiredProperty.swift index 214146470..11c970ff4 100644 --- a/api_generator/tests/references/not_templates_swift/EntityWithRequiredProperty.swift +++ b/api_generator/tests/references/not_templates_swift/EntityWithRequiredProperty.swift @@ -15,6 +15,12 @@ public final class EntityWithRequiredProperty: Sendable { static let propertyValidator: AnyValueValidator = makeStringValidator(minLength: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getExpressionField("property", validator: Self.propertyValidator, context: context) + ) + } + init( property: Expression ) { diff --git a/api_generator/tests/references/not_templates_swift/EntityWithSimpleProperties.swift b/api_generator/tests/references/not_templates_swift/EntityWithSimpleProperties.swift index ade7f8afd..08c9da42a 100644 --- a/api_generator/tests/references/not_templates_swift/EntityWithSimpleProperties.swift +++ b/api_generator/tests/references/not_templates_swift/EntityWithSimpleProperties.swift @@ -51,6 +51,20 @@ public final class EntityWithSimpleProperties: EntityProtocol, Sendable { static let positiveIntegerValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 > 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + boolean: try dictionary.getOptionalExpressionField("boolean", context: context), + booleanInt: try dictionary.getOptionalExpressionField("boolean_int", context: context), + color: try dictionary.getOptionalExpressionField("color", transform: Color.color(withHexString:), context: context), + double: try dictionary.getOptionalExpressionField("double", context: context), + id: try dictionary.getOptionalField("id", context: context), + integer: try dictionary.getOptionalExpressionField("integer", context: context), + positiveInteger: try dictionary.getOptionalExpressionField("positive_integer", validator: Self.positiveIntegerValidator, context: context), + string: try dictionary.getOptionalExpressionField("string", context: context), + url: try dictionary.getOptionalExpressionField("url", transform: URL.makeFromNonEncodedString, context: context) + ) + } + init( boolean: Expression? = nil, booleanInt: Expression? = nil, diff --git a/api_generator/tests/references/not_templates_swift/EntityWithStringArrayProperty.swift b/api_generator/tests/references/not_templates_swift/EntityWithStringArrayProperty.swift index 092408873..0182ed9e0 100644 --- a/api_generator/tests/references/not_templates_swift/EntityWithStringArrayProperty.swift +++ b/api_generator/tests/references/not_templates_swift/EntityWithStringArrayProperty.swift @@ -15,6 +15,12 @@ public final class EntityWithStringArrayProperty: Sendable { static let arrayValidator: AnyArrayValueValidator> = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + array: try dictionary.getExpressionArray("array", validator: Self.arrayValidator, context: context) + ) + } + init( array: [Expression] ) { diff --git a/api_generator/tests/references/not_templates_swift/EntityWithStringEnumProperty.swift b/api_generator/tests/references/not_templates_swift/EntityWithStringEnumProperty.swift index 9ddf18e5a..a81852f06 100644 --- a/api_generator/tests/references/not_templates_swift/EntityWithStringEnumProperty.swift +++ b/api_generator/tests/references/not_templates_swift/EntityWithStringEnumProperty.swift @@ -18,6 +18,12 @@ public final class EntityWithStringEnumProperty: Sendable { resolver.resolveEnum(property) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getExpressionField("property", context: context) + ) + } + init( property: Expression ) { diff --git a/api_generator/tests/references/not_templates_swift/EntityWithStringEnumPropertyWithDefaultValue.swift b/api_generator/tests/references/not_templates_swift/EntityWithStringEnumPropertyWithDefaultValue.swift index 57b602ab6..fbd730d7e 100644 --- a/api_generator/tests/references/not_templates_swift/EntityWithStringEnumPropertyWithDefaultValue.swift +++ b/api_generator/tests/references/not_templates_swift/EntityWithStringEnumPropertyWithDefaultValue.swift @@ -19,6 +19,12 @@ public final class EntityWithStringEnumPropertyWithDefaultValue: Sendable { resolver.resolveEnum(value) ?? Value.second } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getOptionalExpressionField("value", context: context) + ) + } + init( value: Expression? = nil ) { diff --git a/api_generator/tests/references/not_templates_swift/EntityWithoutProperties.swift b/api_generator/tests/references/not_templates_swift/EntityWithoutProperties.swift index fe251db82..c3ec1a174 100644 --- a/api_generator/tests/references/not_templates_swift/EntityWithoutProperties.swift +++ b/api_generator/tests/references/not_templates_swift/EntityWithoutProperties.swift @@ -7,6 +7,8 @@ import Serialization public final class EntityWithoutProperties: Sendable { public static let type: String = "entity_without_properties" + public init(dictionary: [String: Any], context: ParsingContext) throws {} + init() {} } diff --git a/api_generator/tests/references/not_templates_swift/EnumWithDefaultType.swift b/api_generator/tests/references/not_templates_swift/EnumWithDefaultType.swift index 2bf77ef4c..0805b08b0 100644 --- a/api_generator/tests/references/not_templates_swift/EnumWithDefaultType.swift +++ b/api_generator/tests/references/not_templates_swift/EnumWithDefaultType.swift @@ -20,13 +20,13 @@ public enum EnumWithDefaultType: Sendable { } extension EnumWithDefaultType { - public init(dictionary: [String: Any]) throws { + public init(dictionary: [String: Any], context: ParsingContext) throws { let blockType = try dictionary.getField("type") as String switch blockType { case WithDefault.type: - self = .withDefault(try WithDefault(dictionary: dictionary)) + self = .withDefault(try WithDefault(dictionary: dictionary, context: context)) case WithoutDefault.type: - self = .withoutDefault(try WithoutDefault(dictionary: dictionary)) + self = .withoutDefault(try WithoutDefault(dictionary: dictionary, context: context)) default: throw DeserializationError.invalidFieldRepresentation(field: "enum_with_default_type", representation: dictionary) } diff --git a/api_generator/tests/references/not_templates_swift/WithDefault.swift b/api_generator/tests/references/not_templates_swift/WithDefault.swift index d20a725e5..c9e23cc0b 100644 --- a/api_generator/tests/references/not_templates_swift/WithDefault.swift +++ b/api_generator/tests/references/not_templates_swift/WithDefault.swift @@ -7,7 +7,7 @@ import Serialization public final class WithDefault: Sendable { public static let type: String = "default" - public init(dictionary: [String: Any]) throws {} + public init(dictionary: [String: Any], context: ParsingContext) throws {} init() {} } diff --git a/api_generator/tests/references/not_templates_swift/WithoutDefault.swift b/api_generator/tests/references/not_templates_swift/WithoutDefault.swift index bcffe0d3f..10d88fb70 100644 --- a/api_generator/tests/references/not_templates_swift/WithoutDefault.swift +++ b/api_generator/tests/references/not_templates_swift/WithoutDefault.swift @@ -7,7 +7,7 @@ import Serialization public final class WithoutDefault: Sendable { public static let type: String = "non_default" - public init(dictionary: [String: Any]) throws {} + public init(dictionary: [String: Any], context: ParsingContext) throws {} init() {} } diff --git a/api_generator/tests/references/swift/Entity.swift b/api_generator/tests/references/swift/Entity.swift index 4f4f79c37..41c161223 100644 --- a/api_generator/tests/references/swift/Entity.swift +++ b/api_generator/tests/references/swift/Entity.swift @@ -70,6 +70,54 @@ public enum Entity: Sendable { } } +extension Entity { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case EntityWithArray.type: + self = .entityWithArray(try EntityWithArray(dictionary: dictionary, context: context)) + case EntityWithArrayOfEnums.type: + self = .entityWithArrayOfEnums(try EntityWithArrayOfEnums(dictionary: dictionary, context: context)) + case EntityWithArrayOfExpressions.type: + self = .entityWithArrayOfExpressions(try EntityWithArrayOfExpressions(dictionary: dictionary, context: context)) + case EntityWithArrayOfNestedItems.type: + self = .entityWithArrayOfNestedItems(try EntityWithArrayOfNestedItems(dictionary: dictionary, context: context)) + case EntityWithArrayWithTransform.type: + self = .entityWithArrayWithTransform(try EntityWithArrayWithTransform(dictionary: dictionary, context: context)) + case EntityWithComplexProperty.type: + self = .entityWithComplexProperty(try EntityWithComplexProperty(dictionary: dictionary, context: context)) + case EntityWithComplexPropertyWithDefaultValue.type: + self = .entityWithComplexPropertyWithDefaultValue(try EntityWithComplexPropertyWithDefaultValue(dictionary: dictionary, context: context)) + case EntityWithEntityProperty.type: + self = .entityWithEntityProperty(try EntityWithEntityProperty(dictionary: dictionary, context: context)) + case EntityWithOptionalComplexProperty.type: + self = .entityWithOptionalComplexProperty(try EntityWithOptionalComplexProperty(dictionary: dictionary, context: context)) + case EntityWithOptionalProperty.type: + self = .entityWithOptionalProperty(try EntityWithOptionalProperty(dictionary: dictionary, context: context)) + case EntityWithOptionalStringEnumProperty.type: + self = .entityWithOptionalStringEnumProperty(try EntityWithOptionalStringEnumProperty(dictionary: dictionary, context: context)) + case EntityWithPropertyWithDefaultValue.type: + self = .entityWithPropertyWithDefaultValue(try EntityWithPropertyWithDefaultValue(dictionary: dictionary, context: context)) + case EntityWithRawArray.type: + self = .entityWithRawArray(try EntityWithRawArray(dictionary: dictionary, context: context)) + case EntityWithRequiredProperty.type: + self = .entityWithRequiredProperty(try EntityWithRequiredProperty(dictionary: dictionary, context: context)) + case EntityWithSimpleProperties.type: + self = .entityWithSimpleProperties(try EntityWithSimpleProperties(dictionary: dictionary, context: context)) + case EntityWithStringArrayProperty.type: + self = .entityWithStringArrayProperty(try EntityWithStringArrayProperty(dictionary: dictionary, context: context)) + case EntityWithStringEnumProperty.type: + self = .entityWithStringEnumProperty(try EntityWithStringEnumProperty(dictionary: dictionary, context: context)) + case EntityWithStringEnumPropertyWithDefaultValue.type: + self = .entityWithStringEnumPropertyWithDefaultValue(try EntityWithStringEnumPropertyWithDefaultValue(dictionary: dictionary, context: context)) + case EntityWithoutProperties.type: + self = .entityWithoutProperties(try EntityWithoutProperties(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "entity", representation: dictionary) + } + } +} + #if DEBUG extension Entity: Equatable { public static func ==(lhs: Entity, rhs: Entity) -> Bool { diff --git a/api_generator/tests/references/swift/EntityWithArray.swift b/api_generator/tests/references/swift/EntityWithArray.swift index 41126260a..0d5376df9 100644 --- a/api_generator/tests/references/swift/EntityWithArray.swift +++ b/api_generator/tests/references/swift/EntityWithArray.swift @@ -11,6 +11,12 @@ public final class EntityWithArray: Sendable { static let arrayValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + array: try dictionary.getArray("array", transform: { (dict: [String: Any]) in try? Entity(dictionary: dict, context: context) }, validator: Self.arrayValidator) + ) + } + init( array: [Entity] ) { diff --git a/api_generator/tests/references/swift/EntityWithArrayOfEnums.swift b/api_generator/tests/references/swift/EntityWithArrayOfEnums.swift index 9acf6b6a7..2e91185ee 100644 --- a/api_generator/tests/references/swift/EntityWithArrayOfEnums.swift +++ b/api_generator/tests/references/swift/EntityWithArrayOfEnums.swift @@ -17,6 +17,12 @@ public final class EntityWithArrayOfEnums: Sendable { static let itemsValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + items: try dictionary.getArray("items", validator: Self.itemsValidator, context: context) + ) + } + init( items: [Item] ) { diff --git a/api_generator/tests/references/swift/EntityWithArrayOfExpressions.swift b/api_generator/tests/references/swift/EntityWithArrayOfExpressions.swift index a88f7ba8e..f903cbef2 100644 --- a/api_generator/tests/references/swift/EntityWithArrayOfExpressions.swift +++ b/api_generator/tests/references/swift/EntityWithArrayOfExpressions.swift @@ -15,6 +15,12 @@ public final class EntityWithArrayOfExpressions: Sendable { static let itemsValidator: AnyArrayValueValidator> = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + items: try dictionary.getExpressionArray("items", validator: Self.itemsValidator, context: context) + ) + } + init( items: [Expression] ) { diff --git a/api_generator/tests/references/swift/EntityWithArrayOfNestedItems.swift b/api_generator/tests/references/swift/EntityWithArrayOfNestedItems.swift index 265f2fdf1..2edd1e5fc 100644 --- a/api_generator/tests/references/swift/EntityWithArrayOfNestedItems.swift +++ b/api_generator/tests/references/swift/EntityWithArrayOfNestedItems.swift @@ -13,6 +13,13 @@ public final class EntityWithArrayOfNestedItems: Sendable { resolver.resolveString(property) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + entity: try dictionary.getField("entity", transform: { (dict: [String: Any]) in try Entity(dictionary: dict, context: context) }), + property: try dictionary.getExpressionField("property", context: context) + ) + } + init( entity: Entity, property: Expression @@ -28,6 +35,12 @@ public final class EntityWithArrayOfNestedItems: Sendable { static let itemsValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + items: try dictionary.getArray("items", transform: { (dict: [String: Any]) in try? EntityWithArrayOfNestedItems.Item(dictionary: dict, context: context) }, validator: Self.itemsValidator) + ) + } + init( items: [Item] ) { diff --git a/api_generator/tests/references/swift/EntityWithArrayWithTransform.swift b/api_generator/tests/references/swift/EntityWithArrayWithTransform.swift index 463e958bb..a79a22e8c 100644 --- a/api_generator/tests/references/swift/EntityWithArrayWithTransform.swift +++ b/api_generator/tests/references/swift/EntityWithArrayWithTransform.swift @@ -15,6 +15,12 @@ public final class EntityWithArrayWithTransform: Sendable { static let arrayValidator: AnyArrayValueValidator> = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + array: try dictionary.getExpressionArray("array", transform: Color.color(withHexString:), validator: Self.arrayValidator, context: context) + ) + } + init( array: [Expression] ) { diff --git a/api_generator/tests/references/swift/EntityWithComplexProperty.swift b/api_generator/tests/references/swift/EntityWithComplexProperty.swift index 0425c48c3..d7e0b31da 100644 --- a/api_generator/tests/references/swift/EntityWithComplexProperty.swift +++ b/api_generator/tests/references/swift/EntityWithComplexProperty.swift @@ -12,6 +12,12 @@ public final class EntityWithComplexProperty: Sendable { resolver.resolveUrl(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", transform: URL.makeFromNonEncodedString, context: context) + ) + } + init( value: Expression ) { @@ -22,6 +28,12 @@ public final class EntityWithComplexProperty: Sendable { public static let type: String = "entity_with_complex_property" public let property: Property + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getField("property", transform: { (dict: [String: Any]) in try EntityWithComplexProperty.Property(dictionary: dict, context: context) }) + ) + } + init( property: Property ) { diff --git a/api_generator/tests/references/swift/EntityWithComplexPropertyWithDefaultValue.swift b/api_generator/tests/references/swift/EntityWithComplexPropertyWithDefaultValue.swift index 9c2f09b50..5604612c1 100644 --- a/api_generator/tests/references/swift/EntityWithComplexPropertyWithDefaultValue.swift +++ b/api_generator/tests/references/swift/EntityWithComplexPropertyWithDefaultValue.swift @@ -12,6 +12,12 @@ public final class EntityWithComplexPropertyWithDefaultValue: Sendable { resolver.resolveString(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( value: Expression ) { @@ -22,6 +28,12 @@ public final class EntityWithComplexPropertyWithDefaultValue: Sendable { public static let type: String = "entity_with_complex_property_with_default_value" public let property: Property // default value: EntityWithComplexPropertyWithDefaultValue.Property(value: .value("Default text")) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getOptionalField("property", transform: { (dict: [String: Any]) in try EntityWithComplexPropertyWithDefaultValue.Property(dictionary: dict, context: context) }) + ) + } + init( property: Property? = nil ) { diff --git a/api_generator/tests/references/swift/EntityWithEntityProperty.swift b/api_generator/tests/references/swift/EntityWithEntityProperty.swift index fb15cf0bf..2e313f576 100644 --- a/api_generator/tests/references/swift/EntityWithEntityProperty.swift +++ b/api_generator/tests/references/swift/EntityWithEntityProperty.swift @@ -8,6 +8,12 @@ public final class EntityWithEntityProperty: Sendable { public static let type: String = "entity_with_entity_property" public let entity: Entity // default value: .entityWithStringEnumProperty(EntityWithStringEnumProperty(property: .value(.second))) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + entity: try dictionary.getOptionalField("entity", transform: { (dict: [String: Any]) in try Entity(dictionary: dict, context: context) }) + ) + } + init( entity: Entity? = nil ) { diff --git a/api_generator/tests/references/swift/EntityWithJsonProperty.swift b/api_generator/tests/references/swift/EntityWithJsonProperty.swift index f2e7d0c84..baf97523d 100644 --- a/api_generator/tests/references/swift/EntityWithJsonProperty.swift +++ b/api_generator/tests/references/swift/EntityWithJsonProperty.swift @@ -8,6 +8,12 @@ public final class EntityWithJsonProperty: @unchecked Sendable { public static let type: String = "entity_with_json_property" public let jsonProperty: [String: Any] // default value: { "key": "value", "items": [ "value" ] } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + jsonProperty: try dictionary.getOptionalField("json_property", context: context) + ) + } + init( jsonProperty: [String: Any]? = nil ) { diff --git a/api_generator/tests/references/swift/EntityWithOptionalComplexProperty.swift b/api_generator/tests/references/swift/EntityWithOptionalComplexProperty.swift index 5c87b30cb..1326e71ba 100644 --- a/api_generator/tests/references/swift/EntityWithOptionalComplexProperty.swift +++ b/api_generator/tests/references/swift/EntityWithOptionalComplexProperty.swift @@ -12,6 +12,12 @@ public final class EntityWithOptionalComplexProperty: Sendable { resolver.resolveUrl(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", transform: URL.makeFromNonEncodedString, context: context) + ) + } + init( value: Expression ) { @@ -22,6 +28,12 @@ public final class EntityWithOptionalComplexProperty: Sendable { public static let type: String = "entity_with_optional_complex_property" public let property: Property? + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getOptionalField("property", transform: { (dict: [String: Any]) in try EntityWithOptionalComplexProperty.Property(dictionary: dict, context: context) }) + ) + } + init( property: Property? = nil ) { diff --git a/api_generator/tests/references/swift/EntityWithOptionalProperty.swift b/api_generator/tests/references/swift/EntityWithOptionalProperty.swift index 1ddc12970..c6535a88a 100644 --- a/api_generator/tests/references/swift/EntityWithOptionalProperty.swift +++ b/api_generator/tests/references/swift/EntityWithOptionalProperty.swift @@ -12,6 +12,12 @@ public final class EntityWithOptionalProperty: Sendable { resolver.resolveString(property) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getOptionalExpressionField("property", context: context) + ) + } + init( property: Expression? = nil ) { diff --git a/api_generator/tests/references/swift/EntityWithOptionalStringEnumProperty.swift b/api_generator/tests/references/swift/EntityWithOptionalStringEnumProperty.swift index 38b52723f..e0952eeb5 100644 --- a/api_generator/tests/references/swift/EntityWithOptionalStringEnumProperty.swift +++ b/api_generator/tests/references/swift/EntityWithOptionalStringEnumProperty.swift @@ -18,6 +18,12 @@ public final class EntityWithOptionalStringEnumProperty: Sendable { resolver.resolveEnum(property) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getOptionalExpressionField("property", context: context) + ) + } + init( property: Expression? = nil ) { diff --git a/api_generator/tests/references/swift/EntityWithPropertyWithDefaultValue.swift b/api_generator/tests/references/swift/EntityWithPropertyWithDefaultValue.swift index fa5bdc94b..a025f47a8 100644 --- a/api_generator/tests/references/swift/EntityWithPropertyWithDefaultValue.swift +++ b/api_generator/tests/references/swift/EntityWithPropertyWithDefaultValue.swift @@ -28,6 +28,14 @@ public final class EntityWithPropertyWithDefaultValue: Sendable { static let urlValidator: AnyValueValidator = makeURLValidator(schemes: ["https"]) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + int: try dictionary.getOptionalExpressionField("int", validator: Self.intValidator, context: context), + nonOptional: try dictionary.getExpressionField("non_optional", context: context), + url: try dictionary.getOptionalExpressionField("url", transform: URL.makeFromNonEncodedString, validator: Self.urlValidator, context: context) + ) + } + init( int: Expression? = nil, nonOptional: Expression, @@ -58,6 +66,14 @@ public final class EntityWithPropertyWithDefaultValue: Sendable { static let urlValidator: AnyValueValidator = makeURLValidator(schemes: ["https"]) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + int: try dictionary.getOptionalExpressionField("int", validator: Self.intValidator, context: context), + nested: try dictionary.getOptionalField("nested", transform: { (dict: [String: Any]) in try EntityWithPropertyWithDefaultValue.Nested(dictionary: dict, context: context) }), + url: try dictionary.getOptionalExpressionField("url", transform: URL.makeFromNonEncodedString, validator: Self.urlValidator, context: context) + ) + } + init( int: Expression? = nil, nested: Nested? = nil, diff --git a/api_generator/tests/references/swift/EntityWithRawArray.swift b/api_generator/tests/references/swift/EntityWithRawArray.swift index 13d5b3b6f..ff66a4977 100644 --- a/api_generator/tests/references/swift/EntityWithRawArray.swift +++ b/api_generator/tests/references/swift/EntityWithRawArray.swift @@ -12,6 +12,12 @@ public final class EntityWithRawArray: @unchecked Sendable { resolver.resolveArray(array) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + array: try dictionary.getExpressionField("array", context: context) + ) + } + init( array: Expression<[Any]> ) { diff --git a/api_generator/tests/references/swift/EntityWithRequiredProperty.swift b/api_generator/tests/references/swift/EntityWithRequiredProperty.swift index 214146470..11c970ff4 100644 --- a/api_generator/tests/references/swift/EntityWithRequiredProperty.swift +++ b/api_generator/tests/references/swift/EntityWithRequiredProperty.swift @@ -15,6 +15,12 @@ public final class EntityWithRequiredProperty: Sendable { static let propertyValidator: AnyValueValidator = makeStringValidator(minLength: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getExpressionField("property", validator: Self.propertyValidator, context: context) + ) + } + init( property: Expression ) { diff --git a/api_generator/tests/references/swift/EntityWithSimpleProperties.swift b/api_generator/tests/references/swift/EntityWithSimpleProperties.swift index ade7f8afd..08c9da42a 100644 --- a/api_generator/tests/references/swift/EntityWithSimpleProperties.swift +++ b/api_generator/tests/references/swift/EntityWithSimpleProperties.swift @@ -51,6 +51,20 @@ public final class EntityWithSimpleProperties: EntityProtocol, Sendable { static let positiveIntegerValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 > 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + boolean: try dictionary.getOptionalExpressionField("boolean", context: context), + booleanInt: try dictionary.getOptionalExpressionField("boolean_int", context: context), + color: try dictionary.getOptionalExpressionField("color", transform: Color.color(withHexString:), context: context), + double: try dictionary.getOptionalExpressionField("double", context: context), + id: try dictionary.getOptionalField("id", context: context), + integer: try dictionary.getOptionalExpressionField("integer", context: context), + positiveInteger: try dictionary.getOptionalExpressionField("positive_integer", validator: Self.positiveIntegerValidator, context: context), + string: try dictionary.getOptionalExpressionField("string", context: context), + url: try dictionary.getOptionalExpressionField("url", transform: URL.makeFromNonEncodedString, context: context) + ) + } + init( boolean: Expression? = nil, booleanInt: Expression? = nil, diff --git a/api_generator/tests/references/swift/EntityWithStringArrayProperty.swift b/api_generator/tests/references/swift/EntityWithStringArrayProperty.swift index 092408873..0182ed9e0 100644 --- a/api_generator/tests/references/swift/EntityWithStringArrayProperty.swift +++ b/api_generator/tests/references/swift/EntityWithStringArrayProperty.swift @@ -15,6 +15,12 @@ public final class EntityWithStringArrayProperty: Sendable { static let arrayValidator: AnyArrayValueValidator> = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + array: try dictionary.getExpressionArray("array", validator: Self.arrayValidator, context: context) + ) + } + init( array: [Expression] ) { diff --git a/api_generator/tests/references/swift/EntityWithStringEnumProperty.swift b/api_generator/tests/references/swift/EntityWithStringEnumProperty.swift index 9ddf18e5a..a81852f06 100644 --- a/api_generator/tests/references/swift/EntityWithStringEnumProperty.swift +++ b/api_generator/tests/references/swift/EntityWithStringEnumProperty.swift @@ -18,6 +18,12 @@ public final class EntityWithStringEnumProperty: Sendable { resolver.resolveEnum(property) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getExpressionField("property", context: context) + ) + } + init( property: Expression ) { diff --git a/api_generator/tests/references/swift/EntityWithStringEnumPropertyWithDefaultValue.swift b/api_generator/tests/references/swift/EntityWithStringEnumPropertyWithDefaultValue.swift index 57b602ab6..fbd730d7e 100644 --- a/api_generator/tests/references/swift/EntityWithStringEnumPropertyWithDefaultValue.swift +++ b/api_generator/tests/references/swift/EntityWithStringEnumPropertyWithDefaultValue.swift @@ -19,6 +19,12 @@ public final class EntityWithStringEnumPropertyWithDefaultValue: Sendable { resolver.resolveEnum(value) ?? Value.second } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getOptionalExpressionField("value", context: context) + ) + } + init( value: Expression? = nil ) { diff --git a/api_generator/tests/references/swift/EntityWithoutProperties.swift b/api_generator/tests/references/swift/EntityWithoutProperties.swift index fe251db82..c3ec1a174 100644 --- a/api_generator/tests/references/swift/EntityWithoutProperties.swift +++ b/api_generator/tests/references/swift/EntityWithoutProperties.swift @@ -7,6 +7,8 @@ import Serialization public final class EntityWithoutProperties: Sendable { public static let type: String = "entity_without_properties" + public init(dictionary: [String: Any], context: ParsingContext) throws {} + init() {} } diff --git a/api_generator/tests/references/swift/EnumWithDefaultType.swift b/api_generator/tests/references/swift/EnumWithDefaultType.swift index 7bb1f9fc9..0805b08b0 100644 --- a/api_generator/tests/references/swift/EnumWithDefaultType.swift +++ b/api_generator/tests/references/swift/EnumWithDefaultType.swift @@ -19,6 +19,20 @@ public enum EnumWithDefaultType: Sendable { } } +extension EnumWithDefaultType { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case WithDefault.type: + self = .withDefault(try WithDefault(dictionary: dictionary, context: context)) + case WithoutDefault.type: + self = .withoutDefault(try WithoutDefault(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "enum_with_default_type", representation: dictionary) + } + } +} + #if DEBUG extension EnumWithDefaultType: Equatable { public static func ==(lhs: EnumWithDefaultType, rhs: EnumWithDefaultType) -> Bool { diff --git a/api_generator/tests/references/swift/WithDefault.swift b/api_generator/tests/references/swift/WithDefault.swift index 0429839ab..c9e23cc0b 100644 --- a/api_generator/tests/references/swift/WithDefault.swift +++ b/api_generator/tests/references/swift/WithDefault.swift @@ -7,6 +7,8 @@ import Serialization public final class WithDefault: Sendable { public static let type: String = "default" + public init(dictionary: [String: Any], context: ParsingContext) throws {} + init() {} } diff --git a/api_generator/tests/references/swift/WithoutDefault.swift b/api_generator/tests/references/swift/WithoutDefault.swift index 3279cc6dd..10d88fb70 100644 --- a/api_generator/tests/references/swift/WithoutDefault.swift +++ b/api_generator/tests/references/swift/WithoutDefault.swift @@ -7,6 +7,8 @@ import Serialization public final class WithoutDefault: Sendable { public static let type: String = "non_default" + public init(dictionary: [String: Any], context: ParsingContext) throws {} + init() {} } diff --git a/client/ios/DivKit/DivFlagsInfo.swift b/client/ios/DivKit/DivFlagsInfo.swift index f8238673a..f6d500ea6 100644 --- a/client/ios/DivKit/DivFlagsInfo.swift +++ b/client/ios/DivKit/DivFlagsInfo.swift @@ -5,7 +5,7 @@ /// performance issues, crashes, or other problems. By default, only features that have testing are /// included in the framework. /// You can access the default `DivFlagsInfo` instance using the static property `default`. -public struct DivFlagsInfo: Encodable, Equatable { +public struct DivFlagsInfo: Encodable, Equatable, Sendable { /// The default instance of `DivFlagsInfo`. public static let `default` = DivFlagsInfo() @@ -53,6 +53,14 @@ public struct DivFlagsInfo: Encodable, Equatable { /// `font_weight_value` is specified. public let variationFontWeightOverrideEnabled: Bool + /// Enables untyped template resolving pipeline for card parsing. + /// + /// `false` - typed template resolving is used (`*Template.swift` entities). + /// + /// `true` - templates are resolved by untyped resolver and then parsed with generated + /// non-template deserializers. + public let useUntypedTemplateResolver: Bool + /// Creates an instance of `DivFlagsInfo`. public init( useUrlHandlerForVisibilityActions: Bool = false, @@ -62,7 +70,8 @@ public struct DivFlagsInfo: Encodable, Equatable { initializeTriggerOnSet: Bool = true, defaultTextAutoEllipsize: Bool = true, fontCacheEnabled: Bool = true, - variationFontWeightOverrideEnabled: Bool = true + variationFontWeightOverrideEnabled: Bool = true, + useUntypedTemplateResolver: Bool = false ) { self.useUrlHandlerForVisibilityActions = useUrlHandlerForVisibilityActions self.imageBlurPreferMetal = imageBlurPreferMetal @@ -72,6 +81,7 @@ public struct DivFlagsInfo: Encodable, Equatable { self.defaultTextAutoEllipsize = defaultTextAutoEllipsize self.fontCacheEnabled = fontCacheEnabled self.variationFontWeightOverrideEnabled = variationFontWeightOverrideEnabled + self.useUntypedTemplateResolver = useUntypedTemplateResolver } } @@ -85,6 +95,7 @@ extension DivFlagsInfo: Decodable { case defaultTextAutoEllipsize case fontCacheEnabled case variationFontWeightOverrideEnabled + case useUntypedTemplateResolver } public init(from decoder: Decoder) throws { @@ -129,5 +140,10 @@ extension DivFlagsInfo: Decodable { Bool.self, forKey: .variationFontWeightOverrideEnabled ) ?? Self.default.variationFontWeightOverrideEnabled + + self.useUntypedTemplateResolver = try container.decodeIfPresent( + Bool.self, + forKey: .useUntypedTemplateResolver + ) ?? Self.default.useUntypedTemplateResolver } } diff --git a/client/ios/DivKit/DivKitComponents.swift b/client/ios/DivKit/DivKitComponents.swift index 0882a3a11..82fdebcf1 100644 --- a/client/ios/DivKit/DivKitComponents.swift +++ b/client/ios/DivKit/DivKitComponents.swift @@ -265,7 +265,8 @@ public final class DivKitComponents { let rawDivData = try RawDivData(dictionary: jsonDict) let result = DivData.resolve( card: rawDivData.card, - templates: rawDivData.templates + templates: rawDivData.templates, + flagsInfo: flagsInfo ).asCardResult(cardId: cardId) if let divData = result.value { setCardData(divData: divData, cardId: cardId) diff --git a/client/ios/DivKit/Expressions/Serialization/DictionaryExtensions.swift b/client/ios/DivKit/Expressions/Serialization/DictionaryExtensions.swift index d917ec60c..932d734b9 100644 --- a/client/ios/DivKit/Expressions/Serialization/DictionaryExtensions.swift +++ b/client/ios/DivKit/Expressions/Serialization/DictionaryExtensions.swift @@ -43,3 +43,245 @@ extension [String: Any] { ) } } + +extension [String: Any] { + func getExpressionField( + _ key: String, + validator: AnyValueValidator? = nil + ) throws -> Expression where T.RawValue == String { + try getExpressionField( + key, + transform: T.init(rawValue:), + validator: validator + ) + } + + func getExpressionField( + _ key: String, + validator: AnyValueValidator? = nil + ) throws -> Expression { + try getExpressionField( + key, + transform: { $0 as T }, + validator: validator + ) + } + + func getExpressionField( + _ key: String, + transform: (U) -> T?, + validator: AnyValueValidator? = nil + ) throws -> Expression { + try getField( + key, + transform: { expressionTransform($0, transform: transform, validator: validator) } + ) + } + + func getOptionalExpressionField( + _ key: String, + validator: AnyValueValidator? = nil + ) throws -> Expression? where T.RawValue == String { + try getOptionalExpressionField( + key, + transform: T.init(rawValue:), + validator: validator + ) + } + + func getOptionalExpressionField( + _ key: String, + validator: AnyValueValidator? = nil + ) throws -> Expression? { + try getOptionalExpressionField( + key, + transform: { $0 as T }, + validator: validator + ) + } + + func getOptionalExpressionField( + _ key: String, + transform: (U) -> T?, + validator: AnyValueValidator? = nil + ) throws -> Expression? { + try getOptionalField( + key, + transform: { expressionTransform($0, transform: transform, validator: validator) } + ) + } + + func getExpressionArray( + _ key: String, + validator: AnyArrayValueValidator>? = nil + ) throws -> [Expression] { + try getExpressionArray( + key, + transform: { $0 as T }, + validator: validator + ) + } + + func getExpressionArray( + _ key: String, + transform: (U) -> T?, + validator: AnyArrayValueValidator>? = nil + ) throws -> [Expression] { + try getArray( + key, + transform: { (value: U) in + expressionTransform(value, transform: transform) + }, + validator: validator + ) + } + + func getOptionalExpressionArray( + _ key: String, + validator: AnyArrayValueValidator>? = nil + ) throws -> [Expression]? { + try getOptionalExpressionArray( + key, + transform: { $0 as T }, + validator: validator + ) + } + + func getOptionalExpressionArray( + _ key: String, + transform: (U) -> T?, + validator: AnyArrayValueValidator>? = nil + ) throws -> [Expression]? { + try getOptionalArray( + key, + transform: { (value: U) in + expressionTransform(value, transform: transform) + }, + validator: validator + ) + } +} + +extension [String: Any] { + func getExpressionField( + _ key: String, + validator: AnyValueValidator? = nil, + context: ParsingContext + ) throws -> Expression where T.RawValue == String { + try getExpressionField( + key, + transform: T.init(rawValue:), + validator: validator, + context: context + ) + } + + func getExpressionField( + _ key: String, + validator: AnyValueValidator? = nil, + context: ParsingContext + ) throws -> Expression { + try getExpressionField(key, transform: { $0 as T }, validator: validator, context: context) + } + + func getExpressionField( + _ key: String, + transform: (U) -> T?, + validator: AnyValueValidator? = nil, + context: ParsingContext + ) throws -> Expression { + try getField( + key, + transform: { expressionTransform($0, transform: transform, validator: validator) }, + context: context + ) + } + + func getOptionalExpressionField( + _ key: String, + validator: AnyValueValidator? = nil, + context: ParsingContext + ) throws -> Expression? where T.RawValue == String { + try getOptionalExpressionField( + key, + transform: T.init(rawValue:), + validator: validator, + context: context + ) + } + + func getOptionalExpressionField( + _ key: String, + validator: AnyValueValidator? = nil, + context: ParsingContext + ) throws -> Expression? { + try getOptionalExpressionField( + key, + transform: { $0 as T }, + validator: validator, + context: context + ) + } + + func getOptionalExpressionField( + _ key: String, + transform: (U) -> T?, + validator: AnyValueValidator? = nil, + context: ParsingContext + ) throws -> Expression? { + try getOptionalField( + key, + transform: { expressionTransform($0, transform: transform, validator: validator) }, + context: context + ) + } + + func getExpressionArray( + _ key: String, + validator: AnyArrayValueValidator>? = nil, + context: ParsingContext + ) throws -> [Expression] { + try getExpressionArray(key, transform: { $0 as T }, validator: validator, context: context) + } + + func getExpressionArray( + _ key: String, + transform: (U) -> T?, + validator: AnyArrayValueValidator>? = nil, + context: ParsingContext + ) throws -> [Expression] { + try getArray( + key, + transform: { (value: U) in expressionTransform(value, transform: transform) }, + validator: validator, + context: context + ) + } + + func getOptionalExpressionArray( + _ key: String, + validator: AnyArrayValueValidator>? = nil, + context: ParsingContext + ) throws -> [Expression]? { + try getOptionalExpressionArray( + key, + transform: { $0 as T }, + validator: validator, + context: context + ) + } + + func getOptionalExpressionArray( + _ key: String, + transform: (U) -> T?, + validator: AnyArrayValueValidator>? = nil, + context: ParsingContext + ) throws -> [Expression]? { + try getOptionalArray( + key, + transform: { (value: U) in expressionTransform(value, transform: transform) }, + validator: validator, + context: context + ) + } +} diff --git a/client/ios/DivKit/Expressions/Serialization/FieldExtensions.swift b/client/ios/DivKit/Expressions/Serialization/FieldExtensions.swift index 9494d0d67..a35dceb4b 100644 --- a/client/ios/DivKit/Expressions/Serialization/FieldExtensions.swift +++ b/client/ios/DivKit/Expressions/Serialization/FieldExtensions.swift @@ -69,8 +69,11 @@ extension Field { case let .link(link): return context.templateData.getArray( link, - transform: { (value: U) in - expressionTransform(value, transform: transform) + transform: { (value: U) -> DeserializationResult> in + guard let transformed = expressionTransform(value, transform: transform) else { + return .noValue + } + return .success(transformed) }, validator: validator ) diff --git a/client/ios/DivKit/Extensions/DivData/DivDataExtensions.swift b/client/ios/DivKit/Extensions/DivData/DivDataExtensions.swift index 41af2ce9c..bef38f722 100644 --- a/client/ios/DivKit/Extensions/DivData/DivDataExtensions.swift +++ b/client/ios/DivKit/Extensions/DivData/DivDataExtensions.swift @@ -95,8 +95,59 @@ extension DivData: DivBlockModeling { extension DivData { public static func resolve( card cardDict: [String: Any], - templates templatesDict: [String: Any]? + templates templatesDict: [String: Any]?, + flagsInfo: DivFlagsInfo = .default ) -> DeserializationResult { + if flagsInfo.useUntypedTemplateResolver { + var resolver = UntypedDivTemplateResolver(templates: templatesDict) + let resolvedCardResult = resolver.resolve(card: cardDict) + let parsingContext = ParsingContext() + + guard let resolvedCard = resolvedCardResult.value else { + return .failure(resolvedCardResult.errorsOrWarnings ?? NonEmptyArray(.generic)) + } + + let divDataResult: DeserializationResult + do { + divDataResult = try .success(DivData(dictionary: resolvedCard, context: parsingContext)) + } catch let error as DeserializationError { + divDataResult = .failure(NonEmptyArray(error)) + } catch { + divDataResult = + .failure(NonEmptyArray(.unexpectedError(message: String(describing: error)))) + } + + let contextWarnings: NonEmptyArray? = NonEmptyArray(parsingContext + .warnings + ) + let contextErrors: NonEmptyArray? = NonEmptyArray(parsingContext.errors) + let resolverWarnings = resolvedCardResult.warnings + + let allIssues: NonEmptyArray? = NonEmptyArray( + mergeErrors(contextWarnings, contextErrors, resolverWarnings) + ) + + switch divDataResult { + case let .success(value): + if let warnings = allIssues { + return .partialSuccess(value, warnings: warnings) + } + return .success(value) + case let .partialSuccess(value, warnings): + if let mergedWarnings = NonEmptyArray(mergeErrors(warnings, allIssues)) { + return .partialSuccess(value, warnings: mergedWarnings) + } + return .success(value) + case let .failure(errors): + return .failure(NonEmptyArray(mergeErrors(errors, allIssues))!) + case .noValue: + if let warnings = allIssues { + return .failure(warnings) + } + return .failure(NonEmptyArray(.generic)) + } + } + let divTemplates = templatesDict.map(DivTemplates.init) ?? .empty return divTemplates.parseValue(type: DivDataTemplate.self, from: cardDict) } diff --git a/client/ios/DivKit/RawDivData.swift b/client/ios/DivKit/RawDivData.swift index fe4ac292d..4fd5a467c 100644 --- a/client/ios/DivKit/RawDivData.swift +++ b/client/ios/DivKit/RawDivData.swift @@ -9,7 +9,7 @@ public struct RawDivData: Deserializable, @unchecked Sendable { templates = try dictionary.getOptionalField("templates") ?? [:] } - public func resolve() -> DeserializationResult { - DivData.resolve(card: card, templates: templates) + public func resolve(flagsInfo: DivFlagsInfo = .default) -> DeserializationResult { + DivData.resolve(card: card, templates: templates, flagsInfo: flagsInfo) } } diff --git a/client/ios/DivKit/Templates/UntypedDivTemplateResolver.swift b/client/ios/DivKit/Templates/UntypedDivTemplateResolver.swift new file mode 100644 index 000000000..a9ebf5faa --- /dev/null +++ b/client/ios/DivKit/Templates/UntypedDivTemplateResolver.swift @@ -0,0 +1,219 @@ +import Foundation +import Serialization +import VGSL + +struct UntypedDivTemplateResolver { + private enum Origin { + case instance + case template + } + + private struct OriginValue { + let value: Any + let origin: Origin + } + + private let templates: [TemplateName: Any] + private let templateToType: [TemplateName: String] + private var resolvedTemplateCache: [TemplateName: [String: Any]] = [:] + private var currentlyResolvingTemplates = Set() + + init(templates: [String: Any]?) { + let templates = templates ?? [:] + self.templates = templates + templateToType = calculateTemplateToType(in: templates) + } + + mutating func resolve(card: [String: Any]) -> DeserializationResult<[String: Any]> { + resolveDictionary( + card, + linkSource: card, + origin: .instance + ) + } + + private mutating func resolveDictionary( + _ dictionary: [String: Any], + linkSource: [String: Any], + origin: Origin + ) -> DeserializationResult<[String: Any]> { + var values: [String: OriginValue] = [:] + + if let templateName = dictionary["type"] as? String, templates[templateName] != nil { + let resolvedTemplate = resolveTemplate(named: templateName) + guard let templateValue = resolvedTemplate.value else { + return .failure(normalizedErrors(from: resolvedTemplate.errorsOrWarnings)) + } + + values = templateValue.mapValues { OriginValue(value: $0, origin: .template) } + for (key, value) in dictionary { + values[key] = OriginValue(value: value, origin: .instance) + } + values["type"] = OriginValue( + value: templateToType[templateName] ?? templateName, + origin: .template + ) + } else { + values = dictionary.mapValues { OriginValue(value: $0, origin: .instance) } + } + + let currentLinkSource = origin == .instance ? dictionary : linkSource + substituteLinks(values: &values, linkSource: currentLinkSource) + + var resolved: [String: Any] = [:] + var errors: [DeserializationError] = [] + + for (key, value) in values { + guard !key.hasPrefix("$") else { continue } + + let childResult = resolveAny( + value.value, + linkSource: currentLinkSource, + origin: value.origin + ) + if let resolvedChild = childResult.value { + resolved[key] = resolvedChild + } + if let childErrors = childResult.errorsOrWarnings { + errors.append(contentsOf: childErrors.map { .nestedObjectError(field: key, error: $0) }) + } + } + + if let warnings = NonEmptyArray(errors) { + return .partialSuccess(resolved, warnings: warnings) + } + return .success(resolved) + } + + private mutating func resolveArray( + _ array: [Any], + linkSource: [String: Any], + origin: Origin + ) -> DeserializationResult<[Any]> { + var result: [Any] = [] + var errors: [DeserializationError] = [] + result.reserveCapacity(array.count) + + for index in array.indices { + let child = array[index] + let childResult: DeserializationResult + if let dictionary = child as? [String: Any] { + let childLinkSource = origin == .instance ? dictionary : linkSource + childResult = resolveDictionary( + dictionary, + linkSource: childLinkSource, + origin: origin == .instance ? .instance : .template + ).map { $0 as Any } + } else if let nestedArray = child as? [Any] { + childResult = resolveArray( + nestedArray, + linkSource: linkSource, + origin: origin + ).map { $0 as Any } + } else { + childResult = .success(child) + } + + if let value = childResult.value { + result.append(value) + } + if let childErrors = childResult.errorsOrWarnings { + errors + .append(contentsOf: childErrors.map { .nestedObjectError(field: "\(index)", error: $0) }) + } + } + + if let warnings = NonEmptyArray(errors) { + return .partialSuccess(result, warnings: warnings) + } + return .success(result) + } + + private mutating func resolveAny( + _ value: Any, + linkSource: [String: Any], + origin: Origin + ) -> DeserializationResult { + if let dictionary = value as? [String: Any] { + let childLinkSource = origin == .instance ? dictionary : linkSource + return resolveDictionary( + dictionary, + linkSource: childLinkSource, + origin: origin == .instance ? .instance : .template + ).map { $0 as Any } + } + if let array = value as? [Any] { + return resolveArray(array, linkSource: linkSource, origin: origin).map { $0 as Any } + } + return .success(value) + } + + private mutating func resolveTemplate(named templateName: TemplateName) + -> DeserializationResult<[String: Any]> { + if let cached = resolvedTemplateCache[templateName] { + return .success(cached) + } + + guard !currentlyResolvingTemplates.contains(templateName) else { + return .failure(NonEmptyArray(.unknownType(type: templateName))) + } + + guard let templateDict = templates[templateName] as? [String: Any] else { + return .failure(NonEmptyArray(.unknownType(type: templateName))) + } + + currentlyResolvingTemplates.insert(templateName) + defer { currentlyResolvingTemplates.remove(templateName) } + + var result: [String: Any] = [:] + + if let parentName = templateDict["type"] as? String, templates[parentName] != nil { + let parentResult = resolveTemplate(named: parentName) + guard let parentTemplate = parentResult.value else { + return .failure(normalizedErrors(from: parentResult.errorsOrWarnings)) + } + result = parentTemplate + } + + for (key, value) in templateDict { + result[key] = value + } + result["type"] = templateToType[templateName] ?? + (templateDict["type"] as? String ?? templateName) + + resolvedTemplateCache[templateName] = result + return .success(result) + } + + private func substituteLinks(values: inout [String: OriginValue], linkSource: [String: Any]) { + let linkValues = values.filter { $0.key.hasPrefix("$") } + for (linkKey, linkValue) in linkValues { + let key = String(linkKey.dropFirst()) + guard values[key] == nil else { continue } + guard let linkName = linkValue.value as? String else { continue } + guard let value = linkSource[linkName] else { continue } + values[key] = OriginValue(value: value, origin: .instance) + } + } +} + +private func normalizedErrors( + from errors: NonEmptyArray? +) -> NonEmptyArray { + errors ?? NonEmptyArray(.generic) +} + +extension DeserializationResult { + fileprivate func map(_ transform: (T) -> U) -> DeserializationResult { + switch self { + case let .success(value): + .success(transform(value)) + case let .partialSuccess(value, warnings): + .partialSuccess(transform(value), warnings: warnings) + case let .failure(errors): + .failure(errors) + case .noValue: + .noValue + } + } +} diff --git a/client/ios/DivKit/Views/DivBlockProvider.swift b/client/ios/DivKit/Views/DivBlockProvider.swift index ec2a58d33..163ab941d 100644 --- a/client/ios/DivKit/Views/DivBlockProvider.swift +++ b/client/ios/DivKit/Views/DivBlockProvider.swift @@ -305,13 +305,13 @@ final class DivBlockProvider { cardId: DivCardID ) throws -> DeserializationResult { let rawDivData = try RawDivData(dictionary: jsonDict) - let templates = try measurements.templateParsingTime.updateMeasure { - DivTemplates(dictionary: rawDivData.templates) - } return try measurements.divDataParsingTime.updateMeasure { - templates - .parseValue(type: DivDataTemplate.self, from: rawDivData.card) - .asCardResult(cardId: cardId) + DivData.resolve( + card: rawDivData.card, + templates: rawDivData.templates, + flagsInfo: divKitComponents.flagsInfo + ) + .asCardResult(cardId: cardId) } } @@ -321,16 +321,17 @@ final class DivBlockProvider { ) async throws -> DeserializationResult { let rawDivData = try RawDivData(dictionary: jsonDict) let measurements = measurements - let templates = try measurements.templateParsingTime.updateMeasure { - DivTemplates(dictionary: rawDivData.templates) - } + let flagsInfo = divKitComponents.flagsInfo let result = try await withCheckedThrowingContinuation { continuation in DispatchQueue.global().async { [measurements] in do { let result = try measurements.divDataParsingTime.updateMeasure { - templates - .parseValue(type: DivDataTemplate.self, from: rawDivData.card) - .asCardResult(cardId: cardId) + DivData.resolve( + card: rawDivData.card, + templates: rawDivData.templates, + flagsInfo: flagsInfo + ) + .asCardResult(cardId: cardId) } continuation.resume(returning: result) } catch { diff --git a/client/ios/DivKit/generated_sources/ArrayValue.swift b/client/ios/DivKit/generated_sources/ArrayValue.swift index 47017e57b..becbbcb1a 100644 --- a/client/ios/DivKit/generated_sources/ArrayValue.swift +++ b/client/ios/DivKit/generated_sources/ArrayValue.swift @@ -12,6 +12,12 @@ public final class ArrayValue: @unchecked Sendable { resolver.resolveArray(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( value: Expression<[Any]> ) { diff --git a/client/ios/DivKit/generated_sources/ArrayVariable.swift b/client/ios/DivKit/generated_sources/ArrayVariable.swift index 33037d2ad..af42abb49 100644 --- a/client/ios/DivKit/generated_sources/ArrayVariable.swift +++ b/client/ios/DivKit/generated_sources/ArrayVariable.swift @@ -13,6 +13,13 @@ public final class ArrayVariable: @unchecked Sendable { resolver.resolveArray(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + name: try dictionary.getField("name", context: context), + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( name: String, value: Expression<[Any]> diff --git a/client/ios/DivKit/generated_sources/BooleanValue.swift b/client/ios/DivKit/generated_sources/BooleanValue.swift index f32ddb16b..092bf5524 100644 --- a/client/ios/DivKit/generated_sources/BooleanValue.swift +++ b/client/ios/DivKit/generated_sources/BooleanValue.swift @@ -12,6 +12,12 @@ public final class BooleanValue: Sendable { resolver.resolveNumeric(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( value: Expression ) { diff --git a/client/ios/DivKit/generated_sources/BooleanVariable.swift b/client/ios/DivKit/generated_sources/BooleanVariable.swift index b2382e4e2..9ca749c35 100644 --- a/client/ios/DivKit/generated_sources/BooleanVariable.swift +++ b/client/ios/DivKit/generated_sources/BooleanVariable.swift @@ -13,6 +13,13 @@ public final class BooleanVariable: Sendable { resolver.resolveNumeric(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + name: try dictionary.getField("name", context: context), + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( name: String, value: Expression diff --git a/client/ios/DivKit/generated_sources/ColorValue.swift b/client/ios/DivKit/generated_sources/ColorValue.swift index 840f06cc4..8fb8f76e0 100644 --- a/client/ios/DivKit/generated_sources/ColorValue.swift +++ b/client/ios/DivKit/generated_sources/ColorValue.swift @@ -12,6 +12,12 @@ public final class ColorValue: Sendable { resolver.resolveColor(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", transform: Color.color(withHexString:), context: context) + ) + } + init( value: Expression ) { diff --git a/client/ios/DivKit/generated_sources/ColorVariable.swift b/client/ios/DivKit/generated_sources/ColorVariable.swift index c5cdb8c6c..fbf7e5163 100644 --- a/client/ios/DivKit/generated_sources/ColorVariable.swift +++ b/client/ios/DivKit/generated_sources/ColorVariable.swift @@ -13,6 +13,13 @@ public final class ColorVariable: Sendable { resolver.resolveColor(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + name: try dictionary.getField("name", context: context), + value: try dictionary.getExpressionField("value", transform: Color.color(withHexString:), context: context) + ) + } + init( name: String, value: Expression diff --git a/client/ios/DivKit/generated_sources/ContentText.swift b/client/ios/DivKit/generated_sources/ContentText.swift index 65be7678e..01a7a9094 100644 --- a/client/ios/DivKit/generated_sources/ContentText.swift +++ b/client/ios/DivKit/generated_sources/ContentText.swift @@ -12,6 +12,12 @@ public final class ContentText: Sendable { resolver.resolveString(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( value: Expression ) { diff --git a/client/ios/DivKit/generated_sources/ContentUrl.swift b/client/ios/DivKit/generated_sources/ContentUrl.swift index 70841ea44..1946641bc 100644 --- a/client/ios/DivKit/generated_sources/ContentUrl.swift +++ b/client/ios/DivKit/generated_sources/ContentUrl.swift @@ -12,6 +12,12 @@ public final class ContentUrl: Sendable { resolver.resolveUrl(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", transform: URL.makeFromNonEncodedString, context: context) + ) + } + init( value: Expression ) { diff --git a/client/ios/DivKit/generated_sources/DictValue.swift b/client/ios/DivKit/generated_sources/DictValue.swift index ec15fa824..0ce2ec480 100644 --- a/client/ios/DivKit/generated_sources/DictValue.swift +++ b/client/ios/DivKit/generated_sources/DictValue.swift @@ -12,6 +12,12 @@ public final class DictValue: @unchecked Sendable { resolver.resolveDict(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( value: Expression<[String: Any]> ) { diff --git a/client/ios/DivKit/generated_sources/DictVariable.swift b/client/ios/DivKit/generated_sources/DictVariable.swift index cda91d4b2..c2eef716a 100644 --- a/client/ios/DivKit/generated_sources/DictVariable.swift +++ b/client/ios/DivKit/generated_sources/DictVariable.swift @@ -13,6 +13,13 @@ public final class DictVariable: @unchecked Sendable { resolver.resolveDict(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + name: try dictionary.getField("name", context: context), + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( name: String, value: Expression<[String: Any]> diff --git a/client/ios/DivKit/generated_sources/Div.swift b/client/ios/DivKit/generated_sources/Div.swift index 58a3dff59..9fe652f03 100644 --- a/client/ios/DivKit/generated_sources/Div.swift +++ b/client/ios/DivKit/generated_sources/Div.swift @@ -103,6 +103,50 @@ public enum Div: Sendable { } } +extension Div { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivImage.type: + self = .divImage(try DivImage(dictionary: dictionary, context: context)) + case DivGifImage.type: + self = .divGifImage(try DivGifImage(dictionary: dictionary, context: context)) + case DivText.type: + self = .divText(try DivText(dictionary: dictionary, context: context)) + case DivSeparator.type: + self = .divSeparator(try DivSeparator(dictionary: dictionary, context: context)) + case DivContainer.type: + self = .divContainer(try DivContainer(dictionary: dictionary, context: context)) + case DivGrid.type: + self = .divGrid(try DivGrid(dictionary: dictionary, context: context)) + case DivGallery.type: + self = .divGallery(try DivGallery(dictionary: dictionary, context: context)) + case DivPager.type: + self = .divPager(try DivPager(dictionary: dictionary, context: context)) + case DivTabs.type: + self = .divTabs(try DivTabs(dictionary: dictionary, context: context)) + case DivState.type: + self = .divState(try DivState(dictionary: dictionary, context: context)) + case DivCustom.type: + self = .divCustom(try DivCustom(dictionary: dictionary, context: context)) + case DivIndicator.type: + self = .divIndicator(try DivIndicator(dictionary: dictionary, context: context)) + case DivSlider.type: + self = .divSlider(try DivSlider(dictionary: dictionary, context: context)) + case DivSwitch.type: + self = .divSwitch(try DivSwitch(dictionary: dictionary, context: context)) + case DivInput.type: + self = .divInput(try DivInput(dictionary: dictionary, context: context)) + case DivSelect.type: + self = .divSelect(try DivSelect(dictionary: dictionary, context: context)) + case DivVideo.type: + self = .divVideo(try DivVideo(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div", representation: dictionary) + } + } +} + #if DEBUG extension Div: Equatable { public static func ==(lhs: Div, rhs: Div) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivAbsoluteEdgeInsets.swift b/client/ios/DivKit/generated_sources/DivAbsoluteEdgeInsets.swift index 8faa65b11..4ed91e78e 100644 --- a/client/ios/DivKit/generated_sources/DivAbsoluteEdgeInsets.swift +++ b/client/ios/DivKit/generated_sources/DivAbsoluteEdgeInsets.swift @@ -38,6 +38,15 @@ public final class DivAbsoluteEdgeInsets: Sendable { static let topValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + bottom: try dictionary.getOptionalExpressionField("bottom", validator: Self.bottomValidator, context: context), + left: try dictionary.getOptionalExpressionField("left", validator: Self.leftValidator, context: context), + right: try dictionary.getOptionalExpressionField("right", validator: Self.rightValidator, context: context), + top: try dictionary.getOptionalExpressionField("top", validator: Self.topValidator, context: context) + ) + } + init( bottom: Expression? = nil, left: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivAccessibility.swift b/client/ios/DivKit/generated_sources/DivAccessibility.swift index c4a2dae0d..bccb9be31 100644 --- a/client/ios/DivKit/generated_sources/DivAccessibility.swift +++ b/client/ios/DivKit/generated_sources/DivAccessibility.swift @@ -60,6 +60,18 @@ public final class DivAccessibility: Sendable { resolver.resolveString(stateDescription) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + description: try dictionary.getOptionalExpressionField("description", context: context), + hint: try dictionary.getOptionalExpressionField("hint", context: context), + isChecked: try dictionary.getOptionalExpressionField("is_checked", context: context), + mode: try dictionary.getOptionalExpressionField("mode", context: context), + muteAfterAction: try dictionary.getOptionalExpressionField("mute_after_action", context: context), + stateDescription: try dictionary.getOptionalExpressionField("state_description", context: context), + type: try dictionary.getOptionalField("type", context: context) + ) + } + init( description: Expression? = nil, hint: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivAction.swift b/client/ios/DivKit/generated_sources/DivAction.swift index 656d63be4..fca050bc6 100644 --- a/client/ios/DivKit/generated_sources/DivAction.swift +++ b/client/ios/DivKit/generated_sources/DivAction.swift @@ -14,6 +14,14 @@ public final class DivAction: @unchecked Sendable { resolver.resolveString(text) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + action: try dictionary.getOptionalField("action", transform: { (dict: [String: Any]) in try DivAction(dictionary: dict, context: context) }), + actions: try dictionary.getOptionalArray("actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + text: try dictionary.getExpressionField("text", context: context) + ) + } + init( action: DivAction? = nil, actions: [DivAction]? = nil, @@ -56,6 +64,21 @@ public final class DivAction: @unchecked Sendable { resolver.resolveUrl(url) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + downloadCallbacks: try dictionary.getOptionalField("download_callbacks", transform: { (dict: [String: Any]) in try DivDownloadCallbacks(dictionary: dict, context: context) }), + isEnabled: try dictionary.getOptionalExpressionField("is_enabled", context: context), + logId: try dictionary.getExpressionField("log_id", context: context), + logUrl: try dictionary.getOptionalExpressionField("log_url", transform: URL.makeFromNonEncodedString, context: context), + menuItems: try dictionary.getOptionalArray("menu_items", transform: { (dict: [String: Any]) in try? DivAction.MenuItem(dictionary: dict, context: context) }), + payload: try dictionary.getOptionalField("payload", context: context), + referer: try dictionary.getOptionalExpressionField("referer", transform: URL.makeFromNonEncodedString, context: context), + scopeId: try dictionary.getOptionalField("scope_id", context: context), + typed: try dictionary.getOptionalField("typed", transform: { (dict: [String: Any]) in try DivActionTyped(dictionary: dict, context: context) }), + url: try dictionary.getOptionalExpressionField("url", transform: URL.makeFromNonEncodedString, context: context) + ) + } + init( downloadCallbacks: DivDownloadCallbacks? = nil, isEnabled: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivActionAnimatorStart.swift b/client/ios/DivKit/generated_sources/DivActionAnimatorStart.swift index 9c66004bb..758d01c94 100644 --- a/client/ios/DivKit/generated_sources/DivActionAnimatorStart.swift +++ b/client/ios/DivKit/generated_sources/DivActionAnimatorStart.swift @@ -37,6 +37,19 @@ public final class DivActionAnimatorStart: Sendable { static let startDelayValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + animatorId: try dictionary.getField("animator_id", context: context), + direction: try dictionary.getOptionalExpressionField("direction", context: context), + duration: try dictionary.getOptionalExpressionField("duration", validator: Self.durationValidator, context: context), + endValue: try dictionary.getOptionalField("end_value", transform: { (dict: [String: Any]) in try DivTypedValue(dictionary: dict, context: context) }), + interpolator: try dictionary.getOptionalExpressionField("interpolator", context: context), + repeatCount: try dictionary.getOptionalField("repeat_count", transform: { (dict: [String: Any]) in try DivCount(dictionary: dict, context: context) }), + startDelay: try dictionary.getOptionalExpressionField("start_delay", validator: Self.startDelayValidator, context: context), + startValue: try dictionary.getOptionalField("start_value", transform: { (dict: [String: Any]) in try DivTypedValue(dictionary: dict, context: context) }) + ) + } + init( animatorId: String, direction: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivActionAnimatorStop.swift b/client/ios/DivKit/generated_sources/DivActionAnimatorStop.swift index b777ed8af..1c0c634bd 100644 --- a/client/ios/DivKit/generated_sources/DivActionAnimatorStop.swift +++ b/client/ios/DivKit/generated_sources/DivActionAnimatorStop.swift @@ -8,6 +8,12 @@ public final class DivActionAnimatorStop: Sendable { public static let type: String = "animator_stop" public let animatorId: String + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + animatorId: try dictionary.getField("animator_id", context: context) + ) + } + init( animatorId: String ) { diff --git a/client/ios/DivKit/generated_sources/DivActionArrayInsertValue.swift b/client/ios/DivKit/generated_sources/DivActionArrayInsertValue.swift index d5df2d722..148343530 100644 --- a/client/ios/DivKit/generated_sources/DivActionArrayInsertValue.swift +++ b/client/ios/DivKit/generated_sources/DivActionArrayInsertValue.swift @@ -18,6 +18,14 @@ public final class DivActionArrayInsertValue: Sendable { resolver.resolveString(variableName) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + index: try dictionary.getOptionalExpressionField("index", context: context), + value: try dictionary.getField("value", transform: { (dict: [String: Any]) in try DivTypedValue(dictionary: dict, context: context) }), + variableName: try dictionary.getExpressionField("variable_name", context: context) + ) + } + init( index: Expression? = nil, value: DivTypedValue, diff --git a/client/ios/DivKit/generated_sources/DivActionArrayRemoveValue.swift b/client/ios/DivKit/generated_sources/DivActionArrayRemoveValue.swift index 23249c7a8..1524002be 100644 --- a/client/ios/DivKit/generated_sources/DivActionArrayRemoveValue.swift +++ b/client/ios/DivKit/generated_sources/DivActionArrayRemoveValue.swift @@ -17,6 +17,13 @@ public final class DivActionArrayRemoveValue: Sendable { resolver.resolveString(variableName) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + index: try dictionary.getExpressionField("index", context: context), + variableName: try dictionary.getExpressionField("variable_name", context: context) + ) + } + init( index: Expression, variableName: Expression diff --git a/client/ios/DivKit/generated_sources/DivActionArraySetValue.swift b/client/ios/DivKit/generated_sources/DivActionArraySetValue.swift index 3ce6ce737..d7c48b7b4 100644 --- a/client/ios/DivKit/generated_sources/DivActionArraySetValue.swift +++ b/client/ios/DivKit/generated_sources/DivActionArraySetValue.swift @@ -18,6 +18,14 @@ public final class DivActionArraySetValue: Sendable { resolver.resolveString(variableName) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + index: try dictionary.getExpressionField("index", context: context), + value: try dictionary.getField("value", transform: { (dict: [String: Any]) in try DivTypedValue(dictionary: dict, context: context) }), + variableName: try dictionary.getExpressionField("variable_name", context: context) + ) + } + init( index: Expression, value: DivTypedValue, diff --git a/client/ios/DivKit/generated_sources/DivActionClearFocus.swift b/client/ios/DivKit/generated_sources/DivActionClearFocus.swift index d7405b9c1..b7d1cb1de 100644 --- a/client/ios/DivKit/generated_sources/DivActionClearFocus.swift +++ b/client/ios/DivKit/generated_sources/DivActionClearFocus.swift @@ -7,6 +7,8 @@ import VGSL public final class DivActionClearFocus: Sendable { public static let type: String = "clear_focus" + public init(dictionary: [String: Any], context: ParsingContext) throws {} + init() {} } diff --git a/client/ios/DivKit/generated_sources/DivActionCopyToClipboard.swift b/client/ios/DivKit/generated_sources/DivActionCopyToClipboard.swift index d2d63cbaa..50503e212 100644 --- a/client/ios/DivKit/generated_sources/DivActionCopyToClipboard.swift +++ b/client/ios/DivKit/generated_sources/DivActionCopyToClipboard.swift @@ -8,6 +8,12 @@ public final class DivActionCopyToClipboard: Sendable { public static let type: String = "copy_to_clipboard" public let content: DivActionCopyToClipboardContent + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + content: try dictionary.getField("content", transform: { (dict: [String: Any]) in try DivActionCopyToClipboardContent(dictionary: dict, context: context) }) + ) + } + init( content: DivActionCopyToClipboardContent ) { diff --git a/client/ios/DivKit/generated_sources/DivActionCopyToClipboardContent.swift b/client/ios/DivKit/generated_sources/DivActionCopyToClipboardContent.swift index 9dc816c85..4566f14c8 100644 --- a/client/ios/DivKit/generated_sources/DivActionCopyToClipboardContent.swift +++ b/client/ios/DivKit/generated_sources/DivActionCopyToClipboardContent.swift @@ -19,6 +19,20 @@ public enum DivActionCopyToClipboardContent: Sendable { } } +extension DivActionCopyToClipboardContent { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case ContentText.type: + self = .contentText(try ContentText(dictionary: dictionary, context: context)) + case ContentUrl.type: + self = .contentUrl(try ContentUrl(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-action-copy-to-clipboard-content", representation: dictionary) + } + } +} + #if DEBUG extension DivActionCopyToClipboardContent: Equatable { public static func ==(lhs: DivActionCopyToClipboardContent, rhs: DivActionCopyToClipboardContent) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivActionCustom.swift b/client/ios/DivKit/generated_sources/DivActionCustom.swift index 21e059368..f0d1b59e2 100644 --- a/client/ios/DivKit/generated_sources/DivActionCustom.swift +++ b/client/ios/DivKit/generated_sources/DivActionCustom.swift @@ -7,6 +7,8 @@ import VGSL public final class DivActionCustom: Sendable { public static let type: String = "custom" + public init(dictionary: [String: Any], context: ParsingContext) throws {} + init() {} } diff --git a/client/ios/DivKit/generated_sources/DivActionDictSetValue.swift b/client/ios/DivKit/generated_sources/DivActionDictSetValue.swift index 737c75ea5..4e95b6eb9 100644 --- a/client/ios/DivKit/generated_sources/DivActionDictSetValue.swift +++ b/client/ios/DivKit/generated_sources/DivActionDictSetValue.swift @@ -18,6 +18,14 @@ public final class DivActionDictSetValue: Sendable { resolver.resolveString(variableName) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + key: try dictionary.getExpressionField("key", context: context), + value: try dictionary.getOptionalField("value", transform: { (dict: [String: Any]) in try DivTypedValue(dictionary: dict, context: context) }), + variableName: try dictionary.getExpressionField("variable_name", context: context) + ) + } + init( key: Expression, value: DivTypedValue? = nil, diff --git a/client/ios/DivKit/generated_sources/DivActionDownload.swift b/client/ios/DivKit/generated_sources/DivActionDownload.swift index a18b730df..161ac561d 100644 --- a/client/ios/DivKit/generated_sources/DivActionDownload.swift +++ b/client/ios/DivKit/generated_sources/DivActionDownload.swift @@ -14,6 +14,14 @@ public final class DivActionDownload: Sendable { resolver.resolveUrl(url) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + onFailActions: try dictionary.getOptionalArray("on_fail_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + onSuccessActions: try dictionary.getOptionalArray("on_success_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + url: try dictionary.getExpressionField("url", transform: URL.makeFromNonEncodedString, context: context) + ) + } + init( onFailActions: [DivAction]? = nil, onSuccessActions: [DivAction]? = nil, diff --git a/client/ios/DivKit/generated_sources/DivActionFocusElement.swift b/client/ios/DivKit/generated_sources/DivActionFocusElement.swift index 4f581fd12..c3ee7b6ee 100644 --- a/client/ios/DivKit/generated_sources/DivActionFocusElement.swift +++ b/client/ios/DivKit/generated_sources/DivActionFocusElement.swift @@ -12,6 +12,12 @@ public final class DivActionFocusElement: Sendable { resolver.resolveString(elementId) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + elementId: try dictionary.getExpressionField("element_id", context: context) + ) + } + init( elementId: Expression ) { diff --git a/client/ios/DivKit/generated_sources/DivActionHideTooltip.swift b/client/ios/DivKit/generated_sources/DivActionHideTooltip.swift index a149154ef..670d0ac7c 100644 --- a/client/ios/DivKit/generated_sources/DivActionHideTooltip.swift +++ b/client/ios/DivKit/generated_sources/DivActionHideTooltip.swift @@ -12,6 +12,12 @@ public final class DivActionHideTooltip: Sendable { resolver.resolveString(id) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + id: try dictionary.getExpressionField("id", context: context) + ) + } + init( id: Expression ) { diff --git a/client/ios/DivKit/generated_sources/DivActionScrollBy.swift b/client/ios/DivKit/generated_sources/DivActionScrollBy.swift index 71d92f2a8..961576181 100644 --- a/client/ios/DivKit/generated_sources/DivActionScrollBy.swift +++ b/client/ios/DivKit/generated_sources/DivActionScrollBy.swift @@ -38,6 +38,16 @@ public final class DivActionScrollBy: Sendable { resolver.resolveEnum(overflow) ?? Overflow.clamp } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + animated: try dictionary.getOptionalExpressionField("animated", context: context), + id: try dictionary.getExpressionField("id", context: context), + itemCount: try dictionary.getOptionalExpressionField("item_count", context: context), + offset: try dictionary.getOptionalExpressionField("offset", context: context), + overflow: try dictionary.getOptionalExpressionField("overflow", context: context) + ) + } + init( animated: Expression? = nil, id: Expression, diff --git a/client/ios/DivKit/generated_sources/DivActionScrollDestination.swift b/client/ios/DivKit/generated_sources/DivActionScrollDestination.swift index a57e8112f..94dbb0d46 100644 --- a/client/ios/DivKit/generated_sources/DivActionScrollDestination.swift +++ b/client/ios/DivKit/generated_sources/DivActionScrollDestination.swift @@ -25,6 +25,24 @@ public enum DivActionScrollDestination: Sendable { } } +extension DivActionScrollDestination { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case OffsetDestination.type: + self = .offsetDestination(try OffsetDestination(dictionary: dictionary, context: context)) + case IndexDestination.type: + self = .indexDestination(try IndexDestination(dictionary: dictionary, context: context)) + case StartDestination.type: + self = .startDestination(try StartDestination(dictionary: dictionary, context: context)) + case EndDestination.type: + self = .endDestination(try EndDestination(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-action-scroll-destination", representation: dictionary) + } + } +} + #if DEBUG extension DivActionScrollDestination: Equatable { public static func ==(lhs: DivActionScrollDestination, rhs: DivActionScrollDestination) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivActionScrollTo.swift b/client/ios/DivKit/generated_sources/DivActionScrollTo.swift index 6c114aae6..d3632f32b 100644 --- a/client/ios/DivKit/generated_sources/DivActionScrollTo.swift +++ b/client/ios/DivKit/generated_sources/DivActionScrollTo.swift @@ -18,6 +18,14 @@ public final class DivActionScrollTo: Sendable { resolver.resolveString(id) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + animated: try dictionary.getOptionalExpressionField("animated", context: context), + destination: try dictionary.getField("destination", transform: { (dict: [String: Any]) in try DivActionScrollDestination(dictionary: dict, context: context) }), + id: try dictionary.getExpressionField("id", context: context) + ) + } + init( animated: Expression? = nil, destination: DivActionScrollDestination, diff --git a/client/ios/DivKit/generated_sources/DivActionSetState.swift b/client/ios/DivKit/generated_sources/DivActionSetState.swift index 52c7776aa..efdbe5c41 100644 --- a/client/ios/DivKit/generated_sources/DivActionSetState.swift +++ b/client/ios/DivKit/generated_sources/DivActionSetState.swift @@ -17,6 +17,13 @@ public final class DivActionSetState: Sendable { resolver.resolveNumeric(temporary) ?? true } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + stateId: try dictionary.getExpressionField("state_id", context: context), + temporary: try dictionary.getOptionalExpressionField("temporary", context: context) + ) + } + init( stateId: Expression, temporary: Expression? = nil diff --git a/client/ios/DivKit/generated_sources/DivActionSetStoredValue.swift b/client/ios/DivKit/generated_sources/DivActionSetStoredValue.swift index 3420b4154..130f711b1 100644 --- a/client/ios/DivKit/generated_sources/DivActionSetStoredValue.swift +++ b/client/ios/DivKit/generated_sources/DivActionSetStoredValue.swift @@ -18,6 +18,14 @@ public final class DivActionSetStoredValue: Sendable { resolver.resolveString(name) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + lifetime: try dictionary.getExpressionField("lifetime", context: context), + name: try dictionary.getExpressionField("name", context: context), + value: try dictionary.getField("value", transform: { (dict: [String: Any]) in try DivTypedValue(dictionary: dict, context: context) }) + ) + } + init( lifetime: Expression, name: Expression, diff --git a/client/ios/DivKit/generated_sources/DivActionSetVariable.swift b/client/ios/DivKit/generated_sources/DivActionSetVariable.swift index 7bbe01c08..550d3dd1b 100644 --- a/client/ios/DivKit/generated_sources/DivActionSetVariable.swift +++ b/client/ios/DivKit/generated_sources/DivActionSetVariable.swift @@ -13,6 +13,13 @@ public final class DivActionSetVariable: Sendable { resolver.resolveString(variableName) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getField("value", transform: { (dict: [String: Any]) in try DivTypedValue(dictionary: dict, context: context) }), + variableName: try dictionary.getExpressionField("variable_name", context: context) + ) + } + init( value: DivTypedValue, variableName: Expression diff --git a/client/ios/DivKit/generated_sources/DivActionShowTooltip.swift b/client/ios/DivKit/generated_sources/DivActionShowTooltip.swift index 91997bc1d..f4118eb1f 100644 --- a/client/ios/DivKit/generated_sources/DivActionShowTooltip.swift +++ b/client/ios/DivKit/generated_sources/DivActionShowTooltip.swift @@ -17,6 +17,13 @@ public final class DivActionShowTooltip: Sendable { resolver.resolveNumeric(multiple) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + id: try dictionary.getExpressionField("id", context: context), + multiple: try dictionary.getOptionalExpressionField("multiple", context: context) + ) + } + init( id: Expression, multiple: Expression? = nil diff --git a/client/ios/DivKit/generated_sources/DivActionSubmit.swift b/client/ios/DivKit/generated_sources/DivActionSubmit.swift index 869a98c12..90404f0f2 100644 --- a/client/ios/DivKit/generated_sources/DivActionSubmit.swift +++ b/client/ios/DivKit/generated_sources/DivActionSubmit.swift @@ -29,6 +29,13 @@ public final class DivActionSubmit: Sendable { resolver.resolveString(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + name: try dictionary.getExpressionField("name", context: context), + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( name: Expression, value: Expression @@ -50,6 +57,14 @@ public final class DivActionSubmit: Sendable { resolver.resolveUrl(url) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + headers: try dictionary.getOptionalArray("headers", transform: { (dict: [String: Any]) in try? DivActionSubmit.Request.Header(dictionary: dict, context: context) }), + method: try dictionary.getOptionalExpressionField("method", context: context), + url: try dictionary.getExpressionField("url", transform: URL.makeFromNonEncodedString, context: context) + ) + } + init( headers: [Header]? = nil, method: Expression? = nil, @@ -71,6 +86,15 @@ public final class DivActionSubmit: Sendable { resolver.resolveString(containerId) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + containerId: try dictionary.getExpressionField("container_id", context: context), + onFailActions: try dictionary.getOptionalArray("on_fail_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + onSuccessActions: try dictionary.getOptionalArray("on_success_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + request: try dictionary.getField("request", transform: { (dict: [String: Any]) in try DivActionSubmit.Request(dictionary: dict, context: context) }) + ) + } + init( containerId: Expression, onFailActions: [DivAction]? = nil, diff --git a/client/ios/DivKit/generated_sources/DivActionTimer.swift b/client/ios/DivKit/generated_sources/DivActionTimer.swift index 7d84e7d47..38d2ddbcd 100644 --- a/client/ios/DivKit/generated_sources/DivActionTimer.swift +++ b/client/ios/DivKit/generated_sources/DivActionTimer.swift @@ -27,6 +27,13 @@ public final class DivActionTimer: Sendable { resolver.resolveString(id) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + action: try dictionary.getExpressionField("action", context: context), + id: try dictionary.getExpressionField("id", context: context) + ) + } + init( action: Expression, id: Expression diff --git a/client/ios/DivKit/generated_sources/DivActionTyped.swift b/client/ios/DivKit/generated_sources/DivActionTyped.swift index 0810eb5c1..1b40c687b 100644 --- a/client/ios/DivKit/generated_sources/DivActionTyped.swift +++ b/client/ios/DivKit/generated_sources/DivActionTyped.swift @@ -79,6 +79,60 @@ public enum DivActionTyped: Sendable { } } +extension DivActionTyped { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivActionAnimatorStart.type: + self = .divActionAnimatorStart(try DivActionAnimatorStart(dictionary: dictionary, context: context)) + case DivActionAnimatorStop.type: + self = .divActionAnimatorStop(try DivActionAnimatorStop(dictionary: dictionary, context: context)) + case DivActionArrayInsertValue.type: + self = .divActionArrayInsertValue(try DivActionArrayInsertValue(dictionary: dictionary, context: context)) + case DivActionArrayRemoveValue.type: + self = .divActionArrayRemoveValue(try DivActionArrayRemoveValue(dictionary: dictionary, context: context)) + case DivActionArraySetValue.type: + self = .divActionArraySetValue(try DivActionArraySetValue(dictionary: dictionary, context: context)) + case DivActionClearFocus.type: + self = .divActionClearFocus(try DivActionClearFocus(dictionary: dictionary, context: context)) + case DivActionCopyToClipboard.type: + self = .divActionCopyToClipboard(try DivActionCopyToClipboard(dictionary: dictionary, context: context)) + case DivActionDictSetValue.type: + self = .divActionDictSetValue(try DivActionDictSetValue(dictionary: dictionary, context: context)) + case DivActionDownload.type: + self = .divActionDownload(try DivActionDownload(dictionary: dictionary, context: context)) + case DivActionFocusElement.type: + self = .divActionFocusElement(try DivActionFocusElement(dictionary: dictionary, context: context)) + case DivActionHideTooltip.type: + self = .divActionHideTooltip(try DivActionHideTooltip(dictionary: dictionary, context: context)) + case DivActionScrollBy.type: + self = .divActionScrollBy(try DivActionScrollBy(dictionary: dictionary, context: context)) + case DivActionScrollTo.type: + self = .divActionScrollTo(try DivActionScrollTo(dictionary: dictionary, context: context)) + case DivActionSetState.type: + self = .divActionSetState(try DivActionSetState(dictionary: dictionary, context: context)) + case DivActionSetStoredValue.type: + self = .divActionSetStoredValue(try DivActionSetStoredValue(dictionary: dictionary, context: context)) + case DivActionSetVariable.type: + self = .divActionSetVariable(try DivActionSetVariable(dictionary: dictionary, context: context)) + case DivActionShowTooltip.type: + self = .divActionShowTooltip(try DivActionShowTooltip(dictionary: dictionary, context: context)) + case DivActionSubmit.type: + self = .divActionSubmit(try DivActionSubmit(dictionary: dictionary, context: context)) + case DivActionTimer.type: + self = .divActionTimer(try DivActionTimer(dictionary: dictionary, context: context)) + case DivActionUpdateStructure.type: + self = .divActionUpdateStructure(try DivActionUpdateStructure(dictionary: dictionary, context: context)) + case DivActionVideo.type: + self = .divActionVideo(try DivActionVideo(dictionary: dictionary, context: context)) + case DivActionCustom.type: + self = .divActionCustom(try DivActionCustom(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-action-typed", representation: dictionary) + } + } +} + #if DEBUG extension DivActionTyped: Equatable { public static func ==(lhs: DivActionTyped, rhs: DivActionTyped) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivActionUpdateStructure.swift b/client/ios/DivKit/generated_sources/DivActionUpdateStructure.swift index 6e2e98549..d97341e2d 100644 --- a/client/ios/DivKit/generated_sources/DivActionUpdateStructure.swift +++ b/client/ios/DivKit/generated_sources/DivActionUpdateStructure.swift @@ -21,6 +21,14 @@ public final class DivActionUpdateStructure: Sendable { static let pathValidator: AnyValueValidator = makeStringValidator(regex: "^(?!/)(.+)(?, value: DivTypedValue, diff --git a/client/ios/DivKit/generated_sources/DivActionVideo.swift b/client/ios/DivKit/generated_sources/DivActionVideo.swift index a29948af4..18a89cc42 100644 --- a/client/ios/DivKit/generated_sources/DivActionVideo.swift +++ b/client/ios/DivKit/generated_sources/DivActionVideo.swift @@ -23,6 +23,13 @@ public final class DivActionVideo: Sendable { resolver.resolveString(id) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + action: try dictionary.getExpressionField("action", context: context), + id: try dictionary.getExpressionField("id", context: context) + ) + } + init( action: Expression, id: Expression diff --git a/client/ios/DivKit/generated_sources/DivAnimation.swift b/client/ios/DivKit/generated_sources/DivAnimation.swift index 9ec7aa38e..085b16128 100644 --- a/client/ios/DivKit/generated_sources/DivAnimation.swift +++ b/client/ios/DivKit/generated_sources/DivAnimation.swift @@ -54,6 +54,19 @@ public final class DivAnimation: Sendable { static let startDelayValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + duration: try dictionary.getOptionalExpressionField("duration", validator: Self.durationValidator, context: context), + endValue: try dictionary.getOptionalExpressionField("end_value", context: context), + interpolator: try dictionary.getOptionalExpressionField("interpolator", context: context), + items: try dictionary.getOptionalArray("items", transform: { (dict: [String: Any]) in try? DivAnimation(dictionary: dict, context: context) }), + name: try dictionary.getExpressionField("name", context: context), + repeatCount: try dictionary.getOptionalField("repeat", transform: { (dict: [String: Any]) in try DivCount(dictionary: dict, context: context) }), + startDelay: try dictionary.getOptionalExpressionField("start_delay", validator: Self.startDelayValidator, context: context), + startValue: try dictionary.getOptionalExpressionField("start_value", context: context) + ) + } + init( duration: Expression? = nil, endValue: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivAnimator.swift b/client/ios/DivKit/generated_sources/DivAnimator.swift index c6cf795db..b9b31aa93 100644 --- a/client/ios/DivKit/generated_sources/DivAnimator.swift +++ b/client/ios/DivKit/generated_sources/DivAnimator.swift @@ -28,6 +28,20 @@ public enum DivAnimator: Sendable { } } +extension DivAnimator { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivColorAnimator.type: + self = .divColorAnimator(try DivColorAnimator(dictionary: dictionary, context: context)) + case DivNumberAnimator.type: + self = .divNumberAnimator(try DivNumberAnimator(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-animator", representation: dictionary) + } + } +} + #if DEBUG extension DivAnimator: Equatable { public static func ==(lhs: DivAnimator, rhs: DivAnimator) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivAppearanceSetTransition.swift b/client/ios/DivKit/generated_sources/DivAppearanceSetTransition.swift index fe33cb5b4..a0af64226 100644 --- a/client/ios/DivKit/generated_sources/DivAppearanceSetTransition.swift +++ b/client/ios/DivKit/generated_sources/DivAppearanceSetTransition.swift @@ -11,6 +11,12 @@ public final class DivAppearanceSetTransition: Sendable { static let itemsValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + items: try dictionary.getArray("items", transform: { (dict: [String: Any]) in try? DivAppearanceTransition(dictionary: dict, context: context) }, validator: Self.itemsValidator) + ) + } + init( items: [DivAppearanceTransition] ) { diff --git a/client/ios/DivKit/generated_sources/DivAppearanceTransition.swift b/client/ios/DivKit/generated_sources/DivAppearanceTransition.swift index 76d90ab52..725357ab3 100644 --- a/client/ios/DivKit/generated_sources/DivAppearanceTransition.swift +++ b/client/ios/DivKit/generated_sources/DivAppearanceTransition.swift @@ -25,6 +25,24 @@ public enum DivAppearanceTransition: Sendable { } } +extension DivAppearanceTransition { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivAppearanceSetTransition.type: + self = .divAppearanceSetTransition(try DivAppearanceSetTransition(dictionary: dictionary, context: context)) + case DivFadeTransition.type: + self = .divFadeTransition(try DivFadeTransition(dictionary: dictionary, context: context)) + case DivScaleTransition.type: + self = .divScaleTransition(try DivScaleTransition(dictionary: dictionary, context: context)) + case DivSlideTransition.type: + self = .divSlideTransition(try DivSlideTransition(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-appearance-transition", representation: dictionary) + } + } +} + #if DEBUG extension DivAppearanceTransition: Equatable { public static func ==(lhs: DivAppearanceTransition, rhs: DivAppearanceTransition) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivAspect.swift b/client/ios/DivKit/generated_sources/DivAspect.swift index 08b85617b..108d4ec15 100644 --- a/client/ios/DivKit/generated_sources/DivAspect.swift +++ b/client/ios/DivKit/generated_sources/DivAspect.swift @@ -14,6 +14,12 @@ public final class DivAspect: Sendable { static let ratioValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 > 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + ratio: try dictionary.getExpressionField("ratio", validator: Self.ratioValidator, context: context) + ) + } + init( ratio: Expression ) { diff --git a/client/ios/DivKit/generated_sources/DivBackground.swift b/client/ios/DivKit/generated_sources/DivBackground.swift index d9bfcfe98..4527e76c4 100644 --- a/client/ios/DivKit/generated_sources/DivBackground.swift +++ b/client/ios/DivKit/generated_sources/DivBackground.swift @@ -28,6 +28,26 @@ public enum DivBackground: Sendable { } } +extension DivBackground { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivLinearGradient.type: + self = .divLinearGradient(try DivLinearGradient(dictionary: dictionary, context: context)) + case DivRadialGradient.type: + self = .divRadialGradient(try DivRadialGradient(dictionary: dictionary, context: context)) + case DivImageBackground.type: + self = .divImageBackground(try DivImageBackground(dictionary: dictionary, context: context)) + case DivSolidBackground.type: + self = .divSolidBackground(try DivSolidBackground(dictionary: dictionary, context: context)) + case DivNinePatchBackground.type: + self = .divNinePatchBackground(try DivNinePatchBackground(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-background", representation: dictionary) + } + } +} + #if DEBUG extension DivBackground: Equatable { public static func ==(lhs: DivBackground, rhs: DivBackground) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivBlur.swift b/client/ios/DivKit/generated_sources/DivBlur.swift index 042038a5e..6f98b4738 100644 --- a/client/ios/DivKit/generated_sources/DivBlur.swift +++ b/client/ios/DivKit/generated_sources/DivBlur.swift @@ -15,6 +15,12 @@ public final class DivBlur: Sendable { static let radiusValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + radius: try dictionary.getExpressionField("radius", validator: Self.radiusValidator, context: context) + ) + } + init( radius: Expression ) { diff --git a/client/ios/DivKit/generated_sources/DivBorder.swift b/client/ios/DivKit/generated_sources/DivBorder.swift index 0d9123785..deb5d26d5 100644 --- a/client/ios/DivKit/generated_sources/DivBorder.swift +++ b/client/ios/DivKit/generated_sources/DivBorder.swift @@ -22,6 +22,16 @@ public final class DivBorder: Sendable { static let cornerRadiusValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + cornerRadius: try dictionary.getOptionalExpressionField("corner_radius", validator: Self.cornerRadiusValidator, context: context), + cornersRadius: try dictionary.getOptionalField("corners_radius", transform: { (dict: [String: Any]) in try DivCornersRadius(dictionary: dict, context: context) }), + hasShadow: try dictionary.getOptionalExpressionField("has_shadow", context: context), + shadow: try dictionary.getOptionalField("shadow", transform: { (dict: [String: Any]) in try DivShadow(dictionary: dict, context: context) }), + stroke: try dictionary.getOptionalField("stroke", transform: { (dict: [String: Any]) in try DivStroke(dictionary: dict, context: context) }) + ) + } + init( cornerRadius: Expression? = nil, cornersRadius: DivCornersRadius? = nil, diff --git a/client/ios/DivKit/generated_sources/DivChangeBoundsTransition.swift b/client/ios/DivKit/generated_sources/DivChangeBoundsTransition.swift index 6e811c5fb..5d3c5118c 100644 --- a/client/ios/DivKit/generated_sources/DivChangeBoundsTransition.swift +++ b/client/ios/DivKit/generated_sources/DivChangeBoundsTransition.swift @@ -28,6 +28,14 @@ public final class DivChangeBoundsTransition: DivTransitionBase, Sendable { static let startDelayValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + duration: try dictionary.getOptionalExpressionField("duration", validator: Self.durationValidator, context: context), + interpolator: try dictionary.getOptionalExpressionField("interpolator", context: context), + startDelay: try dictionary.getOptionalExpressionField("start_delay", validator: Self.startDelayValidator, context: context) + ) + } + init( duration: Expression? = nil, interpolator: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivChangeSetTransition.swift b/client/ios/DivKit/generated_sources/DivChangeSetTransition.swift index c5948adff..322e3c54b 100644 --- a/client/ios/DivKit/generated_sources/DivChangeSetTransition.swift +++ b/client/ios/DivKit/generated_sources/DivChangeSetTransition.swift @@ -11,6 +11,12 @@ public final class DivChangeSetTransition: Sendable { static let itemsValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + items: try dictionary.getArray("items", transform: { (dict: [String: Any]) in try? DivChangeTransition(dictionary: dict, context: context) }, validator: Self.itemsValidator) + ) + } + init( items: [DivChangeTransition] ) { diff --git a/client/ios/DivKit/generated_sources/DivChangeTransition.swift b/client/ios/DivKit/generated_sources/DivChangeTransition.swift index 439662575..a6cb5d43e 100644 --- a/client/ios/DivKit/generated_sources/DivChangeTransition.swift +++ b/client/ios/DivKit/generated_sources/DivChangeTransition.swift @@ -19,6 +19,20 @@ public enum DivChangeTransition: Sendable { } } +extension DivChangeTransition { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivChangeSetTransition.type: + self = .divChangeSetTransition(try DivChangeSetTransition(dictionary: dictionary, context: context)) + case DivChangeBoundsTransition.type: + self = .divChangeBoundsTransition(try DivChangeBoundsTransition(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-change-transition", representation: dictionary) + } + } +} + #if DEBUG extension DivChangeTransition: Equatable { public static func ==(lhs: DivChangeTransition, rhs: DivChangeTransition) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivCircleShape.swift b/client/ios/DivKit/generated_sources/DivCircleShape.swift index 1c8109d98..256a5d5b3 100644 --- a/client/ios/DivKit/generated_sources/DivCircleShape.swift +++ b/client/ios/DivKit/generated_sources/DivCircleShape.swift @@ -14,6 +14,14 @@ public final class DivCircleShape: Sendable { resolver.resolveColor(backgroundColor) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + backgroundColor: try dictionary.getOptionalExpressionField("background_color", transform: Color.color(withHexString:), context: context), + radius: try dictionary.getOptionalField("radius", transform: { (dict: [String: Any]) in try DivFixedSize(dictionary: dict, context: context) }), + stroke: try dictionary.getOptionalField("stroke", transform: { (dict: [String: Any]) in try DivStroke(dictionary: dict, context: context) }) + ) + } + init( backgroundColor: Expression? = nil, radius: DivFixedSize? = nil, diff --git a/client/ios/DivKit/generated_sources/DivCloudBackground.swift b/client/ios/DivKit/generated_sources/DivCloudBackground.swift index 2d06b59ac..1237399bc 100644 --- a/client/ios/DivKit/generated_sources/DivCloudBackground.swift +++ b/client/ios/DivKit/generated_sources/DivCloudBackground.swift @@ -21,6 +21,14 @@ public final class DivCloudBackground: Sendable { static let cornerRadiusValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + color: try dictionary.getExpressionField("color", transform: Color.color(withHexString:), context: context), + cornerRadius: try dictionary.getExpressionField("corner_radius", validator: Self.cornerRadiusValidator, context: context), + paddings: try dictionary.getOptionalField("paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }) + ) + } + init( color: Expression, cornerRadius: Expression, diff --git a/client/ios/DivKit/generated_sources/DivCollectionItemBuilder.swift b/client/ios/DivKit/generated_sources/DivCollectionItemBuilder.swift index 2e01de666..b5c2a0822 100644 --- a/client/ios/DivKit/generated_sources/DivCollectionItemBuilder.swift +++ b/client/ios/DivKit/generated_sources/DivCollectionItemBuilder.swift @@ -18,6 +18,14 @@ public final class DivCollectionItemBuilder: @unchecked Sendable { resolver.resolveNumeric(selector) ?? true } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + div: try dictionary.getField("div", transform: { (dict: [String: Any]) in try Div(dictionary: dict, context: context) }), + id: try dictionary.getOptionalExpressionField("id", context: context), + selector: try dictionary.getOptionalExpressionField("selector", context: context) + ) + } + init( div: Div, id: Expression? = nil, @@ -40,6 +48,14 @@ public final class DivCollectionItemBuilder: @unchecked Sendable { static let prototypesValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + data: try dictionary.getExpressionField("data", context: context), + dataElementName: try dictionary.getOptionalField("data_element_name", context: context), + prototypes: try dictionary.getArray("prototypes", transform: { (dict: [String: Any]) in try? DivCollectionItemBuilder.Prototype(dictionary: dict, context: context) }, validator: Self.prototypesValidator) + ) + } + init( data: Expression<[Any]>, dataElementName: String? = nil, diff --git a/client/ios/DivKit/generated_sources/DivColorAnimator.swift b/client/ios/DivKit/generated_sources/DivColorAnimator.swift index 2fbe7f2ec..8c50c468f 100644 --- a/client/ios/DivKit/generated_sources/DivColorAnimator.swift +++ b/client/ios/DivKit/generated_sources/DivColorAnimator.swift @@ -48,6 +48,22 @@ public final class DivColorAnimator: DivAnimatorBase, Sendable { static let startDelayValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + cancelActions: try dictionary.getOptionalArray("cancel_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + direction: try dictionary.getOptionalExpressionField("direction", context: context), + duration: try dictionary.getExpressionField("duration", validator: Self.durationValidator, context: context), + endActions: try dictionary.getOptionalArray("end_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + endValue: try dictionary.getExpressionField("end_value", transform: Color.color(withHexString:), context: context), + id: try dictionary.getField("id", context: context), + interpolator: try dictionary.getOptionalExpressionField("interpolator", context: context), + repeatCount: try dictionary.getOptionalField("repeat_count", transform: { (dict: [String: Any]) in try DivCount(dictionary: dict, context: context) }), + startDelay: try dictionary.getOptionalExpressionField("start_delay", validator: Self.startDelayValidator, context: context), + startValue: try dictionary.getOptionalExpressionField("start_value", transform: Color.color(withHexString:), context: context), + variableName: try dictionary.getField("variable_name", context: context) + ) + } + init( cancelActions: [DivAction]? = nil, direction: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivContainer.swift b/client/ios/DivKit/generated_sources/DivContainer.swift index c27289b1e..bd26fb5fd 100644 --- a/client/ios/DivKit/generated_sources/DivContainer.swift +++ b/client/ios/DivKit/generated_sources/DivContainer.swift @@ -37,6 +37,16 @@ public final class DivContainer: DivBase, Sendable { resolver.resolveNumeric(showBetween) ?? true } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + margins: try dictionary.getOptionalField("margins", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + showAtEnd: try dictionary.getOptionalExpressionField("show_at_end", context: context), + showAtStart: try dictionary.getOptionalExpressionField("show_at_start", context: context), + showBetween: try dictionary.getOptionalExpressionField("show_between", context: context), + style: try dictionary.getField("style", transform: { (dict: [String: Any]) in try DivDrawable(dictionary: dict, context: context) }) + ) + } + init( margins: DivEdgeInsets? = nil, showAtEnd: Expression? = nil, @@ -187,6 +197,66 @@ public final class DivContainer: DivBase, Sendable { static let transitionTriggersValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + accessibility: try dictionary.getOptionalField("accessibility", transform: { (dict: [String: Any]) in try DivAccessibility(dictionary: dict, context: context) }), + action: try dictionary.getOptionalField("action", transform: { (dict: [String: Any]) in try DivAction(dictionary: dict, context: context) }), + actionAnimation: try dictionary.getOptionalField("action_animation", transform: { (dict: [String: Any]) in try DivAnimation(dictionary: dict, context: context) }), + actions: try dictionary.getOptionalArray("actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + alignmentHorizontal: try dictionary.getOptionalExpressionField("alignment_horizontal", context: context), + alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical", context: context), + alpha: try dictionary.getOptionalExpressionField("alpha", validator: Self.alphaValidator, context: context), + animators: try dictionary.getOptionalArray("animators", transform: { (dict: [String: Any]) in try? DivAnimator(dictionary: dict, context: context) }), + aspect: try dictionary.getOptionalField("aspect", transform: { (dict: [String: Any]) in try DivAspect(dictionary: dict, context: context) }), + background: try dictionary.getOptionalArray("background", transform: { (dict: [String: Any]) in try? DivBackground(dictionary: dict, context: context) }), + border: try dictionary.getOptionalField("border", transform: { (dict: [String: Any]) in try DivBorder(dictionary: dict, context: context) }), + captureFocusOnAction: try dictionary.getOptionalExpressionField("capture_focus_on_action", context: context), + clipToBounds: try dictionary.getOptionalExpressionField("clip_to_bounds", context: context), + columnSpan: try dictionary.getOptionalExpressionField("column_span", validator: Self.columnSpanValidator, context: context), + contentAlignmentHorizontal: try dictionary.getOptionalExpressionField("content_alignment_horizontal", context: context), + contentAlignmentVertical: try dictionary.getOptionalExpressionField("content_alignment_vertical", context: context), + disappearActions: try dictionary.getOptionalArray("disappear_actions", transform: { (dict: [String: Any]) in try? DivDisappearAction(dictionary: dict, context: context) }), + doubletapActions: try dictionary.getOptionalArray("doubletap_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + extensions: try dictionary.getOptionalArray("extensions", transform: { (dict: [String: Any]) in try? DivExtension(dictionary: dict, context: context) }), + focus: try dictionary.getOptionalField("focus", transform: { (dict: [String: Any]) in try DivFocus(dictionary: dict, context: context) }), + functions: try dictionary.getOptionalArray("functions", transform: { (dict: [String: Any]) in try? DivFunction(dictionary: dict, context: context) }), + height: try dictionary.getOptionalField("height", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }), + hoverEndActions: try dictionary.getOptionalArray("hover_end_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + hoverStartActions: try dictionary.getOptionalArray("hover_start_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + id: try dictionary.getOptionalField("id", context: context), + itemBuilder: try dictionary.getOptionalField("item_builder", transform: { (dict: [String: Any]) in try DivCollectionItemBuilder(dictionary: dict, context: context) }), + itemSpacing: try dictionary.getOptionalExpressionField("item_spacing", validator: Self.itemSpacingValidator, context: context), + items: try dictionary.getOptionalArray("items", transform: { (dict: [String: Any]) in try? Div(dictionary: dict, context: context) }), + layoutMode: try dictionary.getOptionalExpressionField("layout_mode", context: context), + layoutProvider: try dictionary.getOptionalField("layout_provider", transform: { (dict: [String: Any]) in try DivLayoutProvider(dictionary: dict, context: context) }), + lineSeparator: try dictionary.getOptionalField("line_separator", transform: { (dict: [String: Any]) in try DivContainer.Separator(dictionary: dict, context: context) }), + lineSpacing: try dictionary.getOptionalExpressionField("line_spacing", validator: Self.lineSpacingValidator, context: context), + longtapActions: try dictionary.getOptionalArray("longtap_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + margins: try dictionary.getOptionalField("margins", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + orientation: try dictionary.getOptionalExpressionField("orientation", context: context), + paddings: try dictionary.getOptionalField("paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + pressEndActions: try dictionary.getOptionalArray("press_end_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + pressStartActions: try dictionary.getOptionalArray("press_start_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + reuseId: try dictionary.getOptionalExpressionField("reuse_id", context: context), + rowSpan: try dictionary.getOptionalExpressionField("row_span", validator: Self.rowSpanValidator, context: context), + selectedActions: try dictionary.getOptionalArray("selected_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + separator: try dictionary.getOptionalField("separator", transform: { (dict: [String: Any]) in try DivContainer.Separator(dictionary: dict, context: context) }), + tooltips: try dictionary.getOptionalArray("tooltips", transform: { (dict: [String: Any]) in try? DivTooltip(dictionary: dict, context: context) }), + transform: try dictionary.getOptionalField("transform", transform: { (dict: [String: Any]) in try DivTransform(dictionary: dict, context: context) }), + transformations: try dictionary.getOptionalArray("transformations", transform: { (dict: [String: Any]) in try? DivTransformation(dictionary: dict, context: context) }), + transitionChange: try dictionary.getOptionalField("transition_change", transform: { (dict: [String: Any]) in try DivChangeTransition(dictionary: dict, context: context) }), + transitionIn: try dictionary.getOptionalField("transition_in", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionOut: try dictionary.getOptionalField("transition_out", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionTriggers: try dictionary.getOptionalArray("transition_triggers", validator: Self.transitionTriggersValidator, context: context), + variableTriggers: try dictionary.getOptionalArray("variable_triggers", transform: { (dict: [String: Any]) in try? DivTrigger(dictionary: dict, context: context) }), + variables: try dictionary.getOptionalArray("variables", transform: { (dict: [String: Any]) in try? DivVariable(dictionary: dict, context: context) }), + visibility: try dictionary.getOptionalExpressionField("visibility", context: context), + visibilityAction: try dictionary.getOptionalField("visibility_action", transform: { (dict: [String: Any]) in try DivVisibilityAction(dictionary: dict, context: context) }), + visibilityActions: try dictionary.getOptionalArray("visibility_actions", transform: { (dict: [String: Any]) in try? DivVisibilityAction(dictionary: dict, context: context) }), + width: try dictionary.getOptionalField("width", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }) + ) + } + init( accessibility: DivAccessibility?, action: DivAction?, diff --git a/client/ios/DivKit/generated_sources/DivCornersRadius.swift b/client/ios/DivKit/generated_sources/DivCornersRadius.swift index 9e2f74d1c..34b4c05e1 100644 --- a/client/ios/DivKit/generated_sources/DivCornersRadius.swift +++ b/client/ios/DivKit/generated_sources/DivCornersRadius.swift @@ -38,6 +38,15 @@ public final class DivCornersRadius: Sendable { static let topRightValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + bottomLeft: try dictionary.getOptionalExpressionField("bottom-left", validator: Self.bottomLeftValidator, context: context), + bottomRight: try dictionary.getOptionalExpressionField("bottom-right", validator: Self.bottomRightValidator, context: context), + topLeft: try dictionary.getOptionalExpressionField("top-left", validator: Self.topLeftValidator, context: context), + topRight: try dictionary.getOptionalExpressionField("top-right", validator: Self.topRightValidator, context: context) + ) + } + init( bottomLeft: Expression? = nil, bottomRight: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivCount.swift b/client/ios/DivKit/generated_sources/DivCount.swift index bb779c94f..c446ccd59 100644 --- a/client/ios/DivKit/generated_sources/DivCount.swift +++ b/client/ios/DivKit/generated_sources/DivCount.swift @@ -19,6 +19,20 @@ public enum DivCount: Sendable { } } +extension DivCount { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivInfinityCount.type: + self = .divInfinityCount(try DivInfinityCount(dictionary: dictionary, context: context)) + case DivFixedCount.type: + self = .divFixedCount(try DivFixedCount(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-count", representation: dictionary) + } + } +} + #if DEBUG extension DivCount: Equatable { public static func ==(lhs: DivCount, rhs: DivCount) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivCurrencyInputMask.swift b/client/ios/DivKit/generated_sources/DivCurrencyInputMask.swift index d6461d2b3..265f9f2a4 100644 --- a/client/ios/DivKit/generated_sources/DivCurrencyInputMask.swift +++ b/client/ios/DivKit/generated_sources/DivCurrencyInputMask.swift @@ -13,6 +13,13 @@ public final class DivCurrencyInputMask: DivInputMaskBase, Sendable { resolver.resolveString(locale) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + locale: try dictionary.getOptionalExpressionField("locale", context: context), + rawTextVariable: try dictionary.getField("raw_text_variable", context: context) + ) + } + init( locale: Expression? = nil, rawTextVariable: String diff --git a/client/ios/DivKit/generated_sources/DivCustom.swift b/client/ios/DivKit/generated_sources/DivCustom.swift index ada74f22a..7db578630 100644 --- a/client/ios/DivKit/generated_sources/DivCustom.swift +++ b/client/ios/DivKit/generated_sources/DivCustom.swift @@ -83,6 +83,47 @@ public final class DivCustom: DivBase, @unchecked Sendable { static let transitionTriggersValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + accessibility: try dictionary.getOptionalField("accessibility", transform: { (dict: [String: Any]) in try DivAccessibility(dictionary: dict, context: context) }), + alignmentHorizontal: try dictionary.getOptionalExpressionField("alignment_horizontal", context: context), + alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical", context: context), + alpha: try dictionary.getOptionalExpressionField("alpha", validator: Self.alphaValidator, context: context), + animators: try dictionary.getOptionalArray("animators", transform: { (dict: [String: Any]) in try? DivAnimator(dictionary: dict, context: context) }), + background: try dictionary.getOptionalArray("background", transform: { (dict: [String: Any]) in try? DivBackground(dictionary: dict, context: context) }), + border: try dictionary.getOptionalField("border", transform: { (dict: [String: Any]) in try DivBorder(dictionary: dict, context: context) }), + columnSpan: try dictionary.getOptionalExpressionField("column_span", validator: Self.columnSpanValidator, context: context), + customProps: try dictionary.getOptionalField("custom_props", context: context), + customType: try dictionary.getField("custom_type", context: context), + disappearActions: try dictionary.getOptionalArray("disappear_actions", transform: { (dict: [String: Any]) in try? DivDisappearAction(dictionary: dict, context: context) }), + extensions: try dictionary.getOptionalArray("extensions", transform: { (dict: [String: Any]) in try? DivExtension(dictionary: dict, context: context) }), + focus: try dictionary.getOptionalField("focus", transform: { (dict: [String: Any]) in try DivFocus(dictionary: dict, context: context) }), + functions: try dictionary.getOptionalArray("functions", transform: { (dict: [String: Any]) in try? DivFunction(dictionary: dict, context: context) }), + height: try dictionary.getOptionalField("height", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }), + id: try dictionary.getOptionalField("id", context: context), + items: try dictionary.getOptionalArray("items", transform: { (dict: [String: Any]) in try? Div(dictionary: dict, context: context) }), + layoutProvider: try dictionary.getOptionalField("layout_provider", transform: { (dict: [String: Any]) in try DivLayoutProvider(dictionary: dict, context: context) }), + margins: try dictionary.getOptionalField("margins", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + paddings: try dictionary.getOptionalField("paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + reuseId: try dictionary.getOptionalExpressionField("reuse_id", context: context), + rowSpan: try dictionary.getOptionalExpressionField("row_span", validator: Self.rowSpanValidator, context: context), + selectedActions: try dictionary.getOptionalArray("selected_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + tooltips: try dictionary.getOptionalArray("tooltips", transform: { (dict: [String: Any]) in try? DivTooltip(dictionary: dict, context: context) }), + transform: try dictionary.getOptionalField("transform", transform: { (dict: [String: Any]) in try DivTransform(dictionary: dict, context: context) }), + transformations: try dictionary.getOptionalArray("transformations", transform: { (dict: [String: Any]) in try? DivTransformation(dictionary: dict, context: context) }), + transitionChange: try dictionary.getOptionalField("transition_change", transform: { (dict: [String: Any]) in try DivChangeTransition(dictionary: dict, context: context) }), + transitionIn: try dictionary.getOptionalField("transition_in", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionOut: try dictionary.getOptionalField("transition_out", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionTriggers: try dictionary.getOptionalArray("transition_triggers", validator: Self.transitionTriggersValidator, context: context), + variableTriggers: try dictionary.getOptionalArray("variable_triggers", transform: { (dict: [String: Any]) in try? DivTrigger(dictionary: dict, context: context) }), + variables: try dictionary.getOptionalArray("variables", transform: { (dict: [String: Any]) in try? DivVariable(dictionary: dict, context: context) }), + visibility: try dictionary.getOptionalExpressionField("visibility", context: context), + visibilityAction: try dictionary.getOptionalField("visibility_action", transform: { (dict: [String: Any]) in try DivVisibilityAction(dictionary: dict, context: context) }), + visibilityActions: try dictionary.getOptionalArray("visibility_actions", transform: { (dict: [String: Any]) in try? DivVisibilityAction(dictionary: dict, context: context) }), + width: try dictionary.getOptionalField("width", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }) + ) + } + init( accessibility: DivAccessibility? = nil, alignmentHorizontal: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivData.swift b/client/ios/DivKit/generated_sources/DivData.swift index 251309315..c540ff98f 100644 --- a/client/ios/DivKit/generated_sources/DivData.swift +++ b/client/ios/DivKit/generated_sources/DivData.swift @@ -9,6 +9,13 @@ public final class DivData: Sendable { public let div: Div public let stateId: Int + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + div: try dictionary.getField("div", transform: { (dict: [String: Any]) in try Div(dictionary: dict, context: context) }), + stateId: try dictionary.getField("state_id", context: context) + ) + } + init( div: Div, stateId: Int @@ -33,6 +40,18 @@ public final class DivData: Sendable { static let statesValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + functions: try dictionary.getOptionalArray("functions", transform: { (dict: [String: Any]) in try? DivFunction(dictionary: dict, context: context) }), + logId: try dictionary.getField("log_id", context: context), + states: try dictionary.getArray("states", transform: { (dict: [String: Any]) in try? DivData.State(dictionary: dict, context: context) }, validator: Self.statesValidator), + timers: try dictionary.getOptionalArray("timers", transform: { (dict: [String: Any]) in try? DivTimer(dictionary: dict, context: context) }), + transitionAnimationSelector: try dictionary.getOptionalExpressionField("transition_animation_selector", context: context), + variableTriggers: try dictionary.getOptionalArray("variable_triggers", transform: { (dict: [String: Any]) in try? DivTrigger(dictionary: dict, context: context) }), + variables: try dictionary.getOptionalArray("variables", transform: { (dict: [String: Any]) in try? DivVariable(dictionary: dict, context: context) }) + ) + } + init( functions: [DivFunction]?, logId: String, diff --git a/client/ios/DivKit/generated_sources/DivDefaultIndicatorItemPlacement.swift b/client/ios/DivKit/generated_sources/DivDefaultIndicatorItemPlacement.swift index 1fd577f0c..7fdee4eff 100644 --- a/client/ios/DivKit/generated_sources/DivDefaultIndicatorItemPlacement.swift +++ b/client/ios/DivKit/generated_sources/DivDefaultIndicatorItemPlacement.swift @@ -8,6 +8,12 @@ public final class DivDefaultIndicatorItemPlacement: Sendable { public static let type: String = "default" public let spaceBetweenCenters: DivFixedSize // default value: DivFixedSize(value: .value(15)) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + spaceBetweenCenters: try dictionary.getOptionalField("space_between_centers", transform: { (dict: [String: Any]) in try DivFixedSize(dictionary: dict, context: context) }) + ) + } + init( spaceBetweenCenters: DivFixedSize? = nil ) { diff --git a/client/ios/DivKit/generated_sources/DivDimension.swift b/client/ios/DivKit/generated_sources/DivDimension.swift index f7b42164d..27341c744 100644 --- a/client/ios/DivKit/generated_sources/DivDimension.swift +++ b/client/ios/DivKit/generated_sources/DivDimension.swift @@ -16,6 +16,13 @@ public final class DivDimension: Sendable { resolver.resolveNumeric(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + unit: try dictionary.getOptionalExpressionField("unit", context: context), + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( unit: Expression? = nil, value: Expression diff --git a/client/ios/DivKit/generated_sources/DivDisappearAction.swift b/client/ios/DivKit/generated_sources/DivDisappearAction.swift index 9579ca8fa..d90715adb 100644 --- a/client/ios/DivKit/generated_sources/DivDisappearAction.swift +++ b/client/ios/DivKit/generated_sources/DivDisappearAction.swift @@ -54,6 +54,22 @@ public final class DivDisappearAction: DivSightAction, @unchecked Sendable { static let visibilityPercentageValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 && $0 < 100 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + disappearDuration: try dictionary.getOptionalExpressionField("disappear_duration", validator: Self.disappearDurationValidator, context: context), + downloadCallbacks: try dictionary.getOptionalField("download_callbacks", transform: { (dict: [String: Any]) in try DivDownloadCallbacks(dictionary: dict, context: context) }), + isEnabled: try dictionary.getOptionalExpressionField("is_enabled", context: context), + logId: try dictionary.getExpressionField("log_id", context: context), + logLimit: try dictionary.getOptionalExpressionField("log_limit", validator: Self.logLimitValidator, context: context), + payload: try dictionary.getOptionalField("payload", context: context), + referer: try dictionary.getOptionalExpressionField("referer", transform: URL.makeFromNonEncodedString, context: context), + scopeId: try dictionary.getOptionalField("scope_id", context: context), + typed: try dictionary.getOptionalField("typed", transform: { (dict: [String: Any]) in try DivActionTyped(dictionary: dict, context: context) }), + url: try dictionary.getOptionalExpressionField("url", transform: URL.makeFromNonEncodedString, context: context), + visibilityPercentage: try dictionary.getOptionalExpressionField("visibility_percentage", validator: Self.visibilityPercentageValidator, context: context) + ) + } + init( disappearDuration: Expression? = nil, downloadCallbacks: DivDownloadCallbacks? = nil, diff --git a/client/ios/DivKit/generated_sources/DivDownloadCallbacks.swift b/client/ios/DivKit/generated_sources/DivDownloadCallbacks.swift index 4635c9ee2..b96cc3fee 100644 --- a/client/ios/DivKit/generated_sources/DivDownloadCallbacks.swift +++ b/client/ios/DivKit/generated_sources/DivDownloadCallbacks.swift @@ -8,6 +8,13 @@ public final class DivDownloadCallbacks: Sendable { public let onFailActions: [DivAction]? public let onSuccessActions: [DivAction]? + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + onFailActions: try dictionary.getOptionalArray("on_fail_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + onSuccessActions: try dictionary.getOptionalArray("on_success_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }) + ) + } + init( onFailActions: [DivAction]? = nil, onSuccessActions: [DivAction]? = nil diff --git a/client/ios/DivKit/generated_sources/DivDrawable.swift b/client/ios/DivKit/generated_sources/DivDrawable.swift index e5576a102..1a6f6db58 100644 --- a/client/ios/DivKit/generated_sources/DivDrawable.swift +++ b/client/ios/DivKit/generated_sources/DivDrawable.swift @@ -16,6 +16,18 @@ public enum DivDrawable: Sendable { } } +extension DivDrawable { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivShapeDrawable.type: + self = .divShapeDrawable(try DivShapeDrawable(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-drawable", representation: dictionary) + } + } +} + #if DEBUG extension DivDrawable: Equatable { public static func ==(lhs: DivDrawable, rhs: DivDrawable) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivEdgeInsets.swift b/client/ios/DivKit/generated_sources/DivEdgeInsets.swift index be09126de..b5a6bab68 100644 --- a/client/ios/DivKit/generated_sources/DivEdgeInsets.swift +++ b/client/ios/DivKit/generated_sources/DivEdgeInsets.swift @@ -59,6 +59,18 @@ public final class DivEdgeInsets: Sendable { static let topValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + bottom: try dictionary.getOptionalExpressionField("bottom", validator: Self.bottomValidator, context: context), + end: try dictionary.getOptionalExpressionField("end", validator: Self.endValidator, context: context), + left: try dictionary.getOptionalExpressionField("left", validator: Self.leftValidator, context: context), + right: try dictionary.getOptionalExpressionField("right", validator: Self.rightValidator, context: context), + start: try dictionary.getOptionalExpressionField("start", validator: Self.startValidator, context: context), + top: try dictionary.getOptionalExpressionField("top", validator: Self.topValidator, context: context), + unit: try dictionary.getOptionalExpressionField("unit", context: context) + ) + } + init( bottom: Expression? = nil, end: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivExtension.swift b/client/ios/DivKit/generated_sources/DivExtension.swift index 96e36fc9d..5eb57a628 100644 --- a/client/ios/DivKit/generated_sources/DivExtension.swift +++ b/client/ios/DivKit/generated_sources/DivExtension.swift @@ -8,6 +8,13 @@ public final class DivExtension: @unchecked Sendable { public let id: String public let params: [String: Any]? + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + id: try dictionary.getField("id", context: context), + params: try dictionary.getOptionalField("params", context: context) + ) + } + init( id: String, params: [String: Any]? = nil diff --git a/client/ios/DivKit/generated_sources/DivFadeTransition.swift b/client/ios/DivKit/generated_sources/DivFadeTransition.swift index 568c09048..4db8dc45d 100644 --- a/client/ios/DivKit/generated_sources/DivFadeTransition.swift +++ b/client/ios/DivKit/generated_sources/DivFadeTransition.swift @@ -36,6 +36,15 @@ public final class DivFadeTransition: DivTransitionBase, Sendable { static let startDelayValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + alpha: try dictionary.getOptionalExpressionField("alpha", validator: Self.alphaValidator, context: context), + duration: try dictionary.getOptionalExpressionField("duration", validator: Self.durationValidator, context: context), + interpolator: try dictionary.getOptionalExpressionField("interpolator", context: context), + startDelay: try dictionary.getOptionalExpressionField("start_delay", validator: Self.startDelayValidator, context: context) + ) + } + init( alpha: Expression? = nil, duration: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivFilter.swift b/client/ios/DivKit/generated_sources/DivFilter.swift index d54b0a101..4021e43ef 100644 --- a/client/ios/DivKit/generated_sources/DivFilter.swift +++ b/client/ios/DivKit/generated_sources/DivFilter.swift @@ -19,6 +19,20 @@ public enum DivFilter: Sendable { } } +extension DivFilter { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivBlur.type: + self = .divBlur(try DivBlur(dictionary: dictionary, context: context)) + case DivFilterRtlMirror.type: + self = .divFilterRtlMirror(try DivFilterRtlMirror(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-filter", representation: dictionary) + } + } +} + #if DEBUG extension DivFilter: Equatable { public static func ==(lhs: DivFilter, rhs: DivFilter) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivFilterRtlMirror.swift b/client/ios/DivKit/generated_sources/DivFilterRtlMirror.swift index 8913238e3..4d2af340a 100644 --- a/client/ios/DivKit/generated_sources/DivFilterRtlMirror.swift +++ b/client/ios/DivKit/generated_sources/DivFilterRtlMirror.swift @@ -7,6 +7,8 @@ import VGSL public final class DivFilterRtlMirror: Sendable { public static let type: String = "rtl_mirror" + public init(dictionary: [String: Any], context: ParsingContext) throws {} + init() {} } diff --git a/client/ios/DivKit/generated_sources/DivFixedCount.swift b/client/ios/DivKit/generated_sources/DivFixedCount.swift index ae12286b3..7df013e55 100644 --- a/client/ios/DivKit/generated_sources/DivFixedCount.swift +++ b/client/ios/DivKit/generated_sources/DivFixedCount.swift @@ -15,6 +15,12 @@ public final class DivFixedCount: Sendable { static let valueValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", validator: Self.valueValidator, context: context) + ) + } + init( value: Expression ) { diff --git a/client/ios/DivKit/generated_sources/DivFixedLengthInputMask.swift b/client/ios/DivKit/generated_sources/DivFixedLengthInputMask.swift index 946f16c2e..30ae76084 100644 --- a/client/ios/DivKit/generated_sources/DivFixedLengthInputMask.swift +++ b/client/ios/DivKit/generated_sources/DivFixedLengthInputMask.swift @@ -28,6 +28,14 @@ public final class DivFixedLengthInputMask: DivInputMaskBase, Sendable { static let placeholderValidator: AnyValueValidator = makeStringValidator(minLength: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + key: try dictionary.getExpressionField("key", validator: Self.keyValidator, context: context), + placeholder: try dictionary.getOptionalExpressionField("placeholder", validator: Self.placeholderValidator, context: context), + regex: try dictionary.getOptionalExpressionField("regex", context: context) + ) + } + init( key: Expression, placeholder: Expression? = nil, @@ -56,6 +64,15 @@ public final class DivFixedLengthInputMask: DivInputMaskBase, Sendable { static let patternElementsValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + alwaysVisible: try dictionary.getOptionalExpressionField("always_visible", context: context), + pattern: try dictionary.getExpressionField("pattern", context: context), + patternElements: try dictionary.getArray("pattern_elements", transform: { (dict: [String: Any]) in try? DivFixedLengthInputMask.PatternElement(dictionary: dict, context: context) }, validator: Self.patternElementsValidator), + rawTextVariable: try dictionary.getField("raw_text_variable", context: context) + ) + } + init( alwaysVisible: Expression? = nil, pattern: Expression, diff --git a/client/ios/DivKit/generated_sources/DivFixedSize.swift b/client/ios/DivKit/generated_sources/DivFixedSize.swift index 57d731133..19c488e71 100644 --- a/client/ios/DivKit/generated_sources/DivFixedSize.swift +++ b/client/ios/DivKit/generated_sources/DivFixedSize.swift @@ -20,6 +20,13 @@ public final class DivFixedSize: Sendable { static let valueValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + unit: try dictionary.getOptionalExpressionField("unit", context: context), + value: try dictionary.getExpressionField("value", validator: Self.valueValidator, context: context) + ) + } + init( unit: Expression? = nil, value: Expression diff --git a/client/ios/DivKit/generated_sources/DivFixedTranslation.swift b/client/ios/DivKit/generated_sources/DivFixedTranslation.swift index 78b221e8e..93cb23de6 100644 --- a/client/ios/DivKit/generated_sources/DivFixedTranslation.swift +++ b/client/ios/DivKit/generated_sources/DivFixedTranslation.swift @@ -17,6 +17,13 @@ public final class DivFixedTranslation: Sendable { resolver.resolveNumeric(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + unit: try dictionary.getOptionalExpressionField("unit", context: context), + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( unit: Expression? = nil, value: Expression diff --git a/client/ios/DivKit/generated_sources/DivFocus.swift b/client/ios/DivKit/generated_sources/DivFocus.swift index cd9715180..b20a40484 100644 --- a/client/ios/DivKit/generated_sources/DivFocus.swift +++ b/client/ios/DivKit/generated_sources/DivFocus.swift @@ -32,6 +32,16 @@ public final class DivFocus: Sendable { resolver.resolveString(up) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + down: try dictionary.getOptionalExpressionField("down", context: context), + forward: try dictionary.getOptionalExpressionField("forward", context: context), + left: try dictionary.getOptionalExpressionField("left", context: context), + right: try dictionary.getOptionalExpressionField("right", context: context), + up: try dictionary.getOptionalExpressionField("up", context: context) + ) + } + init( down: Expression? = nil, forward: Expression? = nil, @@ -53,6 +63,16 @@ public final class DivFocus: Sendable { public let onBlur: [DivAction]? public let onFocus: [DivAction]? + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + background: try dictionary.getOptionalArray("background", transform: { (dict: [String: Any]) in try? DivBackground(dictionary: dict, context: context) }), + border: try dictionary.getOptionalField("border", transform: { (dict: [String: Any]) in try DivBorder(dictionary: dict, context: context) }), + nextFocusIds: try dictionary.getOptionalField("next_focus_ids", transform: { (dict: [String: Any]) in try DivFocus.NextFocusIds(dictionary: dict, context: context) }), + onBlur: try dictionary.getOptionalArray("on_blur", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + onFocus: try dictionary.getOptionalArray("on_focus", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }) + ) + } + init( background: [DivBackground]? = nil, border: DivBorder? = nil, diff --git a/client/ios/DivKit/generated_sources/DivFunction.swift b/client/ios/DivKit/generated_sources/DivFunction.swift index 39da051c9..19b4a6112 100644 --- a/client/ios/DivKit/generated_sources/DivFunction.swift +++ b/client/ios/DivKit/generated_sources/DivFunction.swift @@ -13,6 +13,15 @@ public final class DivFunction: Sendable { static let nameValidator: AnyValueValidator = makeStringValidator(regex: "^[a-zA-Z_][a-zA-Z0-9_]*$") + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + arguments: try dictionary.getArray("arguments", transform: { (dict: [String: Any]) in try? DivFunctionArgument(dictionary: dict, context: context) }), + body: try dictionary.getField("body", context: context), + name: try dictionary.getField("name", validator: Self.nameValidator, context: context), + returnType: try dictionary.getField("return_type", context: context) + ) + } + init( arguments: [DivFunctionArgument], body: String, diff --git a/client/ios/DivKit/generated_sources/DivFunctionArgument.swift b/client/ios/DivKit/generated_sources/DivFunctionArgument.swift index 7c45ddf13..223029d65 100644 --- a/client/ios/DivKit/generated_sources/DivFunctionArgument.swift +++ b/client/ios/DivKit/generated_sources/DivFunctionArgument.swift @@ -8,6 +8,13 @@ public final class DivFunctionArgument: Sendable { public let name: String public let type: DivEvaluableType + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + name: try dictionary.getField("name", context: context), + type: try dictionary.getField("type", context: context) + ) + } + init( name: String, type: DivEvaluableType diff --git a/client/ios/DivKit/generated_sources/DivGallery.swift b/client/ios/DivKit/generated_sources/DivGallery.swift index 470341509..7841af39e 100644 --- a/client/ios/DivKit/generated_sources/DivGallery.swift +++ b/client/ios/DivKit/generated_sources/DivGallery.swift @@ -164,6 +164,55 @@ public final class DivGallery: DivBase, Sendable { static let transitionTriggersValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + accessibility: try dictionary.getOptionalField("accessibility", transform: { (dict: [String: Any]) in try DivAccessibility(dictionary: dict, context: context) }), + alignmentHorizontal: try dictionary.getOptionalExpressionField("alignment_horizontal", context: context), + alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical", context: context), + alpha: try dictionary.getOptionalExpressionField("alpha", validator: Self.alphaValidator, context: context), + animators: try dictionary.getOptionalArray("animators", transform: { (dict: [String: Any]) in try? DivAnimator(dictionary: dict, context: context) }), + background: try dictionary.getOptionalArray("background", transform: { (dict: [String: Any]) in try? DivBackground(dictionary: dict, context: context) }), + border: try dictionary.getOptionalField("border", transform: { (dict: [String: Any]) in try DivBorder(dictionary: dict, context: context) }), + columnCount: try dictionary.getOptionalExpressionField("column_count", validator: Self.columnCountValidator, context: context), + columnSpan: try dictionary.getOptionalExpressionField("column_span", validator: Self.columnSpanValidator, context: context), + crossContentAlignment: try dictionary.getOptionalExpressionField("cross_content_alignment", context: context), + crossSpacing: try dictionary.getOptionalExpressionField("cross_spacing", validator: Self.crossSpacingValidator, context: context), + defaultItem: try dictionary.getOptionalExpressionField("default_item", validator: Self.defaultItemValidator, context: context), + disappearActions: try dictionary.getOptionalArray("disappear_actions", transform: { (dict: [String: Any]) in try? DivDisappearAction(dictionary: dict, context: context) }), + extensions: try dictionary.getOptionalArray("extensions", transform: { (dict: [String: Any]) in try? DivExtension(dictionary: dict, context: context) }), + focus: try dictionary.getOptionalField("focus", transform: { (dict: [String: Any]) in try DivFocus(dictionary: dict, context: context) }), + functions: try dictionary.getOptionalArray("functions", transform: { (dict: [String: Any]) in try? DivFunction(dictionary: dict, context: context) }), + height: try dictionary.getOptionalField("height", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }), + id: try dictionary.getOptionalField("id", context: context), + itemBuilder: try dictionary.getOptionalField("item_builder", transform: { (dict: [String: Any]) in try DivCollectionItemBuilder(dictionary: dict, context: context) }), + itemSpacing: try dictionary.getOptionalExpressionField("item_spacing", validator: Self.itemSpacingValidator, context: context), + items: try dictionary.getOptionalArray("items", transform: { (dict: [String: Any]) in try? Div(dictionary: dict, context: context) }), + layoutProvider: try dictionary.getOptionalField("layout_provider", transform: { (dict: [String: Any]) in try DivLayoutProvider(dictionary: dict, context: context) }), + margins: try dictionary.getOptionalField("margins", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + orientation: try dictionary.getOptionalExpressionField("orientation", context: context), + paddings: try dictionary.getOptionalField("paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + restrictParentScroll: try dictionary.getOptionalExpressionField("restrict_parent_scroll", context: context), + reuseId: try dictionary.getOptionalExpressionField("reuse_id", context: context), + rowSpan: try dictionary.getOptionalExpressionField("row_span", validator: Self.rowSpanValidator, context: context), + scrollMode: try dictionary.getOptionalExpressionField("scroll_mode", context: context), + scrollbar: try dictionary.getOptionalExpressionField("scrollbar", context: context), + selectedActions: try dictionary.getOptionalArray("selected_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + tooltips: try dictionary.getOptionalArray("tooltips", transform: { (dict: [String: Any]) in try? DivTooltip(dictionary: dict, context: context) }), + transform: try dictionary.getOptionalField("transform", transform: { (dict: [String: Any]) in try DivTransform(dictionary: dict, context: context) }), + transformations: try dictionary.getOptionalArray("transformations", transform: { (dict: [String: Any]) in try? DivTransformation(dictionary: dict, context: context) }), + transitionChange: try dictionary.getOptionalField("transition_change", transform: { (dict: [String: Any]) in try DivChangeTransition(dictionary: dict, context: context) }), + transitionIn: try dictionary.getOptionalField("transition_in", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionOut: try dictionary.getOptionalField("transition_out", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionTriggers: try dictionary.getOptionalArray("transition_triggers", validator: Self.transitionTriggersValidator, context: context), + variableTriggers: try dictionary.getOptionalArray("variable_triggers", transform: { (dict: [String: Any]) in try? DivTrigger(dictionary: dict, context: context) }), + variables: try dictionary.getOptionalArray("variables", transform: { (dict: [String: Any]) in try? DivVariable(dictionary: dict, context: context) }), + visibility: try dictionary.getOptionalExpressionField("visibility", context: context), + visibilityAction: try dictionary.getOptionalField("visibility_action", transform: { (dict: [String: Any]) in try DivVisibilityAction(dictionary: dict, context: context) }), + visibilityActions: try dictionary.getOptionalArray("visibility_actions", transform: { (dict: [String: Any]) in try? DivVisibilityAction(dictionary: dict, context: context) }), + width: try dictionary.getOptionalField("width", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }) + ) + } + init( accessibility: DivAccessibility?, alignmentHorizontal: Expression?, diff --git a/client/ios/DivKit/generated_sources/DivGifImage.swift b/client/ios/DivKit/generated_sources/DivGifImage.swift index efacd7791..1944ae129 100644 --- a/client/ios/DivKit/generated_sources/DivGifImage.swift +++ b/client/ios/DivKit/generated_sources/DivGifImage.swift @@ -135,6 +135,63 @@ public final class DivGifImage: DivBase, Sendable { static let transitionTriggersValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + accessibility: try dictionary.getOptionalField("accessibility", transform: { (dict: [String: Any]) in try DivAccessibility(dictionary: dict, context: context) }), + action: try dictionary.getOptionalField("action", transform: { (dict: [String: Any]) in try DivAction(dictionary: dict, context: context) }), + actionAnimation: try dictionary.getOptionalField("action_animation", transform: { (dict: [String: Any]) in try DivAnimation(dictionary: dict, context: context) }), + actions: try dictionary.getOptionalArray("actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + alignmentHorizontal: try dictionary.getOptionalExpressionField("alignment_horizontal", context: context), + alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical", context: context), + alpha: try dictionary.getOptionalExpressionField("alpha", validator: Self.alphaValidator, context: context), + animators: try dictionary.getOptionalArray("animators", transform: { (dict: [String: Any]) in try? DivAnimator(dictionary: dict, context: context) }), + aspect: try dictionary.getOptionalField("aspect", transform: { (dict: [String: Any]) in try DivAspect(dictionary: dict, context: context) }), + background: try dictionary.getOptionalArray("background", transform: { (dict: [String: Any]) in try? DivBackground(dictionary: dict, context: context) }), + border: try dictionary.getOptionalField("border", transform: { (dict: [String: Any]) in try DivBorder(dictionary: dict, context: context) }), + captureFocusOnAction: try dictionary.getOptionalExpressionField("capture_focus_on_action", context: context), + columnSpan: try dictionary.getOptionalExpressionField("column_span", validator: Self.columnSpanValidator, context: context), + contentAlignmentHorizontal: try dictionary.getOptionalExpressionField("content_alignment_horizontal", context: context), + contentAlignmentVertical: try dictionary.getOptionalExpressionField("content_alignment_vertical", context: context), + disappearActions: try dictionary.getOptionalArray("disappear_actions", transform: { (dict: [String: Any]) in try? DivDisappearAction(dictionary: dict, context: context) }), + doubletapActions: try dictionary.getOptionalArray("doubletap_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + extensions: try dictionary.getOptionalArray("extensions", transform: { (dict: [String: Any]) in try? DivExtension(dictionary: dict, context: context) }), + focus: try dictionary.getOptionalField("focus", transform: { (dict: [String: Any]) in try DivFocus(dictionary: dict, context: context) }), + functions: try dictionary.getOptionalArray("functions", transform: { (dict: [String: Any]) in try? DivFunction(dictionary: dict, context: context) }), + gifUrl: try dictionary.getExpressionField("gif_url", transform: URL.makeFromNonEncodedString, context: context), + height: try dictionary.getOptionalField("height", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }), + hoverEndActions: try dictionary.getOptionalArray("hover_end_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + hoverStartActions: try dictionary.getOptionalArray("hover_start_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + id: try dictionary.getOptionalField("id", context: context), + layoutProvider: try dictionary.getOptionalField("layout_provider", transform: { (dict: [String: Any]) in try DivLayoutProvider(dictionary: dict, context: context) }), + longtapActions: try dictionary.getOptionalArray("longtap_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + margins: try dictionary.getOptionalField("margins", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + paddings: try dictionary.getOptionalField("paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + placeholderColor: try dictionary.getOptionalExpressionField("placeholder_color", transform: Color.color(withHexString:), context: context), + preloadRequired: try dictionary.getOptionalExpressionField("preload_required", context: context), + pressEndActions: try dictionary.getOptionalArray("press_end_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + pressStartActions: try dictionary.getOptionalArray("press_start_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + preview: try dictionary.getOptionalExpressionField("preview", context: context), + previewUrl: try dictionary.getOptionalExpressionField("preview_url", transform: URL.makeFromNonEncodedString, context: context), + reuseId: try dictionary.getOptionalExpressionField("reuse_id", context: context), + rowSpan: try dictionary.getOptionalExpressionField("row_span", validator: Self.rowSpanValidator, context: context), + scale: try dictionary.getOptionalExpressionField("scale", context: context), + selectedActions: try dictionary.getOptionalArray("selected_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + tooltips: try dictionary.getOptionalArray("tooltips", transform: { (dict: [String: Any]) in try? DivTooltip(dictionary: dict, context: context) }), + transform: try dictionary.getOptionalField("transform", transform: { (dict: [String: Any]) in try DivTransform(dictionary: dict, context: context) }), + transformations: try dictionary.getOptionalArray("transformations", transform: { (dict: [String: Any]) in try? DivTransformation(dictionary: dict, context: context) }), + transitionChange: try dictionary.getOptionalField("transition_change", transform: { (dict: [String: Any]) in try DivChangeTransition(dictionary: dict, context: context) }), + transitionIn: try dictionary.getOptionalField("transition_in", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionOut: try dictionary.getOptionalField("transition_out", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionTriggers: try dictionary.getOptionalArray("transition_triggers", validator: Self.transitionTriggersValidator, context: context), + variableTriggers: try dictionary.getOptionalArray("variable_triggers", transform: { (dict: [String: Any]) in try? DivTrigger(dictionary: dict, context: context) }), + variables: try dictionary.getOptionalArray("variables", transform: { (dict: [String: Any]) in try? DivVariable(dictionary: dict, context: context) }), + visibility: try dictionary.getOptionalExpressionField("visibility", context: context), + visibilityAction: try dictionary.getOptionalField("visibility_action", transform: { (dict: [String: Any]) in try DivVisibilityAction(dictionary: dict, context: context) }), + visibilityActions: try dictionary.getOptionalArray("visibility_actions", transform: { (dict: [String: Any]) in try? DivVisibilityAction(dictionary: dict, context: context) }), + width: try dictionary.getOptionalField("width", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }) + ) + } + init( accessibility: DivAccessibility? = nil, action: DivAction? = nil, diff --git a/client/ios/DivKit/generated_sources/DivGrid.swift b/client/ios/DivKit/generated_sources/DivGrid.swift index 8271b5995..f7bd77c3f 100644 --- a/client/ios/DivKit/generated_sources/DivGrid.swift +++ b/client/ios/DivKit/generated_sources/DivGrid.swift @@ -113,6 +113,58 @@ public final class DivGrid: DivBase, Sendable { static let transitionTriggersValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + accessibility: try dictionary.getOptionalField("accessibility", transform: { (dict: [String: Any]) in try DivAccessibility(dictionary: dict, context: context) }), + action: try dictionary.getOptionalField("action", transform: { (dict: [String: Any]) in try DivAction(dictionary: dict, context: context) }), + actionAnimation: try dictionary.getOptionalField("action_animation", transform: { (dict: [String: Any]) in try DivAnimation(dictionary: dict, context: context) }), + actions: try dictionary.getOptionalArray("actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + alignmentHorizontal: try dictionary.getOptionalExpressionField("alignment_horizontal", context: context), + alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical", context: context), + alpha: try dictionary.getOptionalExpressionField("alpha", validator: Self.alphaValidator, context: context), + animators: try dictionary.getOptionalArray("animators", transform: { (dict: [String: Any]) in try? DivAnimator(dictionary: dict, context: context) }), + background: try dictionary.getOptionalArray("background", transform: { (dict: [String: Any]) in try? DivBackground(dictionary: dict, context: context) }), + border: try dictionary.getOptionalField("border", transform: { (dict: [String: Any]) in try DivBorder(dictionary: dict, context: context) }), + captureFocusOnAction: try dictionary.getOptionalExpressionField("capture_focus_on_action", context: context), + columnCount: try dictionary.getExpressionField("column_count", validator: Self.columnCountValidator, context: context), + columnSpan: try dictionary.getOptionalExpressionField("column_span", validator: Self.columnSpanValidator, context: context), + contentAlignmentHorizontal: try dictionary.getOptionalExpressionField("content_alignment_horizontal", context: context), + contentAlignmentVertical: try dictionary.getOptionalExpressionField("content_alignment_vertical", context: context), + disappearActions: try dictionary.getOptionalArray("disappear_actions", transform: { (dict: [String: Any]) in try? DivDisappearAction(dictionary: dict, context: context) }), + doubletapActions: try dictionary.getOptionalArray("doubletap_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + extensions: try dictionary.getOptionalArray("extensions", transform: { (dict: [String: Any]) in try? DivExtension(dictionary: dict, context: context) }), + focus: try dictionary.getOptionalField("focus", transform: { (dict: [String: Any]) in try DivFocus(dictionary: dict, context: context) }), + functions: try dictionary.getOptionalArray("functions", transform: { (dict: [String: Any]) in try? DivFunction(dictionary: dict, context: context) }), + height: try dictionary.getOptionalField("height", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }), + hoverEndActions: try dictionary.getOptionalArray("hover_end_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + hoverStartActions: try dictionary.getOptionalArray("hover_start_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + id: try dictionary.getOptionalField("id", context: context), + items: try dictionary.getOptionalArray("items", transform: { (dict: [String: Any]) in try? Div(dictionary: dict, context: context) }), + layoutProvider: try dictionary.getOptionalField("layout_provider", transform: { (dict: [String: Any]) in try DivLayoutProvider(dictionary: dict, context: context) }), + longtapActions: try dictionary.getOptionalArray("longtap_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + margins: try dictionary.getOptionalField("margins", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + paddings: try dictionary.getOptionalField("paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + pressEndActions: try dictionary.getOptionalArray("press_end_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + pressStartActions: try dictionary.getOptionalArray("press_start_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + reuseId: try dictionary.getOptionalExpressionField("reuse_id", context: context), + rowSpan: try dictionary.getOptionalExpressionField("row_span", validator: Self.rowSpanValidator, context: context), + selectedActions: try dictionary.getOptionalArray("selected_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + tooltips: try dictionary.getOptionalArray("tooltips", transform: { (dict: [String: Any]) in try? DivTooltip(dictionary: dict, context: context) }), + transform: try dictionary.getOptionalField("transform", transform: { (dict: [String: Any]) in try DivTransform(dictionary: dict, context: context) }), + transformations: try dictionary.getOptionalArray("transformations", transform: { (dict: [String: Any]) in try? DivTransformation(dictionary: dict, context: context) }), + transitionChange: try dictionary.getOptionalField("transition_change", transform: { (dict: [String: Any]) in try DivChangeTransition(dictionary: dict, context: context) }), + transitionIn: try dictionary.getOptionalField("transition_in", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionOut: try dictionary.getOptionalField("transition_out", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionTriggers: try dictionary.getOptionalArray("transition_triggers", validator: Self.transitionTriggersValidator, context: context), + variableTriggers: try dictionary.getOptionalArray("variable_triggers", transform: { (dict: [String: Any]) in try? DivTrigger(dictionary: dict, context: context) }), + variables: try dictionary.getOptionalArray("variables", transform: { (dict: [String: Any]) in try? DivVariable(dictionary: dict, context: context) }), + visibility: try dictionary.getOptionalExpressionField("visibility", context: context), + visibilityAction: try dictionary.getOptionalField("visibility_action", transform: { (dict: [String: Any]) in try DivVisibilityAction(dictionary: dict, context: context) }), + visibilityActions: try dictionary.getOptionalArray("visibility_actions", transform: { (dict: [String: Any]) in try? DivVisibilityAction(dictionary: dict, context: context) }), + width: try dictionary.getOptionalField("width", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }) + ) + } + init( accessibility: DivAccessibility?, action: DivAction?, diff --git a/client/ios/DivKit/generated_sources/DivImage.swift b/client/ios/DivKit/generated_sources/DivImage.swift index 9865c0ef0..8d21df6a1 100644 --- a/client/ios/DivKit/generated_sources/DivImage.swift +++ b/client/ios/DivKit/generated_sources/DivImage.swift @@ -147,6 +147,67 @@ public final class DivImage: DivBase, Sendable { static let transitionTriggersValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + accessibility: try dictionary.getOptionalField("accessibility", transform: { (dict: [String: Any]) in try DivAccessibility(dictionary: dict, context: context) }), + action: try dictionary.getOptionalField("action", transform: { (dict: [String: Any]) in try DivAction(dictionary: dict, context: context) }), + actionAnimation: try dictionary.getOptionalField("action_animation", transform: { (dict: [String: Any]) in try DivAnimation(dictionary: dict, context: context) }), + actions: try dictionary.getOptionalArray("actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + alignmentHorizontal: try dictionary.getOptionalExpressionField("alignment_horizontal", context: context), + alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical", context: context), + alpha: try dictionary.getOptionalExpressionField("alpha", validator: Self.alphaValidator, context: context), + animators: try dictionary.getOptionalArray("animators", transform: { (dict: [String: Any]) in try? DivAnimator(dictionary: dict, context: context) }), + appearanceAnimation: try dictionary.getOptionalField("appearance_animation", transform: { (dict: [String: Any]) in try DivFadeTransition(dictionary: dict, context: context) }), + aspect: try dictionary.getOptionalField("aspect", transform: { (dict: [String: Any]) in try DivAspect(dictionary: dict, context: context) }), + background: try dictionary.getOptionalArray("background", transform: { (dict: [String: Any]) in try? DivBackground(dictionary: dict, context: context) }), + border: try dictionary.getOptionalField("border", transform: { (dict: [String: Any]) in try DivBorder(dictionary: dict, context: context) }), + captureFocusOnAction: try dictionary.getOptionalExpressionField("capture_focus_on_action", context: context), + columnSpan: try dictionary.getOptionalExpressionField("column_span", validator: Self.columnSpanValidator, context: context), + contentAlignmentHorizontal: try dictionary.getOptionalExpressionField("content_alignment_horizontal", context: context), + contentAlignmentVertical: try dictionary.getOptionalExpressionField("content_alignment_vertical", context: context), + disappearActions: try dictionary.getOptionalArray("disappear_actions", transform: { (dict: [String: Any]) in try? DivDisappearAction(dictionary: dict, context: context) }), + doubletapActions: try dictionary.getOptionalArray("doubletap_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + extensions: try dictionary.getOptionalArray("extensions", transform: { (dict: [String: Any]) in try? DivExtension(dictionary: dict, context: context) }), + filters: try dictionary.getOptionalArray("filters", transform: { (dict: [String: Any]) in try? DivFilter(dictionary: dict, context: context) }), + focus: try dictionary.getOptionalField("focus", transform: { (dict: [String: Any]) in try DivFocus(dictionary: dict, context: context) }), + functions: try dictionary.getOptionalArray("functions", transform: { (dict: [String: Any]) in try? DivFunction(dictionary: dict, context: context) }), + height: try dictionary.getOptionalField("height", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }), + highPriorityPreviewShow: try dictionary.getOptionalExpressionField("high_priority_preview_show", context: context), + hoverEndActions: try dictionary.getOptionalArray("hover_end_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + hoverStartActions: try dictionary.getOptionalArray("hover_start_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + id: try dictionary.getOptionalField("id", context: context), + imageUrl: try dictionary.getExpressionField("image_url", transform: URL.makeFromNonEncodedString, context: context), + layoutProvider: try dictionary.getOptionalField("layout_provider", transform: { (dict: [String: Any]) in try DivLayoutProvider(dictionary: dict, context: context) }), + longtapActions: try dictionary.getOptionalArray("longtap_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + margins: try dictionary.getOptionalField("margins", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + paddings: try dictionary.getOptionalField("paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + placeholderColor: try dictionary.getOptionalExpressionField("placeholder_color", transform: Color.color(withHexString:), context: context), + preloadRequired: try dictionary.getOptionalExpressionField("preload_required", context: context), + pressEndActions: try dictionary.getOptionalArray("press_end_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + pressStartActions: try dictionary.getOptionalArray("press_start_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + preview: try dictionary.getOptionalExpressionField("preview", context: context), + reuseId: try dictionary.getOptionalExpressionField("reuse_id", context: context), + rowSpan: try dictionary.getOptionalExpressionField("row_span", validator: Self.rowSpanValidator, context: context), + scale: try dictionary.getOptionalExpressionField("scale", context: context), + selectedActions: try dictionary.getOptionalArray("selected_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + tintColor: try dictionary.getOptionalExpressionField("tint_color", transform: Color.color(withHexString:), context: context), + tintMode: try dictionary.getOptionalExpressionField("tint_mode", context: context), + tooltips: try dictionary.getOptionalArray("tooltips", transform: { (dict: [String: Any]) in try? DivTooltip(dictionary: dict, context: context) }), + transform: try dictionary.getOptionalField("transform", transform: { (dict: [String: Any]) in try DivTransform(dictionary: dict, context: context) }), + transformations: try dictionary.getOptionalArray("transformations", transform: { (dict: [String: Any]) in try? DivTransformation(dictionary: dict, context: context) }), + transitionChange: try dictionary.getOptionalField("transition_change", transform: { (dict: [String: Any]) in try DivChangeTransition(dictionary: dict, context: context) }), + transitionIn: try dictionary.getOptionalField("transition_in", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionOut: try dictionary.getOptionalField("transition_out", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionTriggers: try dictionary.getOptionalArray("transition_triggers", validator: Self.transitionTriggersValidator, context: context), + variableTriggers: try dictionary.getOptionalArray("variable_triggers", transform: { (dict: [String: Any]) in try? DivTrigger(dictionary: dict, context: context) }), + variables: try dictionary.getOptionalArray("variables", transform: { (dict: [String: Any]) in try? DivVariable(dictionary: dict, context: context) }), + visibility: try dictionary.getOptionalExpressionField("visibility", context: context), + visibilityAction: try dictionary.getOptionalField("visibility_action", transform: { (dict: [String: Any]) in try DivVisibilityAction(dictionary: dict, context: context) }), + visibilityActions: try dictionary.getOptionalArray("visibility_actions", transform: { (dict: [String: Any]) in try? DivVisibilityAction(dictionary: dict, context: context) }), + width: try dictionary.getOptionalField("width", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }) + ) + } + init( accessibility: DivAccessibility? = nil, action: DivAction? = nil, diff --git a/client/ios/DivKit/generated_sources/DivImageBackground.swift b/client/ios/DivKit/generated_sources/DivImageBackground.swift index bb6614b0f..8888a31b1 100644 --- a/client/ios/DivKit/generated_sources/DivImageBackground.swift +++ b/client/ios/DivKit/generated_sources/DivImageBackground.swift @@ -41,6 +41,18 @@ public final class DivImageBackground: Sendable { static let alphaValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0.0 && $0 <= 1.0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + alpha: try dictionary.getOptionalExpressionField("alpha", validator: Self.alphaValidator, context: context), + contentAlignmentHorizontal: try dictionary.getOptionalExpressionField("content_alignment_horizontal", context: context), + contentAlignmentVertical: try dictionary.getOptionalExpressionField("content_alignment_vertical", context: context), + filters: try dictionary.getOptionalArray("filters", transform: { (dict: [String: Any]) in try? DivFilter(dictionary: dict, context: context) }), + imageUrl: try dictionary.getExpressionField("image_url", transform: URL.makeFromNonEncodedString, context: context), + preloadRequired: try dictionary.getOptionalExpressionField("preload_required", context: context), + scale: try dictionary.getOptionalExpressionField("scale", context: context) + ) + } + init( alpha: Expression? = nil, contentAlignmentHorizontal: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivIndicator.swift b/client/ios/DivKit/generated_sources/DivIndicator.swift index d6ebc06e2..d0b3f5978 100644 --- a/client/ios/DivKit/generated_sources/DivIndicator.swift +++ b/client/ios/DivKit/generated_sources/DivIndicator.swift @@ -125,6 +125,56 @@ public final class DivIndicator: DivBase, Sendable { static let transitionTriggersValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + accessibility: try dictionary.getOptionalField("accessibility", transform: { (dict: [String: Any]) in try DivAccessibility(dictionary: dict, context: context) }), + activeItemColor: try dictionary.getOptionalExpressionField("active_item_color", transform: Color.color(withHexString:), context: context), + activeItemSize: try dictionary.getOptionalExpressionField("active_item_size", validator: Self.activeItemSizeValidator, context: context), + activeShape: try dictionary.getOptionalField("active_shape", transform: { (dict: [String: Any]) in try DivRoundedRectangleShape(dictionary: dict, context: context) }), + alignmentHorizontal: try dictionary.getOptionalExpressionField("alignment_horizontal", context: context), + alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical", context: context), + alpha: try dictionary.getOptionalExpressionField("alpha", validator: Self.alphaValidator, context: context), + animation: try dictionary.getOptionalExpressionField("animation", context: context), + animators: try dictionary.getOptionalArray("animators", transform: { (dict: [String: Any]) in try? DivAnimator(dictionary: dict, context: context) }), + background: try dictionary.getOptionalArray("background", transform: { (dict: [String: Any]) in try? DivBackground(dictionary: dict, context: context) }), + border: try dictionary.getOptionalField("border", transform: { (dict: [String: Any]) in try DivBorder(dictionary: dict, context: context) }), + columnSpan: try dictionary.getOptionalExpressionField("column_span", validator: Self.columnSpanValidator, context: context), + disappearActions: try dictionary.getOptionalArray("disappear_actions", transform: { (dict: [String: Any]) in try? DivDisappearAction(dictionary: dict, context: context) }), + extensions: try dictionary.getOptionalArray("extensions", transform: { (dict: [String: Any]) in try? DivExtension(dictionary: dict, context: context) }), + focus: try dictionary.getOptionalField("focus", transform: { (dict: [String: Any]) in try DivFocus(dictionary: dict, context: context) }), + functions: try dictionary.getOptionalArray("functions", transform: { (dict: [String: Any]) in try? DivFunction(dictionary: dict, context: context) }), + height: try dictionary.getOptionalField("height", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }), + id: try dictionary.getOptionalField("id", context: context), + inactiveItemColor: try dictionary.getOptionalExpressionField("inactive_item_color", transform: Color.color(withHexString:), context: context), + inactiveMinimumShape: try dictionary.getOptionalField("inactive_minimum_shape", transform: { (dict: [String: Any]) in try DivRoundedRectangleShape(dictionary: dict, context: context) }), + inactiveShape: try dictionary.getOptionalField("inactive_shape", transform: { (dict: [String: Any]) in try DivRoundedRectangleShape(dictionary: dict, context: context) }), + itemsPlacement: try dictionary.getOptionalField("items_placement", transform: { (dict: [String: Any]) in try DivIndicatorItemPlacement(dictionary: dict, context: context) }), + layoutProvider: try dictionary.getOptionalField("layout_provider", transform: { (dict: [String: Any]) in try DivLayoutProvider(dictionary: dict, context: context) }), + margins: try dictionary.getOptionalField("margins", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + minimumItemSize: try dictionary.getOptionalExpressionField("minimum_item_size", validator: Self.minimumItemSizeValidator, context: context), + paddings: try dictionary.getOptionalField("paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + pagerId: try dictionary.getOptionalField("pager_id", context: context), + reuseId: try dictionary.getOptionalExpressionField("reuse_id", context: context), + rowSpan: try dictionary.getOptionalExpressionField("row_span", validator: Self.rowSpanValidator, context: context), + selectedActions: try dictionary.getOptionalArray("selected_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + shape: try dictionary.getOptionalField("shape", transform: { (dict: [String: Any]) in try DivShape(dictionary: dict, context: context) }), + spaceBetweenCenters: try dictionary.getOptionalField("space_between_centers", transform: { (dict: [String: Any]) in try DivFixedSize(dictionary: dict, context: context) }), + tooltips: try dictionary.getOptionalArray("tooltips", transform: { (dict: [String: Any]) in try? DivTooltip(dictionary: dict, context: context) }), + transform: try dictionary.getOptionalField("transform", transform: { (dict: [String: Any]) in try DivTransform(dictionary: dict, context: context) }), + transformations: try dictionary.getOptionalArray("transformations", transform: { (dict: [String: Any]) in try? DivTransformation(dictionary: dict, context: context) }), + transitionChange: try dictionary.getOptionalField("transition_change", transform: { (dict: [String: Any]) in try DivChangeTransition(dictionary: dict, context: context) }), + transitionIn: try dictionary.getOptionalField("transition_in", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionOut: try dictionary.getOptionalField("transition_out", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionTriggers: try dictionary.getOptionalArray("transition_triggers", validator: Self.transitionTriggersValidator, context: context), + variableTriggers: try dictionary.getOptionalArray("variable_triggers", transform: { (dict: [String: Any]) in try? DivTrigger(dictionary: dict, context: context) }), + variables: try dictionary.getOptionalArray("variables", transform: { (dict: [String: Any]) in try? DivVariable(dictionary: dict, context: context) }), + visibility: try dictionary.getOptionalExpressionField("visibility", context: context), + visibilityAction: try dictionary.getOptionalField("visibility_action", transform: { (dict: [String: Any]) in try DivVisibilityAction(dictionary: dict, context: context) }), + visibilityActions: try dictionary.getOptionalArray("visibility_actions", transform: { (dict: [String: Any]) in try? DivVisibilityAction(dictionary: dict, context: context) }), + width: try dictionary.getOptionalField("width", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }) + ) + } + init( accessibility: DivAccessibility? = nil, activeItemColor: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivIndicatorItemPlacement.swift b/client/ios/DivKit/generated_sources/DivIndicatorItemPlacement.swift index e2076629c..13026d7a1 100644 --- a/client/ios/DivKit/generated_sources/DivIndicatorItemPlacement.swift +++ b/client/ios/DivKit/generated_sources/DivIndicatorItemPlacement.swift @@ -19,6 +19,20 @@ public enum DivIndicatorItemPlacement: Sendable { } } +extension DivIndicatorItemPlacement { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivDefaultIndicatorItemPlacement.type: + self = .divDefaultIndicatorItemPlacement(try DivDefaultIndicatorItemPlacement(dictionary: dictionary, context: context)) + case DivStretchIndicatorItemPlacement.type: + self = .divStretchIndicatorItemPlacement(try DivStretchIndicatorItemPlacement(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-indicator-item-placement", representation: dictionary) + } + } +} + #if DEBUG extension DivIndicatorItemPlacement: Equatable { public static func ==(lhs: DivIndicatorItemPlacement, rhs: DivIndicatorItemPlacement) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivInfinityCount.swift b/client/ios/DivKit/generated_sources/DivInfinityCount.swift index 476fddcb1..5719fb0ed 100644 --- a/client/ios/DivKit/generated_sources/DivInfinityCount.swift +++ b/client/ios/DivKit/generated_sources/DivInfinityCount.swift @@ -7,6 +7,8 @@ import VGSL public final class DivInfinityCount: Sendable { public static let type: String = "infinity" + public init(dictionary: [String: Any], context: ParsingContext) throws {} + init() {} } diff --git a/client/ios/DivKit/generated_sources/DivInput.swift b/client/ios/DivKit/generated_sources/DivInput.swift index bebd09084..3841320b0 100644 --- a/client/ios/DivKit/generated_sources/DivInput.swift +++ b/client/ios/DivKit/generated_sources/DivInput.swift @@ -41,6 +41,12 @@ public final class DivInput: DivBase, @unchecked Sendable { resolver.resolveColor(color) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + color: try dictionary.getExpressionField("color", transform: Color.color(withHexString:), context: context) + ) + } + init( color: Expression ) { @@ -249,6 +255,71 @@ public final class DivInput: DivBase, @unchecked Sendable { static let transitionTriggersValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + accessibility: try dictionary.getOptionalField("accessibility", transform: { (dict: [String: Any]) in try DivAccessibility(dictionary: dict, context: context) }), + alignmentHorizontal: try dictionary.getOptionalExpressionField("alignment_horizontal", context: context), + alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical", context: context), + alpha: try dictionary.getOptionalExpressionField("alpha", validator: Self.alphaValidator, context: context), + animators: try dictionary.getOptionalArray("animators", transform: { (dict: [String: Any]) in try? DivAnimator(dictionary: dict, context: context) }), + autocapitalization: try dictionary.getOptionalExpressionField("autocapitalization", context: context), + background: try dictionary.getOptionalArray("background", transform: { (dict: [String: Any]) in try? DivBackground(dictionary: dict, context: context) }), + border: try dictionary.getOptionalField("border", transform: { (dict: [String: Any]) in try DivBorder(dictionary: dict, context: context) }), + columnSpan: try dictionary.getOptionalExpressionField("column_span", validator: Self.columnSpanValidator, context: context), + disappearActions: try dictionary.getOptionalArray("disappear_actions", transform: { (dict: [String: Any]) in try? DivDisappearAction(dictionary: dict, context: context) }), + enterKeyActions: try dictionary.getOptionalArray("enter_key_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + enterKeyType: try dictionary.getOptionalExpressionField("enter_key_type", context: context), + extensions: try dictionary.getOptionalArray("extensions", transform: { (dict: [String: Any]) in try? DivExtension(dictionary: dict, context: context) }), + filters: try dictionary.getOptionalArray("filters", transform: { (dict: [String: Any]) in try? DivInputFilter(dictionary: dict, context: context) }), + focus: try dictionary.getOptionalField("focus", transform: { (dict: [String: Any]) in try DivFocus(dictionary: dict, context: context) }), + fontFamily: try dictionary.getOptionalExpressionField("font_family", context: context), + fontSize: try dictionary.getOptionalExpressionField("font_size", validator: Self.fontSizeValidator, context: context), + fontSizeUnit: try dictionary.getOptionalExpressionField("font_size_unit", context: context), + fontVariationSettings: try dictionary.getOptionalExpressionField("font_variation_settings", context: context), + fontWeight: try dictionary.getOptionalExpressionField("font_weight", context: context), + fontWeightValue: try dictionary.getOptionalExpressionField("font_weight_value", validator: Self.fontWeightValueValidator, context: context), + functions: try dictionary.getOptionalArray("functions", transform: { (dict: [String: Any]) in try? DivFunction(dictionary: dict, context: context) }), + height: try dictionary.getOptionalField("height", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }), + highlightColor: try dictionary.getOptionalExpressionField("highlight_color", transform: Color.color(withHexString:), context: context), + hintColor: try dictionary.getOptionalExpressionField("hint_color", transform: Color.color(withHexString:), context: context), + hintText: try dictionary.getOptionalExpressionField("hint_text", context: context), + id: try dictionary.getOptionalField("id", context: context), + isEnabled: try dictionary.getOptionalExpressionField("is_enabled", context: context), + keyboardType: try dictionary.getOptionalExpressionField("keyboard_type", context: context), + layoutProvider: try dictionary.getOptionalField("layout_provider", transform: { (dict: [String: Any]) in try DivLayoutProvider(dictionary: dict, context: context) }), + letterSpacing: try dictionary.getOptionalExpressionField("letter_spacing", context: context), + lineHeight: try dictionary.getOptionalExpressionField("line_height", validator: Self.lineHeightValidator, context: context), + margins: try dictionary.getOptionalField("margins", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + mask: try dictionary.getOptionalField("mask", transform: { (dict: [String: Any]) in try DivInputMask(dictionary: dict, context: context) }), + maxLength: try dictionary.getOptionalExpressionField("max_length", validator: Self.maxLengthValidator, context: context), + maxVisibleLines: try dictionary.getOptionalExpressionField("max_visible_lines", validator: Self.maxVisibleLinesValidator, context: context), + nativeInterface: try dictionary.getOptionalField("native_interface", transform: { (dict: [String: Any]) in try DivInput.NativeInterface(dictionary: dict, context: context) }), + paddings: try dictionary.getOptionalField("paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + reuseId: try dictionary.getOptionalExpressionField("reuse_id", context: context), + rowSpan: try dictionary.getOptionalExpressionField("row_span", validator: Self.rowSpanValidator, context: context), + selectAllOnFocus: try dictionary.getOptionalExpressionField("select_all_on_focus", context: context), + selectedActions: try dictionary.getOptionalArray("selected_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + textAlignmentHorizontal: try dictionary.getOptionalExpressionField("text_alignment_horizontal", context: context), + textAlignmentVertical: try dictionary.getOptionalExpressionField("text_alignment_vertical", context: context), + textColor: try dictionary.getOptionalExpressionField("text_color", transform: Color.color(withHexString:), context: context), + textVariable: try dictionary.getField("text_variable", context: context), + tooltips: try dictionary.getOptionalArray("tooltips", transform: { (dict: [String: Any]) in try? DivTooltip(dictionary: dict, context: context) }), + transform: try dictionary.getOptionalField("transform", transform: { (dict: [String: Any]) in try DivTransform(dictionary: dict, context: context) }), + transformations: try dictionary.getOptionalArray("transformations", transform: { (dict: [String: Any]) in try? DivTransformation(dictionary: dict, context: context) }), + transitionChange: try dictionary.getOptionalField("transition_change", transform: { (dict: [String: Any]) in try DivChangeTransition(dictionary: dict, context: context) }), + transitionIn: try dictionary.getOptionalField("transition_in", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionOut: try dictionary.getOptionalField("transition_out", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionTriggers: try dictionary.getOptionalArray("transition_triggers", validator: Self.transitionTriggersValidator, context: context), + validators: try dictionary.getOptionalArray("validators", transform: { (dict: [String: Any]) in try? DivInputValidator(dictionary: dict, context: context) }), + variableTriggers: try dictionary.getOptionalArray("variable_triggers", transform: { (dict: [String: Any]) in try? DivTrigger(dictionary: dict, context: context) }), + variables: try dictionary.getOptionalArray("variables", transform: { (dict: [String: Any]) in try? DivVariable(dictionary: dict, context: context) }), + visibility: try dictionary.getOptionalExpressionField("visibility", context: context), + visibilityAction: try dictionary.getOptionalField("visibility_action", transform: { (dict: [String: Any]) in try DivVisibilityAction(dictionary: dict, context: context) }), + visibilityActions: try dictionary.getOptionalArray("visibility_actions", transform: { (dict: [String: Any]) in try? DivVisibilityAction(dictionary: dict, context: context) }), + width: try dictionary.getOptionalField("width", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }) + ) + } + init( accessibility: DivAccessibility? = nil, alignmentHorizontal: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivInputFilter.swift b/client/ios/DivKit/generated_sources/DivInputFilter.swift index 3ae79e06e..d36581af9 100644 --- a/client/ios/DivKit/generated_sources/DivInputFilter.swift +++ b/client/ios/DivKit/generated_sources/DivInputFilter.swift @@ -19,6 +19,20 @@ public enum DivInputFilter: Sendable { } } +extension DivInputFilter { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivInputFilterRegex.type: + self = .divInputFilterRegex(try DivInputFilterRegex(dictionary: dictionary, context: context)) + case DivInputFilterExpression.type: + self = .divInputFilterExpression(try DivInputFilterExpression(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-input-filter", representation: dictionary) + } + } +} + #if DEBUG extension DivInputFilter: Equatable { public static func ==(lhs: DivInputFilter, rhs: DivInputFilter) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivInputFilterExpression.swift b/client/ios/DivKit/generated_sources/DivInputFilterExpression.swift index 7c11d2606..1818cc3b8 100644 --- a/client/ios/DivKit/generated_sources/DivInputFilterExpression.swift +++ b/client/ios/DivKit/generated_sources/DivInputFilterExpression.swift @@ -12,6 +12,12 @@ public final class DivInputFilterExpression: Sendable { resolver.resolveNumeric(condition) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + condition: try dictionary.getExpressionField("condition", context: context) + ) + } + init( condition: Expression ) { diff --git a/client/ios/DivKit/generated_sources/DivInputFilterRegex.swift b/client/ios/DivKit/generated_sources/DivInputFilterRegex.swift index 4a25cd18e..379354a3a 100644 --- a/client/ios/DivKit/generated_sources/DivInputFilterRegex.swift +++ b/client/ios/DivKit/generated_sources/DivInputFilterRegex.swift @@ -12,6 +12,12 @@ public final class DivInputFilterRegex: Sendable { resolver.resolveString(pattern) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + pattern: try dictionary.getExpressionField("pattern", context: context) + ) + } + init( pattern: Expression ) { diff --git a/client/ios/DivKit/generated_sources/DivInputMask.swift b/client/ios/DivKit/generated_sources/DivInputMask.swift index d6dae3808..e77baffed 100644 --- a/client/ios/DivKit/generated_sources/DivInputMask.swift +++ b/client/ios/DivKit/generated_sources/DivInputMask.swift @@ -22,6 +22,22 @@ public enum DivInputMask: Sendable { } } +extension DivInputMask { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivFixedLengthInputMask.type: + self = .divFixedLengthInputMask(try DivFixedLengthInputMask(dictionary: dictionary, context: context)) + case DivCurrencyInputMask.type: + self = .divCurrencyInputMask(try DivCurrencyInputMask(dictionary: dictionary, context: context)) + case DivPhoneInputMask.type: + self = .divPhoneInputMask(try DivPhoneInputMask(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-input-mask", representation: dictionary) + } + } +} + #if DEBUG extension DivInputMask: Equatable { public static func ==(lhs: DivInputMask, rhs: DivInputMask) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivInputValidator.swift b/client/ios/DivKit/generated_sources/DivInputValidator.swift index 5072994a1..407703b7c 100644 --- a/client/ios/DivKit/generated_sources/DivInputValidator.swift +++ b/client/ios/DivKit/generated_sources/DivInputValidator.swift @@ -19,6 +19,20 @@ public enum DivInputValidator: Sendable { } } +extension DivInputValidator { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivInputValidatorRegex.type: + self = .divInputValidatorRegex(try DivInputValidatorRegex(dictionary: dictionary, context: context)) + case DivInputValidatorExpression.type: + self = .divInputValidatorExpression(try DivInputValidatorExpression(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-input-validator", representation: dictionary) + } + } +} + #if DEBUG extension DivInputValidator: Equatable { public static func ==(lhs: DivInputValidator, rhs: DivInputValidator) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivInputValidatorBase.swift b/client/ios/DivKit/generated_sources/DivInputValidatorBase.swift index 6ba20a340..60832a0d1 100644 --- a/client/ios/DivKit/generated_sources/DivInputValidatorBase.swift +++ b/client/ios/DivKit/generated_sources/DivInputValidatorBase.swift @@ -17,6 +17,14 @@ public final class DivInputValidatorBase: Sendable { resolver.resolveString(labelId) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + allowEmpty: try dictionary.getOptionalExpressionField("allow_empty", context: context), + labelId: try dictionary.getOptionalExpressionField("label_id", context: context), + variable: try dictionary.getOptionalField("variable", context: context) + ) + } + init( allowEmpty: Expression? = nil, labelId: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivInputValidatorExpression.swift b/client/ios/DivKit/generated_sources/DivInputValidatorExpression.swift index fee30e19c..422584bcc 100644 --- a/client/ios/DivKit/generated_sources/DivInputValidatorExpression.swift +++ b/client/ios/DivKit/generated_sources/DivInputValidatorExpression.swift @@ -23,6 +23,15 @@ public final class DivInputValidatorExpression: Sendable { resolver.resolveString(labelId) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + allowEmpty: try dictionary.getOptionalExpressionField("allow_empty", context: context), + condition: try dictionary.getExpressionField("condition", context: context), + labelId: try dictionary.getExpressionField("label_id", context: context), + variable: try dictionary.getField("variable", context: context) + ) + } + init( allowEmpty: Expression? = nil, condition: Expression, diff --git a/client/ios/DivKit/generated_sources/DivInputValidatorRegex.swift b/client/ios/DivKit/generated_sources/DivInputValidatorRegex.swift index 9f3f4441c..cee76d6ec 100644 --- a/client/ios/DivKit/generated_sources/DivInputValidatorRegex.swift +++ b/client/ios/DivKit/generated_sources/DivInputValidatorRegex.swift @@ -23,6 +23,15 @@ public final class DivInputValidatorRegex: Sendable { resolver.resolveString(pattern) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + allowEmpty: try dictionary.getOptionalExpressionField("allow_empty", context: context), + labelId: try dictionary.getExpressionField("label_id", context: context), + pattern: try dictionary.getExpressionField("pattern", context: context), + variable: try dictionary.getField("variable", context: context) + ) + } + init( allowEmpty: Expression? = nil, labelId: Expression, diff --git a/client/ios/DivKit/generated_sources/DivLayoutProvider.swift b/client/ios/DivKit/generated_sources/DivLayoutProvider.swift index e244a53c2..f52c0c8a5 100644 --- a/client/ios/DivKit/generated_sources/DivLayoutProvider.swift +++ b/client/ios/DivKit/generated_sources/DivLayoutProvider.swift @@ -8,6 +8,13 @@ public final class DivLayoutProvider: Sendable { public let heightVariableName: String? public let widthVariableName: String? + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + heightVariableName: try dictionary.getOptionalField("height_variable_name", context: context), + widthVariableName: try dictionary.getOptionalField("width_variable_name", context: context) + ) + } + init( heightVariableName: String? = nil, widthVariableName: String? = nil diff --git a/client/ios/DivKit/generated_sources/DivLinearGradient.swift b/client/ios/DivKit/generated_sources/DivLinearGradient.swift index 7e00a7044..1b97f0d9c 100644 --- a/client/ios/DivKit/generated_sources/DivLinearGradient.swift +++ b/client/ios/DivKit/generated_sources/DivLinearGradient.swift @@ -20,6 +20,13 @@ public final class DivLinearGradient: Sendable { static let positionValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0.0 && $0 <= 1.0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + color: try dictionary.getExpressionField("color", transform: Color.color(withHexString:), context: context), + position: try dictionary.getExpressionField("position", validator: Self.positionValidator, context: context) + ) + } + init( color: Expression, position: Expression @@ -51,6 +58,14 @@ public final class DivLinearGradient: Sendable { static let colorsValidator: AnyArrayValueValidator> = makeArrayValidator(minItems: 2) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + angle: try dictionary.getOptionalExpressionField("angle", validator: Self.angleValidator, context: context), + colorMap: try dictionary.getOptionalArray("color_map", transform: { (dict: [String: Any]) in try? DivLinearGradient.ColorPoint(dictionary: dict, context: context) }, validator: Self.colorMapValidator), + colors: try dictionary.getOptionalExpressionArray("colors", transform: Color.color(withHexString:), validator: Self.colorsValidator, context: context) + ) + } + init( angle: Expression? = nil, colorMap: [ColorPoint]? = nil, diff --git a/client/ios/DivKit/generated_sources/DivMatchParentSize.swift b/client/ios/DivKit/generated_sources/DivMatchParentSize.swift index 311e769db..09db1a000 100644 --- a/client/ios/DivKit/generated_sources/DivMatchParentSize.swift +++ b/client/ios/DivKit/generated_sources/DivMatchParentSize.swift @@ -17,6 +17,14 @@ public final class DivMatchParentSize: Sendable { static let weightValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 > 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + maxSize: try dictionary.getOptionalField("max_size", transform: { (dict: [String: Any]) in try DivSizeUnitValue(dictionary: dict, context: context) }), + minSize: try dictionary.getOptionalField("min_size", transform: { (dict: [String: Any]) in try DivSizeUnitValue(dictionary: dict, context: context) }), + weight: try dictionary.getOptionalExpressionField("weight", validator: Self.weightValidator, context: context) + ) + } + init( maxSize: DivSizeUnitValue? = nil, minSize: DivSizeUnitValue? = nil, diff --git a/client/ios/DivKit/generated_sources/DivNeighbourPageSize.swift b/client/ios/DivKit/generated_sources/DivNeighbourPageSize.swift index ebf244d04..3a5f8525f 100644 --- a/client/ios/DivKit/generated_sources/DivNeighbourPageSize.swift +++ b/client/ios/DivKit/generated_sources/DivNeighbourPageSize.swift @@ -8,6 +8,12 @@ public final class DivNeighbourPageSize: Sendable { public static let type: String = "fixed" public let neighbourPageWidth: DivFixedSize + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + neighbourPageWidth: try dictionary.getField("neighbour_page_width", transform: { (dict: [String: Any]) in try DivFixedSize(dictionary: dict, context: context) }) + ) + } + init( neighbourPageWidth: DivFixedSize ) { diff --git a/client/ios/DivKit/generated_sources/DivNinePatchBackground.swift b/client/ios/DivKit/generated_sources/DivNinePatchBackground.swift index df9d5a607..9db3cecc7 100644 --- a/client/ios/DivKit/generated_sources/DivNinePatchBackground.swift +++ b/client/ios/DivKit/generated_sources/DivNinePatchBackground.swift @@ -13,6 +13,13 @@ public final class DivNinePatchBackground: Sendable { resolver.resolveUrl(imageUrl) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + imageUrl: try dictionary.getExpressionField("image_url", transform: URL.makeFromNonEncodedString, context: context), + insets: try dictionary.getField("insets", transform: { (dict: [String: Any]) in try DivAbsoluteEdgeInsets(dictionary: dict, context: context) }) + ) + } + init( imageUrl: Expression, insets: DivAbsoluteEdgeInsets diff --git a/client/ios/DivKit/generated_sources/DivNumberAnimator.swift b/client/ios/DivKit/generated_sources/DivNumberAnimator.swift index 8ceae9e9a..4483dd749 100644 --- a/client/ios/DivKit/generated_sources/DivNumberAnimator.swift +++ b/client/ios/DivKit/generated_sources/DivNumberAnimator.swift @@ -48,6 +48,22 @@ public final class DivNumberAnimator: DivAnimatorBase, Sendable { static let startDelayValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + cancelActions: try dictionary.getOptionalArray("cancel_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + direction: try dictionary.getOptionalExpressionField("direction", context: context), + duration: try dictionary.getExpressionField("duration", validator: Self.durationValidator, context: context), + endActions: try dictionary.getOptionalArray("end_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + endValue: try dictionary.getExpressionField("end_value", context: context), + id: try dictionary.getField("id", context: context), + interpolator: try dictionary.getOptionalExpressionField("interpolator", context: context), + repeatCount: try dictionary.getOptionalField("repeat_count", transform: { (dict: [String: Any]) in try DivCount(dictionary: dict, context: context) }), + startDelay: try dictionary.getOptionalExpressionField("start_delay", validator: Self.startDelayValidator, context: context), + startValue: try dictionary.getOptionalExpressionField("start_value", context: context), + variableName: try dictionary.getField("variable_name", context: context) + ) + } + init( cancelActions: [DivAction]? = nil, direction: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivPageContentSize.swift b/client/ios/DivKit/generated_sources/DivPageContentSize.swift index 0a8be33cb..5e3b63f34 100644 --- a/client/ios/DivKit/generated_sources/DivPageContentSize.swift +++ b/client/ios/DivKit/generated_sources/DivPageContentSize.swift @@ -7,6 +7,8 @@ import VGSL public final class DivPageContentSize: Sendable { public static let type: String = "wrap_content" + public init(dictionary: [String: Any], context: ParsingContext) throws {} + init() {} } diff --git a/client/ios/DivKit/generated_sources/DivPageSize.swift b/client/ios/DivKit/generated_sources/DivPageSize.swift index 63a10d089..3c46dfb5d 100644 --- a/client/ios/DivKit/generated_sources/DivPageSize.swift +++ b/client/ios/DivKit/generated_sources/DivPageSize.swift @@ -8,6 +8,12 @@ public final class DivPageSize: Sendable { public static let type: String = "percentage" public let pageWidth: DivPercentageSize + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + pageWidth: try dictionary.getField("page_width", transform: { (dict: [String: Any]) in try DivPercentageSize(dictionary: dict, context: context) }) + ) + } + init( pageWidth: DivPercentageSize ) { diff --git a/client/ios/DivKit/generated_sources/DivPageTransformation.swift b/client/ios/DivKit/generated_sources/DivPageTransformation.swift index ce99209f4..4dabc3d6a 100644 --- a/client/ios/DivKit/generated_sources/DivPageTransformation.swift +++ b/client/ios/DivKit/generated_sources/DivPageTransformation.swift @@ -19,6 +19,20 @@ public enum DivPageTransformation: Sendable { } } +extension DivPageTransformation { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivPageTransformationSlide.type: + self = .divPageTransformationSlide(try DivPageTransformationSlide(dictionary: dictionary, context: context)) + case DivPageTransformationOverlap.type: + self = .divPageTransformationOverlap(try DivPageTransformationOverlap(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-page-transformation", representation: dictionary) + } + } +} + #if DEBUG extension DivPageTransformation: Equatable { public static func ==(lhs: DivPageTransformation, rhs: DivPageTransformation) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivPageTransformationOverlap.swift b/client/ios/DivKit/generated_sources/DivPageTransformationOverlap.swift index 361fe7fcb..9be195e81 100644 --- a/client/ios/DivKit/generated_sources/DivPageTransformationOverlap.swift +++ b/client/ios/DivKit/generated_sources/DivPageTransformationOverlap.swift @@ -49,6 +49,17 @@ public final class DivPageTransformationOverlap: Sendable { static let previousPageScaleValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0.0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + interpolator: try dictionary.getOptionalExpressionField("interpolator", context: context), + nextPageAlpha: try dictionary.getOptionalExpressionField("next_page_alpha", validator: Self.nextPageAlphaValidator, context: context), + nextPageScale: try dictionary.getOptionalExpressionField("next_page_scale", validator: Self.nextPageScaleValidator, context: context), + previousPageAlpha: try dictionary.getOptionalExpressionField("previous_page_alpha", validator: Self.previousPageAlphaValidator, context: context), + previousPageScale: try dictionary.getOptionalExpressionField("previous_page_scale", validator: Self.previousPageScaleValidator, context: context), + reversedStackingOrder: try dictionary.getOptionalExpressionField("reversed_stacking_order", context: context) + ) + } + init( interpolator: Expression? = nil, nextPageAlpha: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivPageTransformationSlide.swift b/client/ios/DivKit/generated_sources/DivPageTransformationSlide.swift index b08689406..9b1fc67a2 100644 --- a/client/ios/DivKit/generated_sources/DivPageTransformationSlide.swift +++ b/client/ios/DivKit/generated_sources/DivPageTransformationSlide.swift @@ -44,6 +44,16 @@ public final class DivPageTransformationSlide: Sendable { static let previousPageScaleValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0.0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + interpolator: try dictionary.getOptionalExpressionField("interpolator", context: context), + nextPageAlpha: try dictionary.getOptionalExpressionField("next_page_alpha", validator: Self.nextPageAlphaValidator, context: context), + nextPageScale: try dictionary.getOptionalExpressionField("next_page_scale", validator: Self.nextPageScaleValidator, context: context), + previousPageAlpha: try dictionary.getOptionalExpressionField("previous_page_alpha", validator: Self.previousPageAlphaValidator, context: context), + previousPageScale: try dictionary.getOptionalExpressionField("previous_page_scale", validator: Self.previousPageScaleValidator, context: context) + ) + } + init( interpolator: Expression? = nil, nextPageAlpha: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivPager.swift b/client/ios/DivKit/generated_sources/DivPager.swift index 12eb5e59a..0b1a4e57b 100644 --- a/client/ios/DivKit/generated_sources/DivPager.swift +++ b/client/ios/DivKit/generated_sources/DivPager.swift @@ -131,6 +131,55 @@ public final class DivPager: DivBase, Sendable { static let transitionTriggersValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + accessibility: try dictionary.getOptionalField("accessibility", transform: { (dict: [String: Any]) in try DivAccessibility(dictionary: dict, context: context) }), + alignmentHorizontal: try dictionary.getOptionalExpressionField("alignment_horizontal", context: context), + alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical", context: context), + alpha: try dictionary.getOptionalExpressionField("alpha", validator: Self.alphaValidator, context: context), + animators: try dictionary.getOptionalArray("animators", transform: { (dict: [String: Any]) in try? DivAnimator(dictionary: dict, context: context) }), + background: try dictionary.getOptionalArray("background", transform: { (dict: [String: Any]) in try? DivBackground(dictionary: dict, context: context) }), + border: try dictionary.getOptionalField("border", transform: { (dict: [String: Any]) in try DivBorder(dictionary: dict, context: context) }), + columnSpan: try dictionary.getOptionalExpressionField("column_span", validator: Self.columnSpanValidator, context: context), + crossAxisAlignment: try dictionary.getOptionalExpressionField("cross_axis_alignment", context: context), + defaultItem: try dictionary.getOptionalExpressionField("default_item", validator: Self.defaultItemValidator, context: context), + disappearActions: try dictionary.getOptionalArray("disappear_actions", transform: { (dict: [String: Any]) in try? DivDisappearAction(dictionary: dict, context: context) }), + extensions: try dictionary.getOptionalArray("extensions", transform: { (dict: [String: Any]) in try? DivExtension(dictionary: dict, context: context) }), + focus: try dictionary.getOptionalField("focus", transform: { (dict: [String: Any]) in try DivFocus(dictionary: dict, context: context) }), + functions: try dictionary.getOptionalArray("functions", transform: { (dict: [String: Any]) in try? DivFunction(dictionary: dict, context: context) }), + height: try dictionary.getOptionalField("height", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }), + id: try dictionary.getOptionalField("id", context: context), + infiniteScroll: try dictionary.getOptionalExpressionField("infinite_scroll", context: context), + itemBuilder: try dictionary.getOptionalField("item_builder", transform: { (dict: [String: Any]) in try DivCollectionItemBuilder(dictionary: dict, context: context) }), + itemSpacing: try dictionary.getOptionalField("item_spacing", transform: { (dict: [String: Any]) in try DivFixedSize(dictionary: dict, context: context) }), + items: try dictionary.getOptionalArray("items", transform: { (dict: [String: Any]) in try? Div(dictionary: dict, context: context) }), + layoutMode: try dictionary.getField("layout_mode", transform: { (dict: [String: Any]) in try DivPagerLayoutMode(dictionary: dict, context: context) }), + layoutProvider: try dictionary.getOptionalField("layout_provider", transform: { (dict: [String: Any]) in try DivLayoutProvider(dictionary: dict, context: context) }), + margins: try dictionary.getOptionalField("margins", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + orientation: try dictionary.getOptionalExpressionField("orientation", context: context), + paddings: try dictionary.getOptionalField("paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + pageTransformation: try dictionary.getOptionalField("page_transformation", transform: { (dict: [String: Any]) in try DivPageTransformation(dictionary: dict, context: context) }), + restrictParentScroll: try dictionary.getOptionalExpressionField("restrict_parent_scroll", context: context), + reuseId: try dictionary.getOptionalExpressionField("reuse_id", context: context), + rowSpan: try dictionary.getOptionalExpressionField("row_span", validator: Self.rowSpanValidator, context: context), + scrollAxisAlignment: try dictionary.getOptionalExpressionField("scroll_axis_alignment", context: context), + selectedActions: try dictionary.getOptionalArray("selected_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + tooltips: try dictionary.getOptionalArray("tooltips", transform: { (dict: [String: Any]) in try? DivTooltip(dictionary: dict, context: context) }), + transform: try dictionary.getOptionalField("transform", transform: { (dict: [String: Any]) in try DivTransform(dictionary: dict, context: context) }), + transformations: try dictionary.getOptionalArray("transformations", transform: { (dict: [String: Any]) in try? DivTransformation(dictionary: dict, context: context) }), + transitionChange: try dictionary.getOptionalField("transition_change", transform: { (dict: [String: Any]) in try DivChangeTransition(dictionary: dict, context: context) }), + transitionIn: try dictionary.getOptionalField("transition_in", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionOut: try dictionary.getOptionalField("transition_out", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionTriggers: try dictionary.getOptionalArray("transition_triggers", validator: Self.transitionTriggersValidator, context: context), + variableTriggers: try dictionary.getOptionalArray("variable_triggers", transform: { (dict: [String: Any]) in try? DivTrigger(dictionary: dict, context: context) }), + variables: try dictionary.getOptionalArray("variables", transform: { (dict: [String: Any]) in try? DivVariable(dictionary: dict, context: context) }), + visibility: try dictionary.getOptionalExpressionField("visibility", context: context), + visibilityAction: try dictionary.getOptionalField("visibility_action", transform: { (dict: [String: Any]) in try DivVisibilityAction(dictionary: dict, context: context) }), + visibilityActions: try dictionary.getOptionalArray("visibility_actions", transform: { (dict: [String: Any]) in try? DivVisibilityAction(dictionary: dict, context: context) }), + width: try dictionary.getOptionalField("width", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }) + ) + } + init( accessibility: DivAccessibility?, alignmentHorizontal: Expression?, diff --git a/client/ios/DivKit/generated_sources/DivPagerLayoutMode.swift b/client/ios/DivKit/generated_sources/DivPagerLayoutMode.swift index 977e15492..bd7f80143 100644 --- a/client/ios/DivKit/generated_sources/DivPagerLayoutMode.swift +++ b/client/ios/DivKit/generated_sources/DivPagerLayoutMode.swift @@ -22,6 +22,22 @@ public enum DivPagerLayoutMode: Sendable { } } +extension DivPagerLayoutMode { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivPageSize.type: + self = .divPageSize(try DivPageSize(dictionary: dictionary, context: context)) + case DivNeighbourPageSize.type: + self = .divNeighbourPageSize(try DivNeighbourPageSize(dictionary: dictionary, context: context)) + case DivPageContentSize.type: + self = .divPageContentSize(try DivPageContentSize(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-pager-layout-mode", representation: dictionary) + } + } +} + #if DEBUG extension DivPagerLayoutMode: Equatable { public static func ==(lhs: DivPagerLayoutMode, rhs: DivPagerLayoutMode) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivPatch.swift b/client/ios/DivKit/generated_sources/DivPatch.swift index ae4b7ece2..7d3f59dcd 100644 --- a/client/ios/DivKit/generated_sources/DivPatch.swift +++ b/client/ios/DivKit/generated_sources/DivPatch.swift @@ -15,6 +15,13 @@ public final class DivPatch: Sendable { public let id: String public let items: [Div]? + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + id: try dictionary.getField("id", context: context), + items: try dictionary.getOptionalArray("items", transform: { (dict: [String: Any]) in try? Div(dictionary: dict, context: context) }) + ) + } + init( id: String, items: [Div]? = nil @@ -36,6 +43,15 @@ public final class DivPatch: Sendable { static let changesValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + changes: try dictionary.getArray("changes", transform: { (dict: [String: Any]) in try? DivPatch.Change(dictionary: dict, context: context) }, validator: Self.changesValidator), + mode: try dictionary.getOptionalExpressionField("mode", context: context), + onAppliedActions: try dictionary.getOptionalArray("on_applied_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + onFailedActions: try dictionary.getOptionalArray("on_failed_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }) + ) + } + init( changes: [Change], mode: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivPercentageSize.swift b/client/ios/DivKit/generated_sources/DivPercentageSize.swift index 4de4ed069..669beefb9 100644 --- a/client/ios/DivKit/generated_sources/DivPercentageSize.swift +++ b/client/ios/DivKit/generated_sources/DivPercentageSize.swift @@ -15,6 +15,12 @@ public final class DivPercentageSize: Sendable { static let valueValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 > 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", validator: Self.valueValidator, context: context) + ) + } + init( value: Expression ) { diff --git a/client/ios/DivKit/generated_sources/DivPercentageTranslation.swift b/client/ios/DivKit/generated_sources/DivPercentageTranslation.swift index 343a30d0e..c34391330 100644 --- a/client/ios/DivKit/generated_sources/DivPercentageTranslation.swift +++ b/client/ios/DivKit/generated_sources/DivPercentageTranslation.swift @@ -12,6 +12,12 @@ public final class DivPercentageTranslation: Sendable { resolver.resolveNumeric(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( value: Expression ) { diff --git a/client/ios/DivKit/generated_sources/DivPhoneInputMask.swift b/client/ios/DivKit/generated_sources/DivPhoneInputMask.swift index 52cbf257e..590c1dc15 100644 --- a/client/ios/DivKit/generated_sources/DivPhoneInputMask.swift +++ b/client/ios/DivKit/generated_sources/DivPhoneInputMask.swift @@ -8,6 +8,12 @@ public final class DivPhoneInputMask: DivInputMaskBase, Sendable { public static let type: String = "phone" public let rawTextVariable: String + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + rawTextVariable: try dictionary.getField("raw_text_variable", context: context) + ) + } + init( rawTextVariable: String ) { diff --git a/client/ios/DivKit/generated_sources/DivPivot.swift b/client/ios/DivKit/generated_sources/DivPivot.swift index 324b5d0bb..11273abe7 100644 --- a/client/ios/DivKit/generated_sources/DivPivot.swift +++ b/client/ios/DivKit/generated_sources/DivPivot.swift @@ -19,6 +19,20 @@ public enum DivPivot: Sendable { } } +extension DivPivot { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivPivotFixed.type: + self = .divPivotFixed(try DivPivotFixed(dictionary: dictionary, context: context)) + case DivPivotPercentage.type: + self = .divPivotPercentage(try DivPivotPercentage(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-pivot", representation: dictionary) + } + } +} + #if DEBUG extension DivPivot: Equatable { public static func ==(lhs: DivPivot, rhs: DivPivot) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivPivotFixed.swift b/client/ios/DivKit/generated_sources/DivPivotFixed.swift index 76371ed3e..27dd210bd 100644 --- a/client/ios/DivKit/generated_sources/DivPivotFixed.swift +++ b/client/ios/DivKit/generated_sources/DivPivotFixed.swift @@ -17,6 +17,13 @@ public final class DivPivotFixed: Sendable { resolver.resolveNumeric(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + unit: try dictionary.getOptionalExpressionField("unit", context: context), + value: try dictionary.getOptionalExpressionField("value", context: context) + ) + } + init( unit: Expression? = nil, value: Expression? = nil diff --git a/client/ios/DivKit/generated_sources/DivPivotPercentage.swift b/client/ios/DivKit/generated_sources/DivPivotPercentage.swift index b60721acd..248c15bef 100644 --- a/client/ios/DivKit/generated_sources/DivPivotPercentage.swift +++ b/client/ios/DivKit/generated_sources/DivPivotPercentage.swift @@ -12,6 +12,12 @@ public final class DivPivotPercentage: Sendable { resolver.resolveNumeric(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( value: Expression ) { diff --git a/client/ios/DivKit/generated_sources/DivPoint.swift b/client/ios/DivKit/generated_sources/DivPoint.swift index 915ec0b88..77aa17a72 100644 --- a/client/ios/DivKit/generated_sources/DivPoint.swift +++ b/client/ios/DivKit/generated_sources/DivPoint.swift @@ -8,6 +8,13 @@ public final class DivPoint: Sendable { public let x: DivDimension public let y: DivDimension + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + x: try dictionary.getField("x", transform: { (dict: [String: Any]) in try DivDimension(dictionary: dict, context: context) }), + y: try dictionary.getField("y", transform: { (dict: [String: Any]) in try DivDimension(dictionary: dict, context: context) }) + ) + } + init( x: DivDimension, y: DivDimension diff --git a/client/ios/DivKit/generated_sources/DivRadialGradient.swift b/client/ios/DivKit/generated_sources/DivRadialGradient.swift index 52114237a..34ca87bc9 100644 --- a/client/ios/DivKit/generated_sources/DivRadialGradient.swift +++ b/client/ios/DivKit/generated_sources/DivRadialGradient.swift @@ -20,6 +20,13 @@ public final class DivRadialGradient: Sendable { static let positionValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0.0 && $0 <= 1.0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + color: try dictionary.getExpressionField("color", transform: Color.color(withHexString:), context: context), + position: try dictionary.getExpressionField("position", validator: Self.positionValidator, context: context) + ) + } + init( color: Expression, position: Expression @@ -46,6 +53,16 @@ public final class DivRadialGradient: Sendable { static let colorsValidator: AnyArrayValueValidator> = makeArrayValidator(minItems: 2) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + centerX: try dictionary.getOptionalField("center_x", transform: { (dict: [String: Any]) in try DivRadialGradientCenter(dictionary: dict, context: context) }), + centerY: try dictionary.getOptionalField("center_y", transform: { (dict: [String: Any]) in try DivRadialGradientCenter(dictionary: dict, context: context) }), + colorMap: try dictionary.getOptionalArray("color_map", transform: { (dict: [String: Any]) in try? DivRadialGradient.ColorPoint(dictionary: dict, context: context) }, validator: Self.colorMapValidator), + colors: try dictionary.getOptionalExpressionArray("colors", transform: Color.color(withHexString:), validator: Self.colorsValidator, context: context), + radius: try dictionary.getOptionalField("radius", transform: { (dict: [String: Any]) in try DivRadialGradientRadius(dictionary: dict, context: context) }) + ) + } + init( centerX: DivRadialGradientCenter? = nil, centerY: DivRadialGradientCenter? = nil, diff --git a/client/ios/DivKit/generated_sources/DivRadialGradientCenter.swift b/client/ios/DivKit/generated_sources/DivRadialGradientCenter.swift index 0955ef6e4..2c95865bd 100644 --- a/client/ios/DivKit/generated_sources/DivRadialGradientCenter.swift +++ b/client/ios/DivKit/generated_sources/DivRadialGradientCenter.swift @@ -19,6 +19,20 @@ public enum DivRadialGradientCenter: Sendable { } } +extension DivRadialGradientCenter { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivRadialGradientFixedCenter.type: + self = .divRadialGradientFixedCenter(try DivRadialGradientFixedCenter(dictionary: dictionary, context: context)) + case DivRadialGradientRelativeCenter.type: + self = .divRadialGradientRelativeCenter(try DivRadialGradientRelativeCenter(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-radial-gradient-center", representation: dictionary) + } + } +} + #if DEBUG extension DivRadialGradientCenter: Equatable { public static func ==(lhs: DivRadialGradientCenter, rhs: DivRadialGradientCenter) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivRadialGradientFixedCenter.swift b/client/ios/DivKit/generated_sources/DivRadialGradientFixedCenter.swift index 2a365a9fe..72601bcdf 100644 --- a/client/ios/DivKit/generated_sources/DivRadialGradientFixedCenter.swift +++ b/client/ios/DivKit/generated_sources/DivRadialGradientFixedCenter.swift @@ -17,6 +17,13 @@ public final class DivRadialGradientFixedCenter: Sendable { resolver.resolveNumeric(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + unit: try dictionary.getOptionalExpressionField("unit", context: context), + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( unit: Expression? = nil, value: Expression diff --git a/client/ios/DivKit/generated_sources/DivRadialGradientRadius.swift b/client/ios/DivKit/generated_sources/DivRadialGradientRadius.swift index ea9f3dcca..affa48442 100644 --- a/client/ios/DivKit/generated_sources/DivRadialGradientRadius.swift +++ b/client/ios/DivKit/generated_sources/DivRadialGradientRadius.swift @@ -19,6 +19,20 @@ public enum DivRadialGradientRadius: Sendable { } } +extension DivRadialGradientRadius { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivFixedSize.type: + self = .divFixedSize(try DivFixedSize(dictionary: dictionary, context: context)) + case DivRadialGradientRelativeRadius.type: + self = .divRadialGradientRelativeRadius(try DivRadialGradientRelativeRadius(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-radial-gradient-radius", representation: dictionary) + } + } +} + #if DEBUG extension DivRadialGradientRadius: Equatable { public static func ==(lhs: DivRadialGradientRadius, rhs: DivRadialGradientRadius) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivRadialGradientRelativeCenter.swift b/client/ios/DivKit/generated_sources/DivRadialGradientRelativeCenter.swift index ccd395ea5..e8049c4b8 100644 --- a/client/ios/DivKit/generated_sources/DivRadialGradientRelativeCenter.swift +++ b/client/ios/DivKit/generated_sources/DivRadialGradientRelativeCenter.swift @@ -12,6 +12,12 @@ public final class DivRadialGradientRelativeCenter: Sendable { resolver.resolveNumeric(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( value: Expression ) { diff --git a/client/ios/DivKit/generated_sources/DivRadialGradientRelativeRadius.swift b/client/ios/DivKit/generated_sources/DivRadialGradientRelativeRadius.swift index 84cde24eb..2708edcd3 100644 --- a/client/ios/DivKit/generated_sources/DivRadialGradientRelativeRadius.swift +++ b/client/ios/DivKit/generated_sources/DivRadialGradientRelativeRadius.swift @@ -20,6 +20,12 @@ public final class DivRadialGradientRelativeRadius: Sendable { resolver.resolveEnum(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( value: Expression ) { diff --git a/client/ios/DivKit/generated_sources/DivRotationTransformation.swift b/client/ios/DivKit/generated_sources/DivRotationTransformation.swift index 2cedb8a19..67ad30035 100644 --- a/client/ios/DivKit/generated_sources/DivRotationTransformation.swift +++ b/client/ios/DivKit/generated_sources/DivRotationTransformation.swift @@ -14,6 +14,14 @@ public final class DivRotationTransformation: Sendable { resolver.resolveNumeric(angle) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + angle: try dictionary.getExpressionField("angle", context: context), + pivotX: try dictionary.getOptionalField("pivot_x", transform: { (dict: [String: Any]) in try DivPivot(dictionary: dict, context: context) }), + pivotY: try dictionary.getOptionalField("pivot_y", transform: { (dict: [String: Any]) in try DivPivot(dictionary: dict, context: context) }) + ) + } + init( angle: Expression, pivotX: DivPivot? = nil, diff --git a/client/ios/DivKit/generated_sources/DivRoundedRectangleShape.swift b/client/ios/DivKit/generated_sources/DivRoundedRectangleShape.swift index 2c728d39a..2251f8c99 100644 --- a/client/ios/DivKit/generated_sources/DivRoundedRectangleShape.swift +++ b/client/ios/DivKit/generated_sources/DivRoundedRectangleShape.swift @@ -16,6 +16,16 @@ public final class DivRoundedRectangleShape: Sendable { resolver.resolveColor(backgroundColor) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + backgroundColor: try dictionary.getOptionalExpressionField("background_color", transform: Color.color(withHexString:), context: context), + cornerRadius: try dictionary.getOptionalField("corner_radius", transform: { (dict: [String: Any]) in try DivFixedSize(dictionary: dict, context: context) }), + itemHeight: try dictionary.getOptionalField("item_height", transform: { (dict: [String: Any]) in try DivFixedSize(dictionary: dict, context: context) }), + itemWidth: try dictionary.getOptionalField("item_width", transform: { (dict: [String: Any]) in try DivFixedSize(dictionary: dict, context: context) }), + stroke: try dictionary.getOptionalField("stroke", transform: { (dict: [String: Any]) in try DivStroke(dictionary: dict, context: context) }) + ) + } + init( backgroundColor: Expression? = nil, cornerRadius: DivFixedSize? = nil, diff --git a/client/ios/DivKit/generated_sources/DivScaleTransition.swift b/client/ios/DivKit/generated_sources/DivScaleTransition.swift index 10e09e83d..91a4bbde0 100644 --- a/client/ios/DivKit/generated_sources/DivScaleTransition.swift +++ b/client/ios/DivKit/generated_sources/DivScaleTransition.swift @@ -52,6 +52,17 @@ public final class DivScaleTransition: DivTransitionBase, Sendable { static let startDelayValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + duration: try dictionary.getOptionalExpressionField("duration", validator: Self.durationValidator, context: context), + interpolator: try dictionary.getOptionalExpressionField("interpolator", context: context), + pivotX: try dictionary.getOptionalExpressionField("pivot_x", validator: Self.pivotXValidator, context: context), + pivotY: try dictionary.getOptionalExpressionField("pivot_y", validator: Self.pivotYValidator, context: context), + scale: try dictionary.getOptionalExpressionField("scale", validator: Self.scaleValidator, context: context), + startDelay: try dictionary.getOptionalExpressionField("start_delay", validator: Self.startDelayValidator, context: context) + ) + } + init( duration: Expression? = nil, interpolator: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivSelect.swift b/client/ios/DivKit/generated_sources/DivSelect.swift index 6d1a032c4..714382218 100644 --- a/client/ios/DivKit/generated_sources/DivSelect.swift +++ b/client/ios/DivKit/generated_sources/DivSelect.swift @@ -17,6 +17,13 @@ public final class DivSelect: DivBase, @unchecked Sendable { resolver.resolveString(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + text: try dictionary.getOptionalExpressionField("text", context: context), + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( text: Expression? = nil, value: Expression @@ -170,6 +177,57 @@ public final class DivSelect: DivBase, @unchecked Sendable { static let transitionTriggersValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + accessibility: try dictionary.getOptionalField("accessibility", transform: { (dict: [String: Any]) in try DivAccessibility(dictionary: dict, context: context) }), + alignmentHorizontal: try dictionary.getOptionalExpressionField("alignment_horizontal", context: context), + alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical", context: context), + alpha: try dictionary.getOptionalExpressionField("alpha", validator: Self.alphaValidator, context: context), + animators: try dictionary.getOptionalArray("animators", transform: { (dict: [String: Any]) in try? DivAnimator(dictionary: dict, context: context) }), + background: try dictionary.getOptionalArray("background", transform: { (dict: [String: Any]) in try? DivBackground(dictionary: dict, context: context) }), + border: try dictionary.getOptionalField("border", transform: { (dict: [String: Any]) in try DivBorder(dictionary: dict, context: context) }), + columnSpan: try dictionary.getOptionalExpressionField("column_span", validator: Self.columnSpanValidator, context: context), + disappearActions: try dictionary.getOptionalArray("disappear_actions", transform: { (dict: [String: Any]) in try? DivDisappearAction(dictionary: dict, context: context) }), + extensions: try dictionary.getOptionalArray("extensions", transform: { (dict: [String: Any]) in try? DivExtension(dictionary: dict, context: context) }), + focus: try dictionary.getOptionalField("focus", transform: { (dict: [String: Any]) in try DivFocus(dictionary: dict, context: context) }), + fontFamily: try dictionary.getOptionalExpressionField("font_family", context: context), + fontSize: try dictionary.getOptionalExpressionField("font_size", validator: Self.fontSizeValidator, context: context), + fontSizeUnit: try dictionary.getOptionalExpressionField("font_size_unit", context: context), + fontVariationSettings: try dictionary.getOptionalExpressionField("font_variation_settings", context: context), + fontWeight: try dictionary.getOptionalExpressionField("font_weight", context: context), + fontWeightValue: try dictionary.getOptionalExpressionField("font_weight_value", validator: Self.fontWeightValueValidator, context: context), + functions: try dictionary.getOptionalArray("functions", transform: { (dict: [String: Any]) in try? DivFunction(dictionary: dict, context: context) }), + height: try dictionary.getOptionalField("height", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }), + hintColor: try dictionary.getOptionalExpressionField("hint_color", transform: Color.color(withHexString:), context: context), + hintText: try dictionary.getOptionalExpressionField("hint_text", context: context), + id: try dictionary.getOptionalField("id", context: context), + layoutProvider: try dictionary.getOptionalField("layout_provider", transform: { (dict: [String: Any]) in try DivLayoutProvider(dictionary: dict, context: context) }), + letterSpacing: try dictionary.getOptionalExpressionField("letter_spacing", context: context), + lineHeight: try dictionary.getOptionalExpressionField("line_height", validator: Self.lineHeightValidator, context: context), + margins: try dictionary.getOptionalField("margins", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + options: try dictionary.getArray("options", transform: { (dict: [String: Any]) in try? DivSelect.Option(dictionary: dict, context: context) }, validator: Self.optionsValidator), + paddings: try dictionary.getOptionalField("paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + reuseId: try dictionary.getOptionalExpressionField("reuse_id", context: context), + rowSpan: try dictionary.getOptionalExpressionField("row_span", validator: Self.rowSpanValidator, context: context), + selectedActions: try dictionary.getOptionalArray("selected_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + textColor: try dictionary.getOptionalExpressionField("text_color", transform: Color.color(withHexString:), context: context), + tooltips: try dictionary.getOptionalArray("tooltips", transform: { (dict: [String: Any]) in try? DivTooltip(dictionary: dict, context: context) }), + transform: try dictionary.getOptionalField("transform", transform: { (dict: [String: Any]) in try DivTransform(dictionary: dict, context: context) }), + transformations: try dictionary.getOptionalArray("transformations", transform: { (dict: [String: Any]) in try? DivTransformation(dictionary: dict, context: context) }), + transitionChange: try dictionary.getOptionalField("transition_change", transform: { (dict: [String: Any]) in try DivChangeTransition(dictionary: dict, context: context) }), + transitionIn: try dictionary.getOptionalField("transition_in", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionOut: try dictionary.getOptionalField("transition_out", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionTriggers: try dictionary.getOptionalArray("transition_triggers", validator: Self.transitionTriggersValidator, context: context), + valueVariable: try dictionary.getField("value_variable", context: context), + variableTriggers: try dictionary.getOptionalArray("variable_triggers", transform: { (dict: [String: Any]) in try? DivTrigger(dictionary: dict, context: context) }), + variables: try dictionary.getOptionalArray("variables", transform: { (dict: [String: Any]) in try? DivVariable(dictionary: dict, context: context) }), + visibility: try dictionary.getOptionalExpressionField("visibility", context: context), + visibilityAction: try dictionary.getOptionalField("visibility_action", transform: { (dict: [String: Any]) in try DivVisibilityAction(dictionary: dict, context: context) }), + visibilityActions: try dictionary.getOptionalArray("visibility_actions", transform: { (dict: [String: Any]) in try? DivVisibilityAction(dictionary: dict, context: context) }), + width: try dictionary.getOptionalField("width", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }) + ) + } + init( accessibility: DivAccessibility? = nil, alignmentHorizontal: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivSeparator.swift b/client/ios/DivKit/generated_sources/DivSeparator.swift index 0ffbe9842..19c8db150 100644 --- a/client/ios/DivKit/generated_sources/DivSeparator.swift +++ b/client/ios/DivKit/generated_sources/DivSeparator.swift @@ -23,6 +23,13 @@ public final class DivSeparator: DivBase, Sendable { resolver.resolveEnum(orientation) ?? Orientation.horizontal } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + color: try dictionary.getOptionalExpressionField("color", transform: Color.color(withHexString:), context: context), + orientation: try dictionary.getOptionalExpressionField("orientation", context: context) + ) + } + init( color: Expression? = nil, orientation: Expression? = nil @@ -122,6 +129,55 @@ public final class DivSeparator: DivBase, Sendable { static let transitionTriggersValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + accessibility: try dictionary.getOptionalField("accessibility", transform: { (dict: [String: Any]) in try DivAccessibility(dictionary: dict, context: context) }), + action: try dictionary.getOptionalField("action", transform: { (dict: [String: Any]) in try DivAction(dictionary: dict, context: context) }), + actionAnimation: try dictionary.getOptionalField("action_animation", transform: { (dict: [String: Any]) in try DivAnimation(dictionary: dict, context: context) }), + actions: try dictionary.getOptionalArray("actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + alignmentHorizontal: try dictionary.getOptionalExpressionField("alignment_horizontal", context: context), + alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical", context: context), + alpha: try dictionary.getOptionalExpressionField("alpha", validator: Self.alphaValidator, context: context), + animators: try dictionary.getOptionalArray("animators", transform: { (dict: [String: Any]) in try? DivAnimator(dictionary: dict, context: context) }), + background: try dictionary.getOptionalArray("background", transform: { (dict: [String: Any]) in try? DivBackground(dictionary: dict, context: context) }), + border: try dictionary.getOptionalField("border", transform: { (dict: [String: Any]) in try DivBorder(dictionary: dict, context: context) }), + captureFocusOnAction: try dictionary.getOptionalExpressionField("capture_focus_on_action", context: context), + columnSpan: try dictionary.getOptionalExpressionField("column_span", validator: Self.columnSpanValidator, context: context), + delimiterStyle: try dictionary.getOptionalField("delimiter_style", transform: { (dict: [String: Any]) in try DivSeparator.DelimiterStyle(dictionary: dict, context: context) }), + disappearActions: try dictionary.getOptionalArray("disappear_actions", transform: { (dict: [String: Any]) in try? DivDisappearAction(dictionary: dict, context: context) }), + doubletapActions: try dictionary.getOptionalArray("doubletap_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + extensions: try dictionary.getOptionalArray("extensions", transform: { (dict: [String: Any]) in try? DivExtension(dictionary: dict, context: context) }), + focus: try dictionary.getOptionalField("focus", transform: { (dict: [String: Any]) in try DivFocus(dictionary: dict, context: context) }), + functions: try dictionary.getOptionalArray("functions", transform: { (dict: [String: Any]) in try? DivFunction(dictionary: dict, context: context) }), + height: try dictionary.getOptionalField("height", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }), + hoverEndActions: try dictionary.getOptionalArray("hover_end_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + hoverStartActions: try dictionary.getOptionalArray("hover_start_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + id: try dictionary.getOptionalField("id", context: context), + layoutProvider: try dictionary.getOptionalField("layout_provider", transform: { (dict: [String: Any]) in try DivLayoutProvider(dictionary: dict, context: context) }), + longtapActions: try dictionary.getOptionalArray("longtap_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + margins: try dictionary.getOptionalField("margins", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + paddings: try dictionary.getOptionalField("paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + pressEndActions: try dictionary.getOptionalArray("press_end_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + pressStartActions: try dictionary.getOptionalArray("press_start_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + reuseId: try dictionary.getOptionalExpressionField("reuse_id", context: context), + rowSpan: try dictionary.getOptionalExpressionField("row_span", validator: Self.rowSpanValidator, context: context), + selectedActions: try dictionary.getOptionalArray("selected_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + tooltips: try dictionary.getOptionalArray("tooltips", transform: { (dict: [String: Any]) in try? DivTooltip(dictionary: dict, context: context) }), + transform: try dictionary.getOptionalField("transform", transform: { (dict: [String: Any]) in try DivTransform(dictionary: dict, context: context) }), + transformations: try dictionary.getOptionalArray("transformations", transform: { (dict: [String: Any]) in try? DivTransformation(dictionary: dict, context: context) }), + transitionChange: try dictionary.getOptionalField("transition_change", transform: { (dict: [String: Any]) in try DivChangeTransition(dictionary: dict, context: context) }), + transitionIn: try dictionary.getOptionalField("transition_in", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionOut: try dictionary.getOptionalField("transition_out", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionTriggers: try dictionary.getOptionalArray("transition_triggers", validator: Self.transitionTriggersValidator, context: context), + variableTriggers: try dictionary.getOptionalArray("variable_triggers", transform: { (dict: [String: Any]) in try? DivTrigger(dictionary: dict, context: context) }), + variables: try dictionary.getOptionalArray("variables", transform: { (dict: [String: Any]) in try? DivVariable(dictionary: dict, context: context) }), + visibility: try dictionary.getOptionalExpressionField("visibility", context: context), + visibilityAction: try dictionary.getOptionalField("visibility_action", transform: { (dict: [String: Any]) in try DivVisibilityAction(dictionary: dict, context: context) }), + visibilityActions: try dictionary.getOptionalArray("visibility_actions", transform: { (dict: [String: Any]) in try? DivVisibilityAction(dictionary: dict, context: context) }), + width: try dictionary.getOptionalField("width", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }) + ) + } + init( accessibility: DivAccessibility? = nil, action: DivAction? = nil, diff --git a/client/ios/DivKit/generated_sources/DivShadow.swift b/client/ios/DivKit/generated_sources/DivShadow.swift index 2ca1586c9..dbb9c0cfe 100644 --- a/client/ios/DivKit/generated_sources/DivShadow.swift +++ b/client/ios/DivKit/generated_sources/DivShadow.swift @@ -28,6 +28,15 @@ public final class DivShadow: Sendable { static let blurValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + alpha: try dictionary.getOptionalExpressionField("alpha", validator: Self.alphaValidator, context: context), + blur: try dictionary.getOptionalExpressionField("blur", validator: Self.blurValidator, context: context), + color: try dictionary.getOptionalExpressionField("color", transform: Color.color(withHexString:), context: context), + offset: try dictionary.getField("offset", transform: { (dict: [String: Any]) in try DivPoint(dictionary: dict, context: context) }) + ) + } + init( alpha: Expression? = nil, blur: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivShape.swift b/client/ios/DivKit/generated_sources/DivShape.swift index 2069acccf..c45f87abd 100644 --- a/client/ios/DivKit/generated_sources/DivShape.swift +++ b/client/ios/DivKit/generated_sources/DivShape.swift @@ -19,6 +19,20 @@ public enum DivShape: Sendable { } } +extension DivShape { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivRoundedRectangleShape.type: + self = .divRoundedRectangleShape(try DivRoundedRectangleShape(dictionary: dictionary, context: context)) + case DivCircleShape.type: + self = .divCircleShape(try DivCircleShape(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-shape", representation: dictionary) + } + } +} + #if DEBUG extension DivShape: Equatable { public static func ==(lhs: DivShape, rhs: DivShape) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivShapeDrawable.swift b/client/ios/DivKit/generated_sources/DivShapeDrawable.swift index 17d373102..a8b0a3501 100644 --- a/client/ios/DivKit/generated_sources/DivShapeDrawable.swift +++ b/client/ios/DivKit/generated_sources/DivShapeDrawable.swift @@ -14,6 +14,14 @@ public final class DivShapeDrawable: Sendable { resolver.resolveColor(color) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + color: try dictionary.getExpressionField("color", transform: Color.color(withHexString:), context: context), + shape: try dictionary.getField("shape", transform: { (dict: [String: Any]) in try DivShape(dictionary: dict, context: context) }), + stroke: try dictionary.getOptionalField("stroke", transform: { (dict: [String: Any]) in try DivStroke(dictionary: dict, context: context) }) + ) + } + init( color: Expression, shape: DivShape, diff --git a/client/ios/DivKit/generated_sources/DivSize.swift b/client/ios/DivKit/generated_sources/DivSize.swift index 5d7a264e4..36b53d2df 100644 --- a/client/ios/DivKit/generated_sources/DivSize.swift +++ b/client/ios/DivKit/generated_sources/DivSize.swift @@ -22,6 +22,22 @@ public enum DivSize: Sendable { } } +extension DivSize { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivFixedSize.type: + self = .divFixedSize(try DivFixedSize(dictionary: dictionary, context: context)) + case DivMatchParentSize.type: + self = .divMatchParentSize(try DivMatchParentSize(dictionary: dictionary, context: context)) + case DivWrapContentSize.type: + self = .divWrapContentSize(try DivWrapContentSize(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-size", representation: dictionary) + } + } +} + #if DEBUG extension DivSize: Equatable { public static func ==(lhs: DivSize, rhs: DivSize) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivSizeUnitValue.swift b/client/ios/DivKit/generated_sources/DivSizeUnitValue.swift index ceb474b0c..a8ac5467f 100644 --- a/client/ios/DivKit/generated_sources/DivSizeUnitValue.swift +++ b/client/ios/DivKit/generated_sources/DivSizeUnitValue.swift @@ -19,6 +19,13 @@ public final class DivSizeUnitValue: Sendable { static let valueValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + unit: try dictionary.getOptionalExpressionField("unit", context: context), + value: try dictionary.getExpressionField("value", validator: Self.valueValidator, context: context) + ) + } + init( unit: Expression? = nil, value: Expression diff --git a/client/ios/DivKit/generated_sources/DivSlideTransition.swift b/client/ios/DivKit/generated_sources/DivSlideTransition.swift index b0734f102..7bb01d585 100644 --- a/client/ios/DivKit/generated_sources/DivSlideTransition.swift +++ b/client/ios/DivKit/generated_sources/DivSlideTransition.swift @@ -42,6 +42,16 @@ public final class DivSlideTransition: DivTransitionBase, Sendable { static let startDelayValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + distance: try dictionary.getOptionalField("distance", transform: { (dict: [String: Any]) in try DivDimension(dictionary: dict, context: context) }), + duration: try dictionary.getOptionalExpressionField("duration", validator: Self.durationValidator, context: context), + edge: try dictionary.getOptionalExpressionField("edge", context: context), + interpolator: try dictionary.getOptionalExpressionField("interpolator", context: context), + startDelay: try dictionary.getOptionalExpressionField("start_delay", validator: Self.startDelayValidator, context: context) + ) + } + init( distance: DivDimension? = nil, duration: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivSlider.swift b/client/ios/DivKit/generated_sources/DivSlider.swift index c50cc997f..4e21620d3 100644 --- a/client/ios/DivKit/generated_sources/DivSlider.swift +++ b/client/ios/DivKit/generated_sources/DivSlider.swift @@ -20,6 +20,16 @@ public final class DivSlider: DivBase, Sendable { resolver.resolveNumeric(start) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + end: try dictionary.getOptionalExpressionField("end", context: context), + margins: try dictionary.getOptionalField("margins", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + start: try dictionary.getOptionalExpressionField("start", context: context), + trackActiveStyle: try dictionary.getOptionalField("track_active_style", transform: { (dict: [String: Any]) in try DivDrawable(dictionary: dict, context: context) }), + trackInactiveStyle: try dictionary.getOptionalField("track_inactive_style", transform: { (dict: [String: Any]) in try DivDrawable(dictionary: dict, context: context) }) + ) + } + init( end: Expression? = nil, margins: DivEdgeInsets? = nil, @@ -84,6 +94,20 @@ public final class DivSlider: DivBase, Sendable { static let fontWeightValueValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 > 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + fontFamily: try dictionary.getOptionalExpressionField("font_family", context: context), + fontSize: try dictionary.getOptionalExpressionField("font_size", validator: Self.fontSizeValidator, context: context), + fontSizeUnit: try dictionary.getOptionalExpressionField("font_size_unit", context: context), + fontVariationSettings: try dictionary.getOptionalExpressionField("font_variation_settings", context: context), + fontWeight: try dictionary.getOptionalExpressionField("font_weight", context: context), + fontWeightValue: try dictionary.getOptionalExpressionField("font_weight_value", validator: Self.fontWeightValueValidator, context: context), + letterSpacing: try dictionary.getOptionalExpressionField("letter_spacing", context: context), + offset: try dictionary.getOptionalField("offset", transform: { (dict: [String: Any]) in try DivPoint(dictionary: dict, context: context) }), + textColor: try dictionary.getOptionalExpressionField("text_color", transform: Color.color(withHexString:), context: context) + ) + } + init( fontFamily: Expression? = nil, fontSize: Expression? = nil, @@ -209,6 +233,59 @@ public final class DivSlider: DivBase, Sendable { static let transitionTriggersValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + accessibility: try dictionary.getOptionalField("accessibility", transform: { (dict: [String: Any]) in try DivAccessibility(dictionary: dict, context: context) }), + alignmentHorizontal: try dictionary.getOptionalExpressionField("alignment_horizontal", context: context), + alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical", context: context), + alpha: try dictionary.getOptionalExpressionField("alpha", validator: Self.alphaValidator, context: context), + animators: try dictionary.getOptionalArray("animators", transform: { (dict: [String: Any]) in try? DivAnimator(dictionary: dict, context: context) }), + background: try dictionary.getOptionalArray("background", transform: { (dict: [String: Any]) in try? DivBackground(dictionary: dict, context: context) }), + border: try dictionary.getOptionalField("border", transform: { (dict: [String: Any]) in try DivBorder(dictionary: dict, context: context) }), + columnSpan: try dictionary.getOptionalExpressionField("column_span", validator: Self.columnSpanValidator, context: context), + disappearActions: try dictionary.getOptionalArray("disappear_actions", transform: { (dict: [String: Any]) in try? DivDisappearAction(dictionary: dict, context: context) }), + extensions: try dictionary.getOptionalArray("extensions", transform: { (dict: [String: Any]) in try? DivExtension(dictionary: dict, context: context) }), + focus: try dictionary.getOptionalField("focus", transform: { (dict: [String: Any]) in try DivFocus(dictionary: dict, context: context) }), + functions: try dictionary.getOptionalArray("functions", transform: { (dict: [String: Any]) in try? DivFunction(dictionary: dict, context: context) }), + height: try dictionary.getOptionalField("height", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }), + id: try dictionary.getOptionalField("id", context: context), + isEnabled: try dictionary.getOptionalExpressionField("is_enabled", context: context), + layoutProvider: try dictionary.getOptionalField("layout_provider", transform: { (dict: [String: Any]) in try DivLayoutProvider(dictionary: dict, context: context) }), + margins: try dictionary.getOptionalField("margins", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + maxValue: try dictionary.getOptionalExpressionField("max_value", context: context), + minValue: try dictionary.getOptionalExpressionField("min_value", context: context), + paddings: try dictionary.getOptionalField("paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + ranges: try dictionary.getOptionalArray("ranges", transform: { (dict: [String: Any]) in try? DivSlider.Range(dictionary: dict, context: context) }), + reuseId: try dictionary.getOptionalExpressionField("reuse_id", context: context), + rowSpan: try dictionary.getOptionalExpressionField("row_span", validator: Self.rowSpanValidator, context: context), + secondaryValueAccessibility: try dictionary.getOptionalField("secondary_value_accessibility", transform: { (dict: [String: Any]) in try DivAccessibility(dictionary: dict, context: context) }), + selectedActions: try dictionary.getOptionalArray("selected_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + thumbSecondaryStyle: try dictionary.getOptionalField("thumb_secondary_style", transform: { (dict: [String: Any]) in try DivDrawable(dictionary: dict, context: context) }), + thumbSecondaryTextStyle: try dictionary.getOptionalField("thumb_secondary_text_style", transform: { (dict: [String: Any]) in try DivSlider.TextStyle(dictionary: dict, context: context) }), + thumbSecondaryValueVariable: try dictionary.getOptionalField("thumb_secondary_value_variable", context: context), + thumbStyle: try dictionary.getField("thumb_style", transform: { (dict: [String: Any]) in try DivDrawable(dictionary: dict, context: context) }), + thumbTextStyle: try dictionary.getOptionalField("thumb_text_style", transform: { (dict: [String: Any]) in try DivSlider.TextStyle(dictionary: dict, context: context) }), + thumbValueVariable: try dictionary.getOptionalField("thumb_value_variable", context: context), + tickMarkActiveStyle: try dictionary.getOptionalField("tick_mark_active_style", transform: { (dict: [String: Any]) in try DivDrawable(dictionary: dict, context: context) }), + tickMarkInactiveStyle: try dictionary.getOptionalField("tick_mark_inactive_style", transform: { (dict: [String: Any]) in try DivDrawable(dictionary: dict, context: context) }), + tooltips: try dictionary.getOptionalArray("tooltips", transform: { (dict: [String: Any]) in try? DivTooltip(dictionary: dict, context: context) }), + trackActiveStyle: try dictionary.getField("track_active_style", transform: { (dict: [String: Any]) in try DivDrawable(dictionary: dict, context: context) }), + trackInactiveStyle: try dictionary.getField("track_inactive_style", transform: { (dict: [String: Any]) in try DivDrawable(dictionary: dict, context: context) }), + transform: try dictionary.getOptionalField("transform", transform: { (dict: [String: Any]) in try DivTransform(dictionary: dict, context: context) }), + transformations: try dictionary.getOptionalArray("transformations", transform: { (dict: [String: Any]) in try? DivTransformation(dictionary: dict, context: context) }), + transitionChange: try dictionary.getOptionalField("transition_change", transform: { (dict: [String: Any]) in try DivChangeTransition(dictionary: dict, context: context) }), + transitionIn: try dictionary.getOptionalField("transition_in", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionOut: try dictionary.getOptionalField("transition_out", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionTriggers: try dictionary.getOptionalArray("transition_triggers", validator: Self.transitionTriggersValidator, context: context), + variableTriggers: try dictionary.getOptionalArray("variable_triggers", transform: { (dict: [String: Any]) in try? DivTrigger(dictionary: dict, context: context) }), + variables: try dictionary.getOptionalArray("variables", transform: { (dict: [String: Any]) in try? DivVariable(dictionary: dict, context: context) }), + visibility: try dictionary.getOptionalExpressionField("visibility", context: context), + visibilityAction: try dictionary.getOptionalField("visibility_action", transform: { (dict: [String: Any]) in try DivVisibilityAction(dictionary: dict, context: context) }), + visibilityActions: try dictionary.getOptionalArray("visibility_actions", transform: { (dict: [String: Any]) in try? DivVisibilityAction(dictionary: dict, context: context) }), + width: try dictionary.getOptionalField("width", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }) + ) + } + init( accessibility: DivAccessibility? = nil, alignmentHorizontal: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivSolidBackground.swift b/client/ios/DivKit/generated_sources/DivSolidBackground.swift index 76ef61d1b..d6e2a4a11 100644 --- a/client/ios/DivKit/generated_sources/DivSolidBackground.swift +++ b/client/ios/DivKit/generated_sources/DivSolidBackground.swift @@ -12,6 +12,12 @@ public final class DivSolidBackground: Sendable { resolver.resolveColor(color) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + color: try dictionary.getExpressionField("color", transform: Color.color(withHexString:), context: context) + ) + } + init( color: Expression ) { diff --git a/client/ios/DivKit/generated_sources/DivState.swift b/client/ios/DivKit/generated_sources/DivState.swift index 1aed8f73e..ed8c3d3c1 100644 --- a/client/ios/DivKit/generated_sources/DivState.swift +++ b/client/ios/DivKit/generated_sources/DivState.swift @@ -12,6 +12,16 @@ public final class DivState: DivBase, Sendable { public let stateId: String public let swipeOutActions: [DivAction]? + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + animationIn: try dictionary.getOptionalField("animation_in", transform: { (dict: [String: Any]) in try DivAnimation(dictionary: dict, context: context) }), + animationOut: try dictionary.getOptionalField("animation_out", transform: { (dict: [String: Any]) in try DivAnimation(dictionary: dict, context: context) }), + div: try dictionary.getOptionalField("div", transform: { (dict: [String: Any]) in try Div(dictionary: dict, context: context) }), + stateId: try dictionary.getField("state_id", context: context), + swipeOutActions: try dictionary.getOptionalArray("swipe_out_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }) + ) + } + init( animationIn: DivAnimation?, animationOut: DivAnimation?, @@ -137,6 +147,60 @@ public final class DivState: DivBase, Sendable { static let transitionTriggersValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + accessibility: try dictionary.getOptionalField("accessibility", transform: { (dict: [String: Any]) in try DivAccessibility(dictionary: dict, context: context) }), + action: try dictionary.getOptionalField("action", transform: { (dict: [String: Any]) in try DivAction(dictionary: dict, context: context) }), + actionAnimation: try dictionary.getOptionalField("action_animation", transform: { (dict: [String: Any]) in try DivAnimation(dictionary: dict, context: context) }), + actions: try dictionary.getOptionalArray("actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + alignmentHorizontal: try dictionary.getOptionalExpressionField("alignment_horizontal", context: context), + alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical", context: context), + alpha: try dictionary.getOptionalExpressionField("alpha", validator: Self.alphaValidator, context: context), + animators: try dictionary.getOptionalArray("animators", transform: { (dict: [String: Any]) in try? DivAnimator(dictionary: dict, context: context) }), + background: try dictionary.getOptionalArray("background", transform: { (dict: [String: Any]) in try? DivBackground(dictionary: dict, context: context) }), + border: try dictionary.getOptionalField("border", transform: { (dict: [String: Any]) in try DivBorder(dictionary: dict, context: context) }), + captureFocusOnAction: try dictionary.getOptionalExpressionField("capture_focus_on_action", context: context), + clipToBounds: try dictionary.getOptionalExpressionField("clip_to_bounds", context: context), + columnSpan: try dictionary.getOptionalExpressionField("column_span", validator: Self.columnSpanValidator, context: context), + defaultStateId: try dictionary.getOptionalExpressionField("default_state_id", context: context), + disappearActions: try dictionary.getOptionalArray("disappear_actions", transform: { (dict: [String: Any]) in try? DivDisappearAction(dictionary: dict, context: context) }), + divId: try dictionary.getOptionalField("div_id", context: context), + doubletapActions: try dictionary.getOptionalArray("doubletap_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + extensions: try dictionary.getOptionalArray("extensions", transform: { (dict: [String: Any]) in try? DivExtension(dictionary: dict, context: context) }), + focus: try dictionary.getOptionalField("focus", transform: { (dict: [String: Any]) in try DivFocus(dictionary: dict, context: context) }), + functions: try dictionary.getOptionalArray("functions", transform: { (dict: [String: Any]) in try? DivFunction(dictionary: dict, context: context) }), + height: try dictionary.getOptionalField("height", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }), + hoverEndActions: try dictionary.getOptionalArray("hover_end_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + hoverStartActions: try dictionary.getOptionalArray("hover_start_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + id: try dictionary.getOptionalField("id", context: context), + layoutProvider: try dictionary.getOptionalField("layout_provider", transform: { (dict: [String: Any]) in try DivLayoutProvider(dictionary: dict, context: context) }), + longtapActions: try dictionary.getOptionalArray("longtap_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + margins: try dictionary.getOptionalField("margins", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + paddings: try dictionary.getOptionalField("paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + pressEndActions: try dictionary.getOptionalArray("press_end_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + pressStartActions: try dictionary.getOptionalArray("press_start_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + reuseId: try dictionary.getOptionalExpressionField("reuse_id", context: context), + rowSpan: try dictionary.getOptionalExpressionField("row_span", validator: Self.rowSpanValidator, context: context), + selectedActions: try dictionary.getOptionalArray("selected_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + stateIdVariable: try dictionary.getOptionalField("state_id_variable", context: context), + states: try dictionary.getArray("states", transform: { (dict: [String: Any]) in try? DivState.State(dictionary: dict, context: context) }, validator: Self.statesValidator), + tooltips: try dictionary.getOptionalArray("tooltips", transform: { (dict: [String: Any]) in try? DivTooltip(dictionary: dict, context: context) }), + transform: try dictionary.getOptionalField("transform", transform: { (dict: [String: Any]) in try DivTransform(dictionary: dict, context: context) }), + transformations: try dictionary.getOptionalArray("transformations", transform: { (dict: [String: Any]) in try? DivTransformation(dictionary: dict, context: context) }), + transitionAnimationSelector: try dictionary.getOptionalExpressionField("transition_animation_selector", context: context), + transitionChange: try dictionary.getOptionalField("transition_change", transform: { (dict: [String: Any]) in try DivChangeTransition(dictionary: dict, context: context) }), + transitionIn: try dictionary.getOptionalField("transition_in", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionOut: try dictionary.getOptionalField("transition_out", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionTriggers: try dictionary.getOptionalArray("transition_triggers", validator: Self.transitionTriggersValidator, context: context), + variableTriggers: try dictionary.getOptionalArray("variable_triggers", transform: { (dict: [String: Any]) in try? DivTrigger(dictionary: dict, context: context) }), + variables: try dictionary.getOptionalArray("variables", transform: { (dict: [String: Any]) in try? DivVariable(dictionary: dict, context: context) }), + visibility: try dictionary.getOptionalExpressionField("visibility", context: context), + visibilityAction: try dictionary.getOptionalField("visibility_action", transform: { (dict: [String: Any]) in try DivVisibilityAction(dictionary: dict, context: context) }), + visibilityActions: try dictionary.getOptionalArray("visibility_actions", transform: { (dict: [String: Any]) in try? DivVisibilityAction(dictionary: dict, context: context) }), + width: try dictionary.getOptionalField("width", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }) + ) + } + init( accessibility: DivAccessibility?, action: DivAction?, diff --git a/client/ios/DivKit/generated_sources/DivStretchIndicatorItemPlacement.swift b/client/ios/DivKit/generated_sources/DivStretchIndicatorItemPlacement.swift index 54926017a..b26d7bac0 100644 --- a/client/ios/DivKit/generated_sources/DivStretchIndicatorItemPlacement.swift +++ b/client/ios/DivKit/generated_sources/DivStretchIndicatorItemPlacement.swift @@ -16,6 +16,13 @@ public final class DivStretchIndicatorItemPlacement: Sendable { static let maxVisibleItemsValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 > 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + itemSpacing: try dictionary.getOptionalField("item_spacing", transform: { (dict: [String: Any]) in try DivFixedSize(dictionary: dict, context: context) }), + maxVisibleItems: try dictionary.getOptionalExpressionField("max_visible_items", validator: Self.maxVisibleItemsValidator, context: context) + ) + } + init( itemSpacing: DivFixedSize? = nil, maxVisibleItems: Expression? = nil diff --git a/client/ios/DivKit/generated_sources/DivStroke.swift b/client/ios/DivKit/generated_sources/DivStroke.swift index e0f576c77..d7a2f0ab9 100644 --- a/client/ios/DivKit/generated_sources/DivStroke.swift +++ b/client/ios/DivKit/generated_sources/DivStroke.swift @@ -25,6 +25,15 @@ public final class DivStroke: Sendable { static let widthValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + color: try dictionary.getExpressionField("color", transform: Color.color(withHexString:), context: context), + style: try dictionary.getOptionalField("style", transform: { (dict: [String: Any]) in try DivStrokeStyle(dictionary: dict, context: context) }), + unit: try dictionary.getOptionalExpressionField("unit", context: context), + width: try dictionary.getOptionalExpressionField("width", validator: Self.widthValidator, context: context) + ) + } + init( color: Expression, style: DivStrokeStyle? = nil, diff --git a/client/ios/DivKit/generated_sources/DivStrokeStyle.swift b/client/ios/DivKit/generated_sources/DivStrokeStyle.swift index 5ec56b50e..4a461a632 100644 --- a/client/ios/DivKit/generated_sources/DivStrokeStyle.swift +++ b/client/ios/DivKit/generated_sources/DivStrokeStyle.swift @@ -19,6 +19,20 @@ public enum DivStrokeStyle: Sendable { } } +extension DivStrokeStyle { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivStrokeStyleSolid.type: + self = .divStrokeStyleSolid(try DivStrokeStyleSolid(dictionary: dictionary, context: context)) + case DivStrokeStyleDashed.type: + self = .divStrokeStyleDashed(try DivStrokeStyleDashed(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-stroke-style", representation: dictionary) + } + } +} + #if DEBUG extension DivStrokeStyle: Equatable { public static func ==(lhs: DivStrokeStyle, rhs: DivStrokeStyle) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivStrokeStyleDashed.swift b/client/ios/DivKit/generated_sources/DivStrokeStyleDashed.swift index da9ae5b34..f80968fb7 100644 --- a/client/ios/DivKit/generated_sources/DivStrokeStyleDashed.swift +++ b/client/ios/DivKit/generated_sources/DivStrokeStyleDashed.swift @@ -7,6 +7,8 @@ import VGSL public final class DivStrokeStyleDashed: Sendable { public static let type: String = "dashed" + public init(dictionary: [String: Any], context: ParsingContext) throws {} + init() {} } diff --git a/client/ios/DivKit/generated_sources/DivStrokeStyleSolid.swift b/client/ios/DivKit/generated_sources/DivStrokeStyleSolid.swift index 993017d56..c17bf90fe 100644 --- a/client/ios/DivKit/generated_sources/DivStrokeStyleSolid.swift +++ b/client/ios/DivKit/generated_sources/DivStrokeStyleSolid.swift @@ -7,6 +7,8 @@ import VGSL public final class DivStrokeStyleSolid: Sendable { public static let type: String = "solid" + public init(dictionary: [String: Any], context: ParsingContext) throws {} + init() {} } diff --git a/client/ios/DivKit/generated_sources/DivSwitch.swift b/client/ios/DivKit/generated_sources/DivSwitch.swift index 714a9bebf..f1da68c23 100644 --- a/client/ios/DivKit/generated_sources/DivSwitch.swift +++ b/client/ios/DivKit/generated_sources/DivSwitch.swift @@ -91,6 +91,47 @@ public final class DivSwitch: DivBase, Sendable { static let transitionTriggersValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + accessibility: try dictionary.getOptionalField("accessibility", transform: { (dict: [String: Any]) in try DivAccessibility(dictionary: dict, context: context) }), + alignmentHorizontal: try dictionary.getOptionalExpressionField("alignment_horizontal", context: context), + alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical", context: context), + alpha: try dictionary.getOptionalExpressionField("alpha", validator: Self.alphaValidator, context: context), + animators: try dictionary.getOptionalArray("animators", transform: { (dict: [String: Any]) in try? DivAnimator(dictionary: dict, context: context) }), + background: try dictionary.getOptionalArray("background", transform: { (dict: [String: Any]) in try? DivBackground(dictionary: dict, context: context) }), + border: try dictionary.getOptionalField("border", transform: { (dict: [String: Any]) in try DivBorder(dictionary: dict, context: context) }), + columnSpan: try dictionary.getOptionalExpressionField("column_span", validator: Self.columnSpanValidator, context: context), + disappearActions: try dictionary.getOptionalArray("disappear_actions", transform: { (dict: [String: Any]) in try? DivDisappearAction(dictionary: dict, context: context) }), + extensions: try dictionary.getOptionalArray("extensions", transform: { (dict: [String: Any]) in try? DivExtension(dictionary: dict, context: context) }), + focus: try dictionary.getOptionalField("focus", transform: { (dict: [String: Any]) in try DivFocus(dictionary: dict, context: context) }), + functions: try dictionary.getOptionalArray("functions", transform: { (dict: [String: Any]) in try? DivFunction(dictionary: dict, context: context) }), + height: try dictionary.getOptionalField("height", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }), + id: try dictionary.getOptionalField("id", context: context), + isEnabled: try dictionary.getOptionalExpressionField("is_enabled", context: context), + isOnVariable: try dictionary.getField("is_on_variable", context: context), + layoutProvider: try dictionary.getOptionalField("layout_provider", transform: { (dict: [String: Any]) in try DivLayoutProvider(dictionary: dict, context: context) }), + margins: try dictionary.getOptionalField("margins", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + onColor: try dictionary.getOptionalExpressionField("on_color", transform: Color.color(withHexString:), context: context), + paddings: try dictionary.getOptionalField("paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + reuseId: try dictionary.getOptionalExpressionField("reuse_id", context: context), + rowSpan: try dictionary.getOptionalExpressionField("row_span", validator: Self.rowSpanValidator, context: context), + selectedActions: try dictionary.getOptionalArray("selected_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + tooltips: try dictionary.getOptionalArray("tooltips", transform: { (dict: [String: Any]) in try? DivTooltip(dictionary: dict, context: context) }), + transform: try dictionary.getOptionalField("transform", transform: { (dict: [String: Any]) in try DivTransform(dictionary: dict, context: context) }), + transformations: try dictionary.getOptionalArray("transformations", transform: { (dict: [String: Any]) in try? DivTransformation(dictionary: dict, context: context) }), + transitionChange: try dictionary.getOptionalField("transition_change", transform: { (dict: [String: Any]) in try DivChangeTransition(dictionary: dict, context: context) }), + transitionIn: try dictionary.getOptionalField("transition_in", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionOut: try dictionary.getOptionalField("transition_out", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionTriggers: try dictionary.getOptionalArray("transition_triggers", validator: Self.transitionTriggersValidator, context: context), + variableTriggers: try dictionary.getOptionalArray("variable_triggers", transform: { (dict: [String: Any]) in try? DivTrigger(dictionary: dict, context: context) }), + variables: try dictionary.getOptionalArray("variables", transform: { (dict: [String: Any]) in try? DivVariable(dictionary: dict, context: context) }), + visibility: try dictionary.getOptionalExpressionField("visibility", context: context), + visibilityAction: try dictionary.getOptionalField("visibility_action", transform: { (dict: [String: Any]) in try DivVisibilityAction(dictionary: dict, context: context) }), + visibilityActions: try dictionary.getOptionalArray("visibility_actions", transform: { (dict: [String: Any]) in try? DivVisibilityAction(dictionary: dict, context: context) }), + width: try dictionary.getOptionalField("width", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }) + ) + } + init( accessibility: DivAccessibility? = nil, alignmentHorizontal: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivTabs.swift b/client/ios/DivKit/generated_sources/DivTabs.swift index 7e7c5b6d7..8f14e4c06 100644 --- a/client/ios/DivKit/generated_sources/DivTabs.swift +++ b/client/ios/DivKit/generated_sources/DivTabs.swift @@ -14,6 +14,14 @@ public final class DivTabs: DivBase, Sendable { resolver.resolveString(title) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + div: try dictionary.getField("div", transform: { (dict: [String: Any]) in try Div(dictionary: dict, context: context) }), + title: try dictionary.getExpressionField("title", context: context), + titleClickAction: try dictionary.getOptionalField("title_click_action", transform: { (dict: [String: Any]) in try DivAction(dictionary: dict, context: context) }) + ) + } + init( div: Div, title: Expression, @@ -34,6 +42,14 @@ public final class DivTabs: DivBase, Sendable { resolver.resolveUrl(imageUrl) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + height: try dictionary.getOptionalField("height", transform: { (dict: [String: Any]) in try DivFixedSize(dictionary: dict, context: context) }), + imageUrl: try dictionary.getExpressionField("image_url", transform: URL.makeFromNonEncodedString, context: context), + width: try dictionary.getOptionalField("width", transform: { (dict: [String: Any]) in try DivFixedSize(dictionary: dict, context: context) }) + ) + } + init( height: DivFixedSize? = nil, imageUrl: Expression, @@ -161,6 +177,31 @@ public final class DivTabs: DivBase, Sendable { static let lineHeightValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + activeBackgroundColor: try dictionary.getOptionalExpressionField("active_background_color", transform: Color.color(withHexString:), context: context), + activeFontVariationSettings: try dictionary.getOptionalExpressionField("active_font_variation_settings", context: context), + activeFontWeight: try dictionary.getOptionalExpressionField("active_font_weight", context: context), + activeTextColor: try dictionary.getOptionalExpressionField("active_text_color", transform: Color.color(withHexString:), context: context), + animationDuration: try dictionary.getOptionalExpressionField("animation_duration", validator: Self.animationDurationValidator, context: context), + animationType: try dictionary.getOptionalExpressionField("animation_type", context: context), + cornerRadius: try dictionary.getOptionalExpressionField("corner_radius", validator: Self.cornerRadiusValidator, context: context), + cornersRadius: try dictionary.getOptionalField("corners_radius", transform: { (dict: [String: Any]) in try DivCornersRadius(dictionary: dict, context: context) }), + fontFamily: try dictionary.getOptionalExpressionField("font_family", context: context), + fontSize: try dictionary.getOptionalExpressionField("font_size", validator: Self.fontSizeValidator, context: context), + fontSizeUnit: try dictionary.getOptionalExpressionField("font_size_unit", context: context), + fontWeight: try dictionary.getOptionalExpressionField("font_weight", context: context), + inactiveBackgroundColor: try dictionary.getOptionalExpressionField("inactive_background_color", transform: Color.color(withHexString:), context: context), + inactiveFontVariationSettings: try dictionary.getOptionalExpressionField("inactive_font_variation_settings", context: context), + inactiveFontWeight: try dictionary.getOptionalExpressionField("inactive_font_weight", context: context), + inactiveTextColor: try dictionary.getOptionalExpressionField("inactive_text_color", transform: Color.color(withHexString:), context: context), + itemSpacing: try dictionary.getOptionalExpressionField("item_spacing", validator: Self.itemSpacingValidator, context: context), + letterSpacing: try dictionary.getOptionalExpressionField("letter_spacing", context: context), + lineHeight: try dictionary.getOptionalExpressionField("line_height", validator: Self.lineHeightValidator, context: context), + paddings: try dictionary.getOptionalField("paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }) + ) + } + init( activeBackgroundColor: Expression? = nil, activeFontVariationSettings: Expression<[String: Any]>? = nil, @@ -322,6 +363,55 @@ public final class DivTabs: DivBase, Sendable { static let transitionTriggersValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + accessibility: try dictionary.getOptionalField("accessibility", transform: { (dict: [String: Any]) in try DivAccessibility(dictionary: dict, context: context) }), + alignmentHorizontal: try dictionary.getOptionalExpressionField("alignment_horizontal", context: context), + alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical", context: context), + alpha: try dictionary.getOptionalExpressionField("alpha", validator: Self.alphaValidator, context: context), + animators: try dictionary.getOptionalArray("animators", transform: { (dict: [String: Any]) in try? DivAnimator(dictionary: dict, context: context) }), + background: try dictionary.getOptionalArray("background", transform: { (dict: [String: Any]) in try? DivBackground(dictionary: dict, context: context) }), + border: try dictionary.getOptionalField("border", transform: { (dict: [String: Any]) in try DivBorder(dictionary: dict, context: context) }), + columnSpan: try dictionary.getOptionalExpressionField("column_span", validator: Self.columnSpanValidator, context: context), + disappearActions: try dictionary.getOptionalArray("disappear_actions", transform: { (dict: [String: Any]) in try? DivDisappearAction(dictionary: dict, context: context) }), + dynamicHeight: try dictionary.getOptionalExpressionField("dynamic_height", context: context), + extensions: try dictionary.getOptionalArray("extensions", transform: { (dict: [String: Any]) in try? DivExtension(dictionary: dict, context: context) }), + focus: try dictionary.getOptionalField("focus", transform: { (dict: [String: Any]) in try DivFocus(dictionary: dict, context: context) }), + functions: try dictionary.getOptionalArray("functions", transform: { (dict: [String: Any]) in try? DivFunction(dictionary: dict, context: context) }), + hasSeparator: try dictionary.getOptionalExpressionField("has_separator", context: context), + height: try dictionary.getOptionalField("height", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }), + id: try dictionary.getOptionalField("id", context: context), + items: try dictionary.getArray("items", transform: { (dict: [String: Any]) in try? DivTabs.Item(dictionary: dict, context: context) }, validator: Self.itemsValidator), + layoutProvider: try dictionary.getOptionalField("layout_provider", transform: { (dict: [String: Any]) in try DivLayoutProvider(dictionary: dict, context: context) }), + margins: try dictionary.getOptionalField("margins", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + paddings: try dictionary.getOptionalField("paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + restrictParentScroll: try dictionary.getOptionalExpressionField("restrict_parent_scroll", context: context), + reuseId: try dictionary.getOptionalExpressionField("reuse_id", context: context), + rowSpan: try dictionary.getOptionalExpressionField("row_span", validator: Self.rowSpanValidator, context: context), + selectedActions: try dictionary.getOptionalArray("selected_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + selectedTab: try dictionary.getOptionalExpressionField("selected_tab", validator: Self.selectedTabValidator, context: context), + separatorColor: try dictionary.getOptionalExpressionField("separator_color", transform: Color.color(withHexString:), context: context), + separatorPaddings: try dictionary.getOptionalField("separator_paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + switchTabsByContentSwipeEnabled: try dictionary.getOptionalExpressionField("switch_tabs_by_content_swipe_enabled", context: context), + tabTitleDelimiter: try dictionary.getOptionalField("tab_title_delimiter", transform: { (dict: [String: Any]) in try DivTabs.TabTitleDelimiter(dictionary: dict, context: context) }), + tabTitleStyle: try dictionary.getOptionalField("tab_title_style", transform: { (dict: [String: Any]) in try DivTabs.TabTitleStyle(dictionary: dict, context: context) }), + titlePaddings: try dictionary.getOptionalField("title_paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + tooltips: try dictionary.getOptionalArray("tooltips", transform: { (dict: [String: Any]) in try? DivTooltip(dictionary: dict, context: context) }), + transform: try dictionary.getOptionalField("transform", transform: { (dict: [String: Any]) in try DivTransform(dictionary: dict, context: context) }), + transformations: try dictionary.getOptionalArray("transformations", transform: { (dict: [String: Any]) in try? DivTransformation(dictionary: dict, context: context) }), + transitionChange: try dictionary.getOptionalField("transition_change", transform: { (dict: [String: Any]) in try DivChangeTransition(dictionary: dict, context: context) }), + transitionIn: try dictionary.getOptionalField("transition_in", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionOut: try dictionary.getOptionalField("transition_out", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionTriggers: try dictionary.getOptionalArray("transition_triggers", validator: Self.transitionTriggersValidator, context: context), + variableTriggers: try dictionary.getOptionalArray("variable_triggers", transform: { (dict: [String: Any]) in try? DivTrigger(dictionary: dict, context: context) }), + variables: try dictionary.getOptionalArray("variables", transform: { (dict: [String: Any]) in try? DivVariable(dictionary: dict, context: context) }), + visibility: try dictionary.getOptionalExpressionField("visibility", context: context), + visibilityAction: try dictionary.getOptionalField("visibility_action", transform: { (dict: [String: Any]) in try DivVisibilityAction(dictionary: dict, context: context) }), + visibilityActions: try dictionary.getOptionalArray("visibility_actions", transform: { (dict: [String: Any]) in try? DivVisibilityAction(dictionary: dict, context: context) }), + width: try dictionary.getOptionalField("width", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }) + ) + } + init( accessibility: DivAccessibility?, alignmentHorizontal: Expression?, diff --git a/client/ios/DivKit/generated_sources/DivText.swift b/client/ios/DivKit/generated_sources/DivText.swift index ceb2000ba..51fa0993c 100644 --- a/client/ios/DivKit/generated_sources/DivText.swift +++ b/client/ios/DivKit/generated_sources/DivText.swift @@ -23,6 +23,15 @@ public final class DivText: DivBase, @unchecked Sendable { resolver.resolveString(text) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + actions: try dictionary.getOptionalArray("actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + images: try dictionary.getOptionalArray("images", transform: { (dict: [String: Any]) in try? DivText.Image(dictionary: dict, context: context) }), + ranges: try dictionary.getOptionalArray("ranges", transform: { (dict: [String: Any]) in try? DivText.Range(dictionary: dict, context: context) }), + text: try dictionary.getExpressionField("text", context: context) + ) + } + init( actions: [DivAction]? = nil, images: [Image]? = nil, @@ -60,6 +69,13 @@ public final class DivText: DivBase, @unchecked Sendable { resolver.resolveString(description) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + description: try dictionary.getOptionalExpressionField("description", context: context), + type: try dictionary.getOptionalField("type", context: context) + ) + } + init( description: Expression? = nil, type: Kind? = nil @@ -111,6 +127,21 @@ public final class DivText: DivBase, @unchecked Sendable { static let startValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + accessibility: try dictionary.getOptionalField("accessibility", transform: { (dict: [String: Any]) in try DivText.Image.Accessibility(dictionary: dict, context: context) }), + alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical", context: context), + height: try dictionary.getOptionalField("height", transform: { (dict: [String: Any]) in try DivFixedSize(dictionary: dict, context: context) }), + indexingDirection: try dictionary.getOptionalExpressionField("indexing_direction", context: context), + preloadRequired: try dictionary.getOptionalExpressionField("preload_required", context: context), + start: try dictionary.getExpressionField("start", validator: Self.startValidator, context: context), + tintColor: try dictionary.getOptionalExpressionField("tint_color", transform: Color.color(withHexString:), context: context), + tintMode: try dictionary.getOptionalExpressionField("tint_mode", context: context), + url: try dictionary.getExpressionField("url", transform: URL.makeFromNonEncodedString, context: context), + width: try dictionary.getOptionalField("width", transform: { (dict: [String: Any]) in try DivFixedSize(dictionary: dict, context: context) }) + ) + } + init( accessibility: Accessibility? = nil, alignmentVertical: Expression? = nil, @@ -246,6 +277,33 @@ public final class DivText: DivBase, @unchecked Sendable { static let topOffsetValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + actions: try dictionary.getOptionalArray("actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical", context: context), + background: try dictionary.getOptionalField("background", transform: { (dict: [String: Any]) in try DivTextRangeBackground(dictionary: dict, context: context) }), + baselineOffset: try dictionary.getOptionalExpressionField("baseline_offset", context: context), + border: try dictionary.getOptionalField("border", transform: { (dict: [String: Any]) in try DivTextRangeBorder(dictionary: dict, context: context) }), + end: try dictionary.getOptionalExpressionField("end", validator: Self.endValidator, context: context), + fontFamily: try dictionary.getOptionalExpressionField("font_family", context: context), + fontFeatureSettings: try dictionary.getOptionalExpressionField("font_feature_settings", context: context), + fontSize: try dictionary.getOptionalExpressionField("font_size", validator: Self.fontSizeValidator, context: context), + fontSizeUnit: try dictionary.getOptionalExpressionField("font_size_unit", context: context), + fontVariationSettings: try dictionary.getOptionalExpressionField("font_variation_settings", context: context), + fontWeight: try dictionary.getOptionalExpressionField("font_weight", context: context), + fontWeightValue: try dictionary.getOptionalExpressionField("font_weight_value", validator: Self.fontWeightValueValidator, context: context), + letterSpacing: try dictionary.getOptionalExpressionField("letter_spacing", context: context), + lineHeight: try dictionary.getOptionalExpressionField("line_height", validator: Self.lineHeightValidator, context: context), + mask: try dictionary.getOptionalField("mask", transform: { (dict: [String: Any]) in try DivTextRangeMask(dictionary: dict, context: context) }), + start: try dictionary.getOptionalExpressionField("start", validator: Self.startValidator, context: context), + strike: try dictionary.getOptionalExpressionField("strike", context: context), + textColor: try dictionary.getOptionalExpressionField("text_color", transform: Color.color(withHexString:), context: context), + textShadow: try dictionary.getOptionalField("text_shadow", transform: { (dict: [String: Any]) in try DivShadow(dictionary: dict, context: context) }), + topOffset: try dictionary.getOptionalExpressionField("top_offset", validator: Self.topOffsetValidator, context: context), + underline: try dictionary.getOptionalExpressionField("underline", context: context) + ) + } + init( actions: [DivAction]? = nil, alignmentVertical: Expression? = nil, @@ -514,6 +572,81 @@ public final class DivText: DivBase, @unchecked Sendable { static let transitionTriggersValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + accessibility: try dictionary.getOptionalField("accessibility", transform: { (dict: [String: Any]) in try DivAccessibility(dictionary: dict, context: context) }), + action: try dictionary.getOptionalField("action", transform: { (dict: [String: Any]) in try DivAction(dictionary: dict, context: context) }), + actionAnimation: try dictionary.getOptionalField("action_animation", transform: { (dict: [String: Any]) in try DivAnimation(dictionary: dict, context: context) }), + actions: try dictionary.getOptionalArray("actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + alignmentHorizontal: try dictionary.getOptionalExpressionField("alignment_horizontal", context: context), + alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical", context: context), + alpha: try dictionary.getOptionalExpressionField("alpha", validator: Self.alphaValidator, context: context), + animators: try dictionary.getOptionalArray("animators", transform: { (dict: [String: Any]) in try? DivAnimator(dictionary: dict, context: context) }), + autoEllipsize: try dictionary.getOptionalExpressionField("auto_ellipsize", context: context), + background: try dictionary.getOptionalArray("background", transform: { (dict: [String: Any]) in try? DivBackground(dictionary: dict, context: context) }), + border: try dictionary.getOptionalField("border", transform: { (dict: [String: Any]) in try DivBorder(dictionary: dict, context: context) }), + captureFocusOnAction: try dictionary.getOptionalExpressionField("capture_focus_on_action", context: context), + columnSpan: try dictionary.getOptionalExpressionField("column_span", validator: Self.columnSpanValidator, context: context), + disappearActions: try dictionary.getOptionalArray("disappear_actions", transform: { (dict: [String: Any]) in try? DivDisappearAction(dictionary: dict, context: context) }), + doubletapActions: try dictionary.getOptionalArray("doubletap_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + ellipsis: try dictionary.getOptionalField("ellipsis", transform: { (dict: [String: Any]) in try DivText.Ellipsis(dictionary: dict, context: context) }), + extensions: try dictionary.getOptionalArray("extensions", transform: { (dict: [String: Any]) in try? DivExtension(dictionary: dict, context: context) }), + focus: try dictionary.getOptionalField("focus", transform: { (dict: [String: Any]) in try DivFocus(dictionary: dict, context: context) }), + focusedTextColor: try dictionary.getOptionalExpressionField("focused_text_color", transform: Color.color(withHexString:), context: context), + fontFamily: try dictionary.getOptionalExpressionField("font_family", context: context), + fontFeatureSettings: try dictionary.getOptionalExpressionField("font_feature_settings", context: context), + fontSize: try dictionary.getOptionalExpressionField("font_size", validator: Self.fontSizeValidator, context: context), + fontSizeUnit: try dictionary.getOptionalExpressionField("font_size_unit", context: context), + fontVariationSettings: try dictionary.getOptionalExpressionField("font_variation_settings", context: context), + fontWeight: try dictionary.getOptionalExpressionField("font_weight", context: context), + fontWeightValue: try dictionary.getOptionalExpressionField("font_weight_value", validator: Self.fontWeightValueValidator, context: context), + functions: try dictionary.getOptionalArray("functions", transform: { (dict: [String: Any]) in try? DivFunction(dictionary: dict, context: context) }), + height: try dictionary.getOptionalField("height", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }), + hoverEndActions: try dictionary.getOptionalArray("hover_end_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + hoverStartActions: try dictionary.getOptionalArray("hover_start_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + id: try dictionary.getOptionalField("id", context: context), + images: try dictionary.getOptionalArray("images", transform: { (dict: [String: Any]) in try? DivText.Image(dictionary: dict, context: context) }), + layoutProvider: try dictionary.getOptionalField("layout_provider", transform: { (dict: [String: Any]) in try DivLayoutProvider(dictionary: dict, context: context) }), + letterSpacing: try dictionary.getOptionalExpressionField("letter_spacing", context: context), + lineHeight: try dictionary.getOptionalExpressionField("line_height", validator: Self.lineHeightValidator, context: context), + longtapActions: try dictionary.getOptionalArray("longtap_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + margins: try dictionary.getOptionalField("margins", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + maxLines: try dictionary.getOptionalExpressionField("max_lines", validator: Self.maxLinesValidator, context: context), + minHiddenLines: try dictionary.getOptionalExpressionField("min_hidden_lines", validator: Self.minHiddenLinesValidator, context: context), + paddings: try dictionary.getOptionalField("paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + pressEndActions: try dictionary.getOptionalArray("press_end_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + pressStartActions: try dictionary.getOptionalArray("press_start_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + ranges: try dictionary.getOptionalArray("ranges", transform: { (dict: [String: Any]) in try? DivText.Range(dictionary: dict, context: context) }), + reuseId: try dictionary.getOptionalExpressionField("reuse_id", context: context), + rowSpan: try dictionary.getOptionalExpressionField("row_span", validator: Self.rowSpanValidator, context: context), + selectable: try dictionary.getOptionalExpressionField("selectable", context: context), + selectedActions: try dictionary.getOptionalArray("selected_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + strike: try dictionary.getOptionalExpressionField("strike", context: context), + text: try dictionary.getExpressionField("text", context: context), + textAlignmentHorizontal: try dictionary.getOptionalExpressionField("text_alignment_horizontal", context: context), + textAlignmentVertical: try dictionary.getOptionalExpressionField("text_alignment_vertical", context: context), + textColor: try dictionary.getOptionalExpressionField("text_color", transform: Color.color(withHexString:), context: context), + textGradient: try dictionary.getOptionalField("text_gradient", transform: { (dict: [String: Any]) in try DivTextGradient(dictionary: dict, context: context) }), + textShadow: try dictionary.getOptionalField("text_shadow", transform: { (dict: [String: Any]) in try DivShadow(dictionary: dict, context: context) }), + tightenWidth: try dictionary.getOptionalExpressionField("tighten_width", context: context), + tooltips: try dictionary.getOptionalArray("tooltips", transform: { (dict: [String: Any]) in try? DivTooltip(dictionary: dict, context: context) }), + transform: try dictionary.getOptionalField("transform", transform: { (dict: [String: Any]) in try DivTransform(dictionary: dict, context: context) }), + transformations: try dictionary.getOptionalArray("transformations", transform: { (dict: [String: Any]) in try? DivTransformation(dictionary: dict, context: context) }), + transitionChange: try dictionary.getOptionalField("transition_change", transform: { (dict: [String: Any]) in try DivChangeTransition(dictionary: dict, context: context) }), + transitionIn: try dictionary.getOptionalField("transition_in", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionOut: try dictionary.getOptionalField("transition_out", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionTriggers: try dictionary.getOptionalArray("transition_triggers", validator: Self.transitionTriggersValidator, context: context), + truncate: try dictionary.getOptionalExpressionField("truncate", context: context), + underline: try dictionary.getOptionalExpressionField("underline", context: context), + variableTriggers: try dictionary.getOptionalArray("variable_triggers", transform: { (dict: [String: Any]) in try? DivTrigger(dictionary: dict, context: context) }), + variables: try dictionary.getOptionalArray("variables", transform: { (dict: [String: Any]) in try? DivVariable(dictionary: dict, context: context) }), + visibility: try dictionary.getOptionalExpressionField("visibility", context: context), + visibilityAction: try dictionary.getOptionalField("visibility_action", transform: { (dict: [String: Any]) in try DivVisibilityAction(dictionary: dict, context: context) }), + visibilityActions: try dictionary.getOptionalArray("visibility_actions", transform: { (dict: [String: Any]) in try? DivVisibilityAction(dictionary: dict, context: context) }), + width: try dictionary.getOptionalField("width", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }) + ) + } + init( accessibility: DivAccessibility? = nil, action: DivAction? = nil, diff --git a/client/ios/DivKit/generated_sources/DivTextGradient.swift b/client/ios/DivKit/generated_sources/DivTextGradient.swift index b8c880cac..1d5ebf1db 100644 --- a/client/ios/DivKit/generated_sources/DivTextGradient.swift +++ b/client/ios/DivKit/generated_sources/DivTextGradient.swift @@ -19,6 +19,20 @@ public enum DivTextGradient: Sendable { } } +extension DivTextGradient { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivLinearGradient.type: + self = .divLinearGradient(try DivLinearGradient(dictionary: dictionary, context: context)) + case DivRadialGradient.type: + self = .divRadialGradient(try DivRadialGradient(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-text-gradient", representation: dictionary) + } + } +} + #if DEBUG extension DivTextGradient: Equatable { public static func ==(lhs: DivTextGradient, rhs: DivTextGradient) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivTextRangeBackground.swift b/client/ios/DivKit/generated_sources/DivTextRangeBackground.swift index 24258145d..08e59d66c 100644 --- a/client/ios/DivKit/generated_sources/DivTextRangeBackground.swift +++ b/client/ios/DivKit/generated_sources/DivTextRangeBackground.swift @@ -19,6 +19,20 @@ public enum DivTextRangeBackground: Sendable { } } +extension DivTextRangeBackground { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivSolidBackground.type: + self = .divSolidBackground(try DivSolidBackground(dictionary: dictionary, context: context)) + case DivCloudBackground.type: + self = .divCloudBackground(try DivCloudBackground(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-text-range-background", representation: dictionary) + } + } +} + #if DEBUG extension DivTextRangeBackground: Equatable { public static func ==(lhs: DivTextRangeBackground, rhs: DivTextRangeBackground) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivTextRangeBorder.swift b/client/ios/DivKit/generated_sources/DivTextRangeBorder.swift index 6c12122c2..35a54700e 100644 --- a/client/ios/DivKit/generated_sources/DivTextRangeBorder.swift +++ b/client/ios/DivKit/generated_sources/DivTextRangeBorder.swift @@ -15,6 +15,13 @@ public final class DivTextRangeBorder: Sendable { static let cornerRadiusValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + cornerRadius: try dictionary.getOptionalExpressionField("corner_radius", validator: Self.cornerRadiusValidator, context: context), + stroke: try dictionary.getOptionalField("stroke", transform: { (dict: [String: Any]) in try DivStroke(dictionary: dict, context: context) }) + ) + } + init( cornerRadius: Expression? = nil, stroke: DivStroke? = nil diff --git a/client/ios/DivKit/generated_sources/DivTextRangeMask.swift b/client/ios/DivKit/generated_sources/DivTextRangeMask.swift index 201fc4a87..aa99b0de2 100644 --- a/client/ios/DivKit/generated_sources/DivTextRangeMask.swift +++ b/client/ios/DivKit/generated_sources/DivTextRangeMask.swift @@ -19,6 +19,20 @@ public enum DivTextRangeMask: Sendable { } } +extension DivTextRangeMask { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivTextRangeMaskParticles.type: + self = .divTextRangeMaskParticles(try DivTextRangeMaskParticles(dictionary: dictionary, context: context)) + case DivTextRangeMaskSolid.type: + self = .divTextRangeMaskSolid(try DivTextRangeMaskSolid(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-text-range-mask", representation: dictionary) + } + } +} + #if DEBUG extension DivTextRangeMask: Equatable { public static func ==(lhs: DivTextRangeMask, rhs: DivTextRangeMask) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivTextRangeMaskBase.swift b/client/ios/DivKit/generated_sources/DivTextRangeMaskBase.swift index bf7172a52..391335c59 100644 --- a/client/ios/DivKit/generated_sources/DivTextRangeMaskBase.swift +++ b/client/ios/DivKit/generated_sources/DivTextRangeMaskBase.swift @@ -11,6 +11,12 @@ public final class DivTextRangeMaskBase: Sendable { resolver.resolveNumeric(isEnabled) ?? true } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + isEnabled: try dictionary.getOptionalExpressionField("is_enabled", context: context) + ) + } + init( isEnabled: Expression? = nil ) { diff --git a/client/ios/DivKit/generated_sources/DivTextRangeMaskParticles.swift b/client/ios/DivKit/generated_sources/DivTextRangeMaskParticles.swift index 84171b3e0..634c11360 100644 --- a/client/ios/DivKit/generated_sources/DivTextRangeMaskParticles.swift +++ b/client/ios/DivKit/generated_sources/DivTextRangeMaskParticles.swift @@ -31,6 +31,16 @@ public final class DivTextRangeMaskParticles: Sendable { static let densityValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 > 0.0 && $0 <= 1.0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + color: try dictionary.getExpressionField("color", transform: Color.color(withHexString:), context: context), + density: try dictionary.getOptionalExpressionField("density", validator: Self.densityValidator, context: context), + isAnimated: try dictionary.getOptionalExpressionField("is_animated", context: context), + isEnabled: try dictionary.getOptionalExpressionField("is_enabled", context: context), + particleSize: try dictionary.getOptionalField("particle_size", transform: { (dict: [String: Any]) in try DivFixedSize(dictionary: dict, context: context) }) + ) + } + init( color: Expression, density: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivTextRangeMaskSolid.swift b/client/ios/DivKit/generated_sources/DivTextRangeMaskSolid.swift index 125b03f3d..d0fe6f10e 100644 --- a/client/ios/DivKit/generated_sources/DivTextRangeMaskSolid.swift +++ b/client/ios/DivKit/generated_sources/DivTextRangeMaskSolid.swift @@ -17,6 +17,13 @@ public final class DivTextRangeMaskSolid: Sendable { resolver.resolveNumeric(isEnabled) ?? true } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + color: try dictionary.getExpressionField("color", transform: Color.color(withHexString:), context: context), + isEnabled: try dictionary.getOptionalExpressionField("is_enabled", context: context) + ) + } + init( color: Expression, isEnabled: Expression? = nil diff --git a/client/ios/DivKit/generated_sources/DivTimer.swift b/client/ios/DivKit/generated_sources/DivTimer.swift index fc890159c..f232daa89 100644 --- a/client/ios/DivKit/generated_sources/DivTimer.swift +++ b/client/ios/DivKit/generated_sources/DivTimer.swift @@ -26,6 +26,17 @@ public final class DivTimer: Sendable { static let tickIntervalValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 > 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + duration: try dictionary.getOptionalExpressionField("duration", validator: Self.durationValidator, context: context), + endActions: try dictionary.getOptionalArray("end_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + id: try dictionary.getField("id", context: context), + tickActions: try dictionary.getOptionalArray("tick_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + tickInterval: try dictionary.getOptionalExpressionField("tick_interval", validator: Self.tickIntervalValidator, context: context), + valueVariable: try dictionary.getOptionalField("value_variable", context: context) + ) + } + init( duration: Expression? = nil, endActions: [DivAction]? = nil, diff --git a/client/ios/DivKit/generated_sources/DivTooltip.swift b/client/ios/DivKit/generated_sources/DivTooltip.swift index 24398abea..3d289a4f1 100644 --- a/client/ios/DivKit/generated_sources/DivTooltip.swift +++ b/client/ios/DivKit/generated_sources/DivTooltip.swift @@ -51,6 +51,24 @@ public final class DivTooltip: Sendable { static let durationValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + animationIn: try dictionary.getOptionalField("animation_in", transform: { (dict: [String: Any]) in try DivAnimation(dictionary: dict, context: context) }), + animationOut: try dictionary.getOptionalField("animation_out", transform: { (dict: [String: Any]) in try DivAnimation(dictionary: dict, context: context) }), + backgroundAccessibilityDescription: try dictionary.getOptionalExpressionField("background_accessibility_description", context: context), + bringToTopId: try dictionary.getOptionalField("bring_to_top_id", context: context), + closeByTapOutside: try dictionary.getOptionalExpressionField("close_by_tap_outside", context: context), + div: try dictionary.getField("div", transform: { (dict: [String: Any]) in try Div(dictionary: dict, context: context) }), + duration: try dictionary.getOptionalExpressionField("duration", validator: Self.durationValidator, context: context), + id: try dictionary.getField("id", context: context), + mode: try dictionary.getOptionalField("mode", transform: { (dict: [String: Any]) in try DivTooltipMode(dictionary: dict, context: context) }), + offset: try dictionary.getOptionalField("offset", transform: { (dict: [String: Any]) in try DivPoint(dictionary: dict, context: context) }), + position: try dictionary.getExpressionField("position", context: context), + substrateDiv: try dictionary.getOptionalField("substrate_div", transform: { (dict: [String: Any]) in try Div(dictionary: dict, context: context) }), + tapOutsideActions: try dictionary.getOptionalArray("tap_outside_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }) + ) + } + init( animationIn: DivAnimation? = nil, animationOut: DivAnimation? = nil, diff --git a/client/ios/DivKit/generated_sources/DivTooltipMode.swift b/client/ios/DivKit/generated_sources/DivTooltipMode.swift index 752281f94..f902749db 100644 --- a/client/ios/DivKit/generated_sources/DivTooltipMode.swift +++ b/client/ios/DivKit/generated_sources/DivTooltipMode.swift @@ -19,6 +19,20 @@ public enum DivTooltipMode: Sendable { } } +extension DivTooltipMode { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivTooltipModeNonModal.type: + self = .divTooltipModeNonModal(try DivTooltipModeNonModal(dictionary: dictionary, context: context)) + case DivTooltipModeModal.type: + self = .divTooltipModeModal(try DivTooltipModeModal(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-tooltip-mode", representation: dictionary) + } + } +} + #if DEBUG extension DivTooltipMode: Equatable { public static func ==(lhs: DivTooltipMode, rhs: DivTooltipMode) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivTooltipModeModal.swift b/client/ios/DivKit/generated_sources/DivTooltipModeModal.swift index b0e8b8e40..a9edd8fa3 100644 --- a/client/ios/DivKit/generated_sources/DivTooltipModeModal.swift +++ b/client/ios/DivKit/generated_sources/DivTooltipModeModal.swift @@ -7,6 +7,8 @@ import VGSL public final class DivTooltipModeModal: Sendable { public static let type: String = "modal" + public init(dictionary: [String: Any], context: ParsingContext) throws {} + init() {} } diff --git a/client/ios/DivKit/generated_sources/DivTooltipModeNonModal.swift b/client/ios/DivKit/generated_sources/DivTooltipModeNonModal.swift index 14629710a..d66f9844c 100644 --- a/client/ios/DivKit/generated_sources/DivTooltipModeNonModal.swift +++ b/client/ios/DivKit/generated_sources/DivTooltipModeNonModal.swift @@ -7,6 +7,8 @@ import VGSL public final class DivTooltipModeNonModal: Sendable { public static let type: String = "non_modal" + public init(dictionary: [String: Any], context: ParsingContext) throws {} + init() {} } diff --git a/client/ios/DivKit/generated_sources/DivTransform.swift b/client/ios/DivKit/generated_sources/DivTransform.swift index 061f3311d..28bfd9627 100644 --- a/client/ios/DivKit/generated_sources/DivTransform.swift +++ b/client/ios/DivKit/generated_sources/DivTransform.swift @@ -13,6 +13,14 @@ public final class DivTransform: Sendable { resolver.resolveNumeric(rotation) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + pivotX: try dictionary.getOptionalField("pivot_x", transform: { (dict: [String: Any]) in try DivPivot(dictionary: dict, context: context) }), + pivotY: try dictionary.getOptionalField("pivot_y", transform: { (dict: [String: Any]) in try DivPivot(dictionary: dict, context: context) }), + rotation: try dictionary.getOptionalExpressionField("rotation", context: context) + ) + } + init( pivotX: DivPivot? = nil, pivotY: DivPivot? = nil, diff --git a/client/ios/DivKit/generated_sources/DivTransformation.swift b/client/ios/DivKit/generated_sources/DivTransformation.swift index 3349ce0c2..8bd1929ea 100644 --- a/client/ios/DivKit/generated_sources/DivTransformation.swift +++ b/client/ios/DivKit/generated_sources/DivTransformation.swift @@ -19,6 +19,20 @@ public enum DivTransformation: Sendable { } } +extension DivTransformation { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivRotationTransformation.type: + self = .divRotationTransformation(try DivRotationTransformation(dictionary: dictionary, context: context)) + case DivTranslationTransformation.type: + self = .divTranslationTransformation(try DivTranslationTransformation(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-transformation", representation: dictionary) + } + } +} + #if DEBUG extension DivTransformation: Equatable { public static func ==(lhs: DivTransformation, rhs: DivTransformation) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivTranslation.swift b/client/ios/DivKit/generated_sources/DivTranslation.swift index 2047a4b49..4a1e1d201 100644 --- a/client/ios/DivKit/generated_sources/DivTranslation.swift +++ b/client/ios/DivKit/generated_sources/DivTranslation.swift @@ -19,6 +19,20 @@ public enum DivTranslation: Sendable { } } +extension DivTranslation { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case DivFixedTranslation.type: + self = .divFixedTranslation(try DivFixedTranslation(dictionary: dictionary, context: context)) + case DivPercentageTranslation.type: + self = .divPercentageTranslation(try DivPercentageTranslation(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-translation", representation: dictionary) + } + } +} + #if DEBUG extension DivTranslation: Equatable { public static func ==(lhs: DivTranslation, rhs: DivTranslation) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivTranslationTransformation.swift b/client/ios/DivKit/generated_sources/DivTranslationTransformation.swift index 3679c6c85..4829bed0e 100644 --- a/client/ios/DivKit/generated_sources/DivTranslationTransformation.swift +++ b/client/ios/DivKit/generated_sources/DivTranslationTransformation.swift @@ -9,6 +9,13 @@ public final class DivTranslationTransformation: Sendable { public let x: DivTranslation? public let y: DivTranslation? + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + x: try dictionary.getOptionalField("x", transform: { (dict: [String: Any]) in try DivTranslation(dictionary: dict, context: context) }), + y: try dictionary.getOptionalField("y", transform: { (dict: [String: Any]) in try DivTranslation(dictionary: dict, context: context) }) + ) + } + init( x: DivTranslation? = nil, y: DivTranslation? = nil diff --git a/client/ios/DivKit/generated_sources/DivTrigger.swift b/client/ios/DivKit/generated_sources/DivTrigger.swift index acd4d967b..2d4b92200 100644 --- a/client/ios/DivKit/generated_sources/DivTrigger.swift +++ b/client/ios/DivKit/generated_sources/DivTrigger.swift @@ -26,6 +26,14 @@ public final class DivTrigger: Sendable { static let actionsValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + actions: try dictionary.getArray("actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }, validator: Self.actionsValidator), + condition: try dictionary.getExpressionField("condition", context: context), + mode: try dictionary.getOptionalExpressionField("mode", context: context) + ) + } + init( actions: [DivAction], condition: Expression, diff --git a/client/ios/DivKit/generated_sources/DivTypedValue.swift b/client/ios/DivKit/generated_sources/DivTypedValue.swift index 0e06d87e2..4069dbc73 100644 --- a/client/ios/DivKit/generated_sources/DivTypedValue.swift +++ b/client/ios/DivKit/generated_sources/DivTypedValue.swift @@ -37,6 +37,32 @@ public enum DivTypedValue: Sendable { } } +extension DivTypedValue { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case StringValue.type: + self = .stringValue(try StringValue(dictionary: dictionary, context: context)) + case IntegerValue.type: + self = .integerValue(try IntegerValue(dictionary: dictionary, context: context)) + case NumberValue.type: + self = .numberValue(try NumberValue(dictionary: dictionary, context: context)) + case ColorValue.type: + self = .colorValue(try ColorValue(dictionary: dictionary, context: context)) + case BooleanValue.type: + self = .booleanValue(try BooleanValue(dictionary: dictionary, context: context)) + case UrlValue.type: + self = .urlValue(try UrlValue(dictionary: dictionary, context: context)) + case DictValue.type: + self = .dictValue(try DictValue(dictionary: dictionary, context: context)) + case ArrayValue.type: + self = .arrayValue(try ArrayValue(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-typed-value", representation: dictionary) + } + } +} + #if DEBUG extension DivTypedValue: Equatable { public static func ==(lhs: DivTypedValue, rhs: DivTypedValue) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivVariable.swift b/client/ios/DivKit/generated_sources/DivVariable.swift index 235e72134..7f70f464e 100644 --- a/client/ios/DivKit/generated_sources/DivVariable.swift +++ b/client/ios/DivKit/generated_sources/DivVariable.swift @@ -40,6 +40,34 @@ public enum DivVariable: Sendable { } } +extension DivVariable { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case StringVariable.type: + self = .stringVariable(try StringVariable(dictionary: dictionary, context: context)) + case NumberVariable.type: + self = .numberVariable(try NumberVariable(dictionary: dictionary, context: context)) + case IntegerVariable.type: + self = .integerVariable(try IntegerVariable(dictionary: dictionary, context: context)) + case BooleanVariable.type: + self = .booleanVariable(try BooleanVariable(dictionary: dictionary, context: context)) + case ColorVariable.type: + self = .colorVariable(try ColorVariable(dictionary: dictionary, context: context)) + case UrlVariable.type: + self = .urlVariable(try UrlVariable(dictionary: dictionary, context: context)) + case DictVariable.type: + self = .dictVariable(try DictVariable(dictionary: dictionary, context: context)) + case ArrayVariable.type: + self = .arrayVariable(try ArrayVariable(dictionary: dictionary, context: context)) + case PropertyVariable.type: + self = .propertyVariable(try PropertyVariable(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "div-variable", representation: dictionary) + } + } +} + #if DEBUG extension DivVariable: Equatable { public static func ==(lhs: DivVariable, rhs: DivVariable) -> Bool { diff --git a/client/ios/DivKit/generated_sources/DivVideo.swift b/client/ios/DivKit/generated_sources/DivVideo.swift index 656f03f9a..343cad792 100644 --- a/client/ios/DivKit/generated_sources/DivVideo.swift +++ b/client/ios/DivKit/generated_sources/DivVideo.swift @@ -122,6 +122,59 @@ public final class DivVideo: DivBase, @unchecked Sendable { static let videoSourcesValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + accessibility: try dictionary.getOptionalField("accessibility", transform: { (dict: [String: Any]) in try DivAccessibility(dictionary: dict, context: context) }), + alignmentHorizontal: try dictionary.getOptionalExpressionField("alignment_horizontal", context: context), + alignmentVertical: try dictionary.getOptionalExpressionField("alignment_vertical", context: context), + alpha: try dictionary.getOptionalExpressionField("alpha", validator: Self.alphaValidator, context: context), + animators: try dictionary.getOptionalArray("animators", transform: { (dict: [String: Any]) in try? DivAnimator(dictionary: dict, context: context) }), + aspect: try dictionary.getOptionalField("aspect", transform: { (dict: [String: Any]) in try DivAspect(dictionary: dict, context: context) }), + autostart: try dictionary.getOptionalExpressionField("autostart", context: context), + background: try dictionary.getOptionalArray("background", transform: { (dict: [String: Any]) in try? DivBackground(dictionary: dict, context: context) }), + border: try dictionary.getOptionalField("border", transform: { (dict: [String: Any]) in try DivBorder(dictionary: dict, context: context) }), + bufferingActions: try dictionary.getOptionalArray("buffering_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + columnSpan: try dictionary.getOptionalExpressionField("column_span", validator: Self.columnSpanValidator, context: context), + disappearActions: try dictionary.getOptionalArray("disappear_actions", transform: { (dict: [String: Any]) in try? DivDisappearAction(dictionary: dict, context: context) }), + elapsedTimeVariable: try dictionary.getOptionalField("elapsed_time_variable", context: context), + endActions: try dictionary.getOptionalArray("end_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + extensions: try dictionary.getOptionalArray("extensions", transform: { (dict: [String: Any]) in try? DivExtension(dictionary: dict, context: context) }), + fatalActions: try dictionary.getOptionalArray("fatal_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + focus: try dictionary.getOptionalField("focus", transform: { (dict: [String: Any]) in try DivFocus(dictionary: dict, context: context) }), + functions: try dictionary.getOptionalArray("functions", transform: { (dict: [String: Any]) in try? DivFunction(dictionary: dict, context: context) }), + height: try dictionary.getOptionalField("height", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }), + id: try dictionary.getOptionalField("id", context: context), + layoutProvider: try dictionary.getOptionalField("layout_provider", transform: { (dict: [String: Any]) in try DivLayoutProvider(dictionary: dict, context: context) }), + margins: try dictionary.getOptionalField("margins", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + muted: try dictionary.getOptionalExpressionField("muted", context: context), + paddings: try dictionary.getOptionalField("paddings", transform: { (dict: [String: Any]) in try DivEdgeInsets(dictionary: dict, context: context) }), + pauseActions: try dictionary.getOptionalArray("pause_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + playerSettingsPayload: try dictionary.getOptionalField("player_settings_payload", context: context), + preloadRequired: try dictionary.getOptionalExpressionField("preload_required", context: context), + preview: try dictionary.getOptionalExpressionField("preview", context: context), + repeatable: try dictionary.getOptionalExpressionField("repeatable", context: context), + resumeActions: try dictionary.getOptionalArray("resume_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + reuseId: try dictionary.getOptionalExpressionField("reuse_id", context: context), + rowSpan: try dictionary.getOptionalExpressionField("row_span", validator: Self.rowSpanValidator, context: context), + scale: try dictionary.getOptionalExpressionField("scale", context: context), + selectedActions: try dictionary.getOptionalArray("selected_actions", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + tooltips: try dictionary.getOptionalArray("tooltips", transform: { (dict: [String: Any]) in try? DivTooltip(dictionary: dict, context: context) }), + transform: try dictionary.getOptionalField("transform", transform: { (dict: [String: Any]) in try DivTransform(dictionary: dict, context: context) }), + transformations: try dictionary.getOptionalArray("transformations", transform: { (dict: [String: Any]) in try? DivTransformation(dictionary: dict, context: context) }), + transitionChange: try dictionary.getOptionalField("transition_change", transform: { (dict: [String: Any]) in try DivChangeTransition(dictionary: dict, context: context) }), + transitionIn: try dictionary.getOptionalField("transition_in", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionOut: try dictionary.getOptionalField("transition_out", transform: { (dict: [String: Any]) in try DivAppearanceTransition(dictionary: dict, context: context) }), + transitionTriggers: try dictionary.getOptionalArray("transition_triggers", validator: Self.transitionTriggersValidator, context: context), + variableTriggers: try dictionary.getOptionalArray("variable_triggers", transform: { (dict: [String: Any]) in try? DivTrigger(dictionary: dict, context: context) }), + variables: try dictionary.getOptionalArray("variables", transform: { (dict: [String: Any]) in try? DivVariable(dictionary: dict, context: context) }), + videoSources: try dictionary.getArray("video_sources", transform: { (dict: [String: Any]) in try? DivVideoSource(dictionary: dict, context: context) }, validator: Self.videoSourcesValidator), + visibility: try dictionary.getOptionalExpressionField("visibility", context: context), + visibilityAction: try dictionary.getOptionalField("visibility_action", transform: { (dict: [String: Any]) in try DivVisibilityAction(dictionary: dict, context: context) }), + visibilityActions: try dictionary.getOptionalArray("visibility_actions", transform: { (dict: [String: Any]) in try? DivVisibilityAction(dictionary: dict, context: context) }), + width: try dictionary.getOptionalField("width", transform: { (dict: [String: Any]) in try DivSize(dictionary: dict, context: context) }) + ) + } + init( accessibility: DivAccessibility? = nil, alignmentHorizontal: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivVideoSource.swift b/client/ios/DivKit/generated_sources/DivVideoSource.swift index fdc766fcf..5f632e825 100644 --- a/client/ios/DivKit/generated_sources/DivVideoSource.swift +++ b/client/ios/DivKit/generated_sources/DivVideoSource.swift @@ -24,6 +24,13 @@ public final class DivVideoSource: Sendable { static let widthValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 > 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + height: try dictionary.getExpressionField("height", validator: Self.heightValidator, context: context), + width: try dictionary.getExpressionField("width", validator: Self.widthValidator, context: context) + ) + } + init( height: Expression, width: Expression @@ -51,6 +58,15 @@ public final class DivVideoSource: Sendable { resolver.resolveUrl(url) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + bitrate: try dictionary.getOptionalExpressionField("bitrate", context: context), + mimeType: try dictionary.getExpressionField("mime_type", context: context), + resolution: try dictionary.getOptionalField("resolution", transform: { (dict: [String: Any]) in try DivVideoSource.Resolution(dictionary: dict, context: context) }), + url: try dictionary.getExpressionField("url", transform: URL.makeFromNonEncodedString, context: context) + ) + } + init( bitrate: Expression? = nil, mimeType: Expression, diff --git a/client/ios/DivKit/generated_sources/DivVisibilityAction.swift b/client/ios/DivKit/generated_sources/DivVisibilityAction.swift index 41466a098..8a05b0d91 100644 --- a/client/ios/DivKit/generated_sources/DivVisibilityAction.swift +++ b/client/ios/DivKit/generated_sources/DivVisibilityAction.swift @@ -54,6 +54,22 @@ public final class DivVisibilityAction: DivSightAction, @unchecked Sendable { static let visibilityPercentageValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 > 0 && $0 <= 100 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + downloadCallbacks: try dictionary.getOptionalField("download_callbacks", transform: { (dict: [String: Any]) in try DivDownloadCallbacks(dictionary: dict, context: context) }), + isEnabled: try dictionary.getOptionalExpressionField("is_enabled", context: context), + logId: try dictionary.getExpressionField("log_id", context: context), + logLimit: try dictionary.getOptionalExpressionField("log_limit", validator: Self.logLimitValidator, context: context), + payload: try dictionary.getOptionalField("payload", context: context), + referer: try dictionary.getOptionalExpressionField("referer", transform: URL.makeFromNonEncodedString, context: context), + scopeId: try dictionary.getOptionalField("scope_id", context: context), + typed: try dictionary.getOptionalField("typed", transform: { (dict: [String: Any]) in try DivActionTyped(dictionary: dict, context: context) }), + url: try dictionary.getOptionalExpressionField("url", transform: URL.makeFromNonEncodedString, context: context), + visibilityDuration: try dictionary.getOptionalExpressionField("visibility_duration", validator: Self.visibilityDurationValidator, context: context), + visibilityPercentage: try dictionary.getOptionalExpressionField("visibility_percentage", validator: Self.visibilityPercentageValidator, context: context) + ) + } + init( downloadCallbacks: DivDownloadCallbacks? = nil, isEnabled: Expression? = nil, diff --git a/client/ios/DivKit/generated_sources/DivWrapContentSize.swift b/client/ios/DivKit/generated_sources/DivWrapContentSize.swift index 37805764e..5c25851bf 100644 --- a/client/ios/DivKit/generated_sources/DivWrapContentSize.swift +++ b/client/ios/DivKit/generated_sources/DivWrapContentSize.swift @@ -14,6 +14,14 @@ public final class DivWrapContentSize: Sendable { resolver.resolveNumeric(constrained) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + constrained: try dictionary.getOptionalExpressionField("constrained", context: context), + maxSize: try dictionary.getOptionalField("max_size", transform: { (dict: [String: Any]) in try DivSizeUnitValue(dictionary: dict, context: context) }), + minSize: try dictionary.getOptionalField("min_size", transform: { (dict: [String: Any]) in try DivSizeUnitValue(dictionary: dict, context: context) }) + ) + } + init( constrained: Expression? = nil, maxSize: DivSizeUnitValue? = nil, diff --git a/client/ios/DivKit/generated_sources/EndDestination.swift b/client/ios/DivKit/generated_sources/EndDestination.swift index db5a1d73a..c44687ca2 100644 --- a/client/ios/DivKit/generated_sources/EndDestination.swift +++ b/client/ios/DivKit/generated_sources/EndDestination.swift @@ -7,6 +7,8 @@ import VGSL public final class EndDestination: Sendable { public static let type: String = "end" + public init(dictionary: [String: Any], context: ParsingContext) throws {} + init() {} } diff --git a/client/ios/DivKit/generated_sources/IndexDestination.swift b/client/ios/DivKit/generated_sources/IndexDestination.swift index 0477d3785..5ee01668d 100644 --- a/client/ios/DivKit/generated_sources/IndexDestination.swift +++ b/client/ios/DivKit/generated_sources/IndexDestination.swift @@ -15,6 +15,12 @@ public final class IndexDestination: Sendable { static let valueValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", validator: Self.valueValidator, context: context) + ) + } + init( value: Expression ) { diff --git a/client/ios/DivKit/generated_sources/IntegerValue.swift b/client/ios/DivKit/generated_sources/IntegerValue.swift index ea029ce40..91fbf1ae0 100644 --- a/client/ios/DivKit/generated_sources/IntegerValue.swift +++ b/client/ios/DivKit/generated_sources/IntegerValue.swift @@ -12,6 +12,12 @@ public final class IntegerValue: Sendable { resolver.resolveNumeric(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( value: Expression ) { diff --git a/client/ios/DivKit/generated_sources/IntegerVariable.swift b/client/ios/DivKit/generated_sources/IntegerVariable.swift index 2ba45d5e7..fcf54399e 100644 --- a/client/ios/DivKit/generated_sources/IntegerVariable.swift +++ b/client/ios/DivKit/generated_sources/IntegerVariable.swift @@ -13,6 +13,13 @@ public final class IntegerVariable: Sendable { resolver.resolveNumeric(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + name: try dictionary.getField("name", context: context), + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( name: String, value: Expression diff --git a/client/ios/DivKit/generated_sources/NumberValue.swift b/client/ios/DivKit/generated_sources/NumberValue.swift index 455b9dea5..d4df0413b 100644 --- a/client/ios/DivKit/generated_sources/NumberValue.swift +++ b/client/ios/DivKit/generated_sources/NumberValue.swift @@ -12,6 +12,12 @@ public final class NumberValue: Sendable { resolver.resolveNumeric(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( value: Expression ) { diff --git a/client/ios/DivKit/generated_sources/NumberVariable.swift b/client/ios/DivKit/generated_sources/NumberVariable.swift index 7277ee750..1349b6a26 100644 --- a/client/ios/DivKit/generated_sources/NumberVariable.swift +++ b/client/ios/DivKit/generated_sources/NumberVariable.swift @@ -13,6 +13,13 @@ public final class NumberVariable: Sendable { resolver.resolveNumeric(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + name: try dictionary.getField("name", context: context), + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( name: String, value: Expression diff --git a/client/ios/DivKit/generated_sources/OffsetDestination.swift b/client/ios/DivKit/generated_sources/OffsetDestination.swift index 384589ae5..7bef952f4 100644 --- a/client/ios/DivKit/generated_sources/OffsetDestination.swift +++ b/client/ios/DivKit/generated_sources/OffsetDestination.swift @@ -15,6 +15,12 @@ public final class OffsetDestination: Sendable { static let valueValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 >= 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", validator: Self.valueValidator, context: context) + ) + } + init( value: Expression ) { diff --git a/client/ios/DivKit/generated_sources/PropertyVariable.swift b/client/ios/DivKit/generated_sources/PropertyVariable.swift index 697634f16..e5b479a36 100644 --- a/client/ios/DivKit/generated_sources/PropertyVariable.swift +++ b/client/ios/DivKit/generated_sources/PropertyVariable.swift @@ -16,6 +16,16 @@ public final class PropertyVariable: Sendable { resolver.resolveString(get) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + get: try dictionary.getExpressionField("get", context: context), + name: try dictionary.getField("name", context: context), + newValueVariableName: try dictionary.getOptionalField("new_value_variable_name", context: context), + set: try dictionary.getOptionalArray("set", transform: { (dict: [String: Any]) in try? DivAction(dictionary: dict, context: context) }), + valueType: try dictionary.getField("value_type", context: context) + ) + } + init( get: Expression, name: String, diff --git a/client/ios/DivKit/generated_sources/StartDestination.swift b/client/ios/DivKit/generated_sources/StartDestination.swift index 7afd8039e..963d8dc5f 100644 --- a/client/ios/DivKit/generated_sources/StartDestination.swift +++ b/client/ios/DivKit/generated_sources/StartDestination.swift @@ -7,6 +7,8 @@ import VGSL public final class StartDestination: Sendable { public static let type: String = "start" + public init(dictionary: [String: Any], context: ParsingContext) throws {} + init() {} } diff --git a/client/ios/DivKit/generated_sources/StringValue.swift b/client/ios/DivKit/generated_sources/StringValue.swift index 29c43f1e1..3bc0de13c 100644 --- a/client/ios/DivKit/generated_sources/StringValue.swift +++ b/client/ios/DivKit/generated_sources/StringValue.swift @@ -12,6 +12,12 @@ public final class StringValue: Sendable { resolver.resolveString(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( value: Expression ) { diff --git a/client/ios/DivKit/generated_sources/StringVariable.swift b/client/ios/DivKit/generated_sources/StringVariable.swift index c65d1ee45..b0dba2b5e 100644 --- a/client/ios/DivKit/generated_sources/StringVariable.swift +++ b/client/ios/DivKit/generated_sources/StringVariable.swift @@ -13,6 +13,13 @@ public final class StringVariable: Sendable { resolver.resolveString(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + name: try dictionary.getField("name", context: context), + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( name: String, value: Expression diff --git a/client/ios/DivKit/generated_sources/UrlValue.swift b/client/ios/DivKit/generated_sources/UrlValue.swift index a19dc6b0c..046296faf 100644 --- a/client/ios/DivKit/generated_sources/UrlValue.swift +++ b/client/ios/DivKit/generated_sources/UrlValue.swift @@ -12,6 +12,12 @@ public final class UrlValue: Sendable { resolver.resolveUrl(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", transform: URL.makeFromNonEncodedString, context: context) + ) + } + init( value: Expression ) { diff --git a/client/ios/DivKit/generated_sources/UrlVariable.swift b/client/ios/DivKit/generated_sources/UrlVariable.swift index 9033ee7e7..33d52e1b9 100644 --- a/client/ios/DivKit/generated_sources/UrlVariable.swift +++ b/client/ios/DivKit/generated_sources/UrlVariable.swift @@ -13,6 +13,13 @@ public final class UrlVariable: Sendable { resolver.resolveUrl(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + name: try dictionary.getField("name", context: context), + value: try dictionary.getExpressionField("value", transform: URL.makeFromNonEncodedString, context: context) + ) + } + init( name: String, value: Expression diff --git a/client/ios/DivKitPlayground/Utils/Palette.swift b/client/ios/DivKitPlayground/Utils/Palette.swift index 3ec37b2c9..798985ef2 100644 --- a/client/ios/DivKitPlayground/Utils/Palette.swift +++ b/client/ios/DivKitPlayground/Utils/Palette.swift @@ -9,7 +9,7 @@ struct Palette { } func makeVariables(theme: Theme) -> DivVariables { - guard let palette = json.getArray(theme.rawValue).value as? [[String: String]] else { + guard let palette: [[String: String]] = try? json.getArray(theme.rawValue) else { return [:] } diff --git a/client/ios/DivKitTests/DictionarySerializationBehaviorTests.swift b/client/ios/DivKitTests/DictionarySerializationBehaviorTests.swift new file mode 100644 index 000000000..58446980e --- /dev/null +++ b/client/ios/DivKitTests/DictionarySerializationBehaviorTests.swift @@ -0,0 +1,95 @@ +import Serialization +import XCTest + +final class DictionarySerializationBehaviorTests: XCTestCase { + func testRequiredField_WhenMissing_ThrowsNoData() { + let dictionary: [String: Any] = [:] + + XCTAssertThrowsError(try dictionary.getField("value") as String) { error in + guard case .noData = error as? DeserializationError else { + return XCTFail("Expected noData, got: \(error)") + } + } + } + + func testOptionalFieldWithoutContext_WhenInvalidType_ReturnsNil() throws { + let dictionary: [String: Any] = ["value": "text"] + + let parsed: Int? = try dictionary.getOptionalField("value") + + XCTAssertNil(parsed) + } + + func testOptionalFieldWithContext_WhenInvalidType_ReturnsNilAndAppendsWarning() throws { + let dictionary: [String: Any] = ["value": "text"] + let context = ParsingContext() + + let parsed: Int? = try dictionary.getOptionalField("value", context: context) + + XCTAssertNil(parsed) + XCTAssertEqual(context.errors.count, 0) + XCTAssertEqual(context.warnings.count, 1) + } + + func testOptionalArrayWithoutContext_WhenElementTypeInvalid_Throws() { + let dictionary: [String: Any] = ["items": [1, "bad", 3]] + + XCTAssertThrowsError( + try dictionary.getOptionalArray( + "items", + transform: { (value: Int) throws -> Int in value } + ) as [Int]? + ) { error in + guard case .invalidFieldRepresentation = error as? DeserializationError else { + return XCTFail("Expected invalidFieldRepresentation, got: \(error)") + } + } + } + + func testOptionalArrayWithoutContext_WhenTransformFails_DropsInvalidElement() throws { + let dictionary: [String: Any] = ["items": [1, 2, 3]] + + let parsed: [Int]? = try dictionary.getOptionalArray( + "items", + transform: { (value: Int) throws -> Int in + if value == 2 { + throw DeserializationError.generic + } + return value + } + ) + + XCTAssertEqual(parsed, [1, 3]) + } + + func testOptionalArrayWithContext_WhenElementTypeInvalid_AppendsWarningAndKeepsPartialResult( + ) throws { + let dictionary: [String: Any] = ["items": [1, "bad", 3]] + let context = ParsingContext() + + let parsed: [Int]? = try dictionary.getOptionalArray("items", context: context) + + XCTAssertEqual(parsed, [1, 3]) + XCTAssertEqual(context.errors.count, 0) + XCTAssertEqual(context.warnings.count, 1) + } + + func testOptionalFieldValidatorParity_WithAndWithoutContext() throws { + let dictionary: [String: Any] = ["value": 5] + let validator = makeValueValidator { (value: Int) in value > 10 } + + let withoutContext: Int? = try dictionary.getOptionalField("value", validator: validator) + + let context = ParsingContext() + let withContext: Int? = try dictionary.getOptionalField( + "value", + validator: validator, + context: context + ) + + XCTAssertNil(withoutContext) + XCTAssertNil(withContext) + XCTAssertEqual(context.errors.count, 0) + XCTAssertEqual(context.warnings.count, 1) + } +} diff --git a/client/ios/DivKitTests/DivDataParsingTests.swift b/client/ios/DivKitTests/DivDataParsingTests.swift index b5d45bf7c..6a73a5435 100644 --- a/client/ios/DivKitTests/DivDataParsingTests.swift +++ b/client/ios/DivKitTests/DivDataParsingTests.swift @@ -9,7 +9,16 @@ final class DivDataParsingTests: XCTestCase { } private func runTest(_ data: TestData) { - let result = DivData.resolve(card: data.card, templates: data.templates) + let typedResult = DivData.resolve( + card: data.card, + templates: data.templates, + flagsInfo: DivFlagsInfo(useUntypedTemplateResolver: false) + ) + let untypedResult = DivData.resolve( + card: data.card, + templates: data.templates, + flagsInfo: DivFlagsInfo(useUntypedTemplateResolver: true) + ) let expectedResult = DivData.resolve(card: data.expectedCard, templates: [:]) XCTAssertNil( @@ -17,13 +26,19 @@ private func runTest(_ data: TestData) { "Test data corrupted: expected result contains errors" ) - assertEqual(result.value, expectedResult.value) + assertEqual(typedResult.value, expectedResult.value) + assertEqual(untypedResult.value, expectedResult.value) XCTAssertEqual( - result.errorsOrWarnings?.count ?? 0, + typedResult.errorsOrWarnings?.count ?? 0, data.expectedErrorCount, "Expected error count does not match actual result" ) + XCTAssertEqual( + untypedResult.errorsOrWarnings?.count ?? 0, + typedResult.errorsOrWarnings?.count ?? 0, + "Untyped pipeline should produce same number of warnings/errors as typed" + ) } private func makeTestCases() -> [(String, TestData)] { diff --git a/client/ios/DivKitTests/Entities/generated_sources/Entity.swift b/client/ios/DivKitTests/Entities/generated_sources/Entity.swift index fc993c001..8da83c70f 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/Entity.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/Entity.swift @@ -73,6 +73,54 @@ public enum Entity: Sendable { } } +extension Entity { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case EntityWithArray.type: + self = .entityWithArray(try EntityWithArray(dictionary: dictionary, context: context)) + case EntityWithArrayOfEnums.type: + self = .entityWithArrayOfEnums(try EntityWithArrayOfEnums(dictionary: dictionary, context: context)) + case EntityWithArrayOfExpressions.type: + self = .entityWithArrayOfExpressions(try EntityWithArrayOfExpressions(dictionary: dictionary, context: context)) + case EntityWithArrayOfNestedItems.type: + self = .entityWithArrayOfNestedItems(try EntityWithArrayOfNestedItems(dictionary: dictionary, context: context)) + case EntityWithArrayWithTransform.type: + self = .entityWithArrayWithTransform(try EntityWithArrayWithTransform(dictionary: dictionary, context: context)) + case EntityWithComplexProperty.type: + self = .entityWithComplexProperty(try EntityWithComplexProperty(dictionary: dictionary, context: context)) + case EntityWithComplexPropertyWithDefaultValue.type: + self = .entityWithComplexPropertyWithDefaultValue(try EntityWithComplexPropertyWithDefaultValue(dictionary: dictionary, context: context)) + case EntityWithEntityProperty.type: + self = .entityWithEntityProperty(try EntityWithEntityProperty(dictionary: dictionary, context: context)) + case EntityWithOptionalComplexProperty.type: + self = .entityWithOptionalComplexProperty(try EntityWithOptionalComplexProperty(dictionary: dictionary, context: context)) + case EntityWithOptionalProperty.type: + self = .entityWithOptionalProperty(try EntityWithOptionalProperty(dictionary: dictionary, context: context)) + case EntityWithOptionalStringEnumProperty.type: + self = .entityWithOptionalStringEnumProperty(try EntityWithOptionalStringEnumProperty(dictionary: dictionary, context: context)) + case EntityWithPropertyWithDefaultValue.type: + self = .entityWithPropertyWithDefaultValue(try EntityWithPropertyWithDefaultValue(dictionary: dictionary, context: context)) + case EntityWithRawArray.type: + self = .entityWithRawArray(try EntityWithRawArray(dictionary: dictionary, context: context)) + case EntityWithRequiredProperty.type: + self = .entityWithRequiredProperty(try EntityWithRequiredProperty(dictionary: dictionary, context: context)) + case EntityWithSimpleProperties.type: + self = .entityWithSimpleProperties(try EntityWithSimpleProperties(dictionary: dictionary, context: context)) + case EntityWithStringArrayProperty.type: + self = .entityWithStringArrayProperty(try EntityWithStringArrayProperty(dictionary: dictionary, context: context)) + case EntityWithStringEnumProperty.type: + self = .entityWithStringEnumProperty(try EntityWithStringEnumProperty(dictionary: dictionary, context: context)) + case EntityWithStringEnumPropertyWithDefaultValue.type: + self = .entityWithStringEnumPropertyWithDefaultValue(try EntityWithStringEnumPropertyWithDefaultValue(dictionary: dictionary, context: context)) + case EntityWithoutProperties.type: + self = .entityWithoutProperties(try EntityWithoutProperties(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "entity", representation: dictionary) + } + } +} + #if DEBUG extension Entity: Equatable { public static func ==(lhs: Entity, rhs: Entity) -> Bool { diff --git a/client/ios/DivKitTests/Entities/generated_sources/EntityWithArray.swift b/client/ios/DivKitTests/Entities/generated_sources/EntityWithArray.swift index 46ae10361..80050f67c 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EntityWithArray.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EntityWithArray.swift @@ -14,6 +14,12 @@ public final class EntityWithArray: Sendable { static let arrayValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + array: try dictionary.getArray("array", transform: { (dict: [String: Any]) in try? Entity(dictionary: dict, context: context) }, validator: Self.arrayValidator) + ) + } + init( array: [Entity] ) { diff --git a/client/ios/DivKitTests/Entities/generated_sources/EntityWithArrayOfEnums.swift b/client/ios/DivKitTests/Entities/generated_sources/EntityWithArrayOfEnums.swift index 207ba7c7b..3c7f8d952 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EntityWithArrayOfEnums.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EntityWithArrayOfEnums.swift @@ -20,6 +20,12 @@ public final class EntityWithArrayOfEnums: Sendable { static let itemsValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + items: try dictionary.getArray("items", validator: Self.itemsValidator, context: context) + ) + } + init( items: [Item] ) { diff --git a/client/ios/DivKitTests/Entities/generated_sources/EntityWithArrayOfExpressions.swift b/client/ios/DivKitTests/Entities/generated_sources/EntityWithArrayOfExpressions.swift index c02c5da2c..3c4b5a3e9 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EntityWithArrayOfExpressions.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EntityWithArrayOfExpressions.swift @@ -18,6 +18,12 @@ public final class EntityWithArrayOfExpressions: Sendable { static let itemsValidator: AnyArrayValueValidator> = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + items: try dictionary.getExpressionArray("items", validator: Self.itemsValidator, context: context) + ) + } + init( items: [Expression] ) { diff --git a/client/ios/DivKitTests/Entities/generated_sources/EntityWithArrayOfNestedItems.swift b/client/ios/DivKitTests/Entities/generated_sources/EntityWithArrayOfNestedItems.swift index fb4386e3d..8ba93b118 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EntityWithArrayOfNestedItems.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EntityWithArrayOfNestedItems.swift @@ -16,6 +16,13 @@ public final class EntityWithArrayOfNestedItems: Sendable { resolver.resolveString(property) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + entity: try dictionary.getField("entity", transform: { (dict: [String: Any]) in try Entity(dictionary: dict, context: context) }), + property: try dictionary.getExpressionField("property", context: context) + ) + } + init( entity: Entity, property: Expression @@ -31,6 +38,12 @@ public final class EntityWithArrayOfNestedItems: Sendable { static let itemsValidator: AnyArrayValueValidator = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + items: try dictionary.getArray("items", transform: { (dict: [String: Any]) in try? EntityWithArrayOfNestedItems.Item(dictionary: dict, context: context) }, validator: Self.itemsValidator) + ) + } + init( items: [Item] ) { diff --git a/client/ios/DivKitTests/Entities/generated_sources/EntityWithArrayWithTransform.swift b/client/ios/DivKitTests/Entities/generated_sources/EntityWithArrayWithTransform.swift index c3f6ae165..932ad8649 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EntityWithArrayWithTransform.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EntityWithArrayWithTransform.swift @@ -18,6 +18,12 @@ public final class EntityWithArrayWithTransform: Sendable { static let arrayValidator: AnyArrayValueValidator> = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + array: try dictionary.getExpressionArray("array", transform: Color.color(withHexString:), validator: Self.arrayValidator, context: context) + ) + } + init( array: [Expression] ) { diff --git a/client/ios/DivKitTests/Entities/generated_sources/EntityWithComplexProperty.swift b/client/ios/DivKitTests/Entities/generated_sources/EntityWithComplexProperty.swift index 6add75b9e..22bbe9ac1 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EntityWithComplexProperty.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EntityWithComplexProperty.swift @@ -15,6 +15,12 @@ public final class EntityWithComplexProperty: Sendable { resolver.resolveUrl(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", transform: URL.makeFromNonEncodedString, context: context) + ) + } + init( value: Expression ) { @@ -25,6 +31,12 @@ public final class EntityWithComplexProperty: Sendable { public static let type: String = "entity_with_complex_property" public let property: Property + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getField("property", transform: { (dict: [String: Any]) in try EntityWithComplexProperty.Property(dictionary: dict, context: context) }) + ) + } + init( property: Property ) { diff --git a/client/ios/DivKitTests/Entities/generated_sources/EntityWithComplexPropertyWithDefaultValue.swift b/client/ios/DivKitTests/Entities/generated_sources/EntityWithComplexPropertyWithDefaultValue.swift index 7ea24e312..71ce262a6 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EntityWithComplexPropertyWithDefaultValue.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EntityWithComplexPropertyWithDefaultValue.swift @@ -15,6 +15,12 @@ public final class EntityWithComplexPropertyWithDefaultValue: Sendable { resolver.resolveString(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", context: context) + ) + } + init( value: Expression ) { @@ -25,6 +31,12 @@ public final class EntityWithComplexPropertyWithDefaultValue: Sendable { public static let type: String = "entity_with_complex_property_with_default_value" public let property: Property // default value: EntityWithComplexPropertyWithDefaultValue.Property(value: .value("Default text")) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getOptionalField("property", transform: { (dict: [String: Any]) in try EntityWithComplexPropertyWithDefaultValue.Property(dictionary: dict, context: context) }) + ) + } + init( property: Property? = nil ) { diff --git a/client/ios/DivKitTests/Entities/generated_sources/EntityWithEntityProperty.swift b/client/ios/DivKitTests/Entities/generated_sources/EntityWithEntityProperty.swift index ab470273c..f0fdd48c6 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EntityWithEntityProperty.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EntityWithEntityProperty.swift @@ -11,6 +11,12 @@ public final class EntityWithEntityProperty: Sendable { public static let type: String = "entity_with_entity_property" public let entity: Entity // default value: .entityWithStringEnumProperty(EntityWithStringEnumProperty(property: .value(.second))) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + entity: try dictionary.getOptionalField("entity", transform: { (dict: [String: Any]) in try Entity(dictionary: dict, context: context) }) + ) + } + init( entity: Entity? = nil ) { diff --git a/client/ios/DivKitTests/Entities/generated_sources/EntityWithJsonProperty.swift b/client/ios/DivKitTests/Entities/generated_sources/EntityWithJsonProperty.swift index 4572bfb01..13926b78c 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EntityWithJsonProperty.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EntityWithJsonProperty.swift @@ -11,6 +11,12 @@ public final class EntityWithJsonProperty: @unchecked Sendable { public static let type: String = "entity_with_json_property" public let jsonProperty: [String: Any] // default value: { "key": "value", "items": [ "value" ] } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + jsonProperty: try dictionary.getOptionalField("json_property", context: context) + ) + } + init( jsonProperty: [String: Any]? = nil ) { diff --git a/client/ios/DivKitTests/Entities/generated_sources/EntityWithOptionalComplexProperty.swift b/client/ios/DivKitTests/Entities/generated_sources/EntityWithOptionalComplexProperty.swift index f9c2964fc..f33d7d177 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EntityWithOptionalComplexProperty.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EntityWithOptionalComplexProperty.swift @@ -15,6 +15,12 @@ public final class EntityWithOptionalComplexProperty: Sendable { resolver.resolveUrl(value) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getExpressionField("value", transform: URL.makeFromNonEncodedString, context: context) + ) + } + init( value: Expression ) { @@ -25,6 +31,12 @@ public final class EntityWithOptionalComplexProperty: Sendable { public static let type: String = "entity_with_optional_complex_property" public let property: Property? + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getOptionalField("property", transform: { (dict: [String: Any]) in try EntityWithOptionalComplexProperty.Property(dictionary: dict, context: context) }) + ) + } + init( property: Property? = nil ) { diff --git a/client/ios/DivKitTests/Entities/generated_sources/EntityWithOptionalProperty.swift b/client/ios/DivKitTests/Entities/generated_sources/EntityWithOptionalProperty.swift index 851e1d1ba..67de866e6 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EntityWithOptionalProperty.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EntityWithOptionalProperty.swift @@ -15,6 +15,12 @@ public final class EntityWithOptionalProperty: Sendable { resolver.resolveString(property) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getOptionalExpressionField("property", context: context) + ) + } + init( property: Expression? = nil ) { diff --git a/client/ios/DivKitTests/Entities/generated_sources/EntityWithOptionalStringEnumProperty.swift b/client/ios/DivKitTests/Entities/generated_sources/EntityWithOptionalStringEnumProperty.swift index 25804362d..b0faccc6c 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EntityWithOptionalStringEnumProperty.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EntityWithOptionalStringEnumProperty.swift @@ -21,6 +21,12 @@ public final class EntityWithOptionalStringEnumProperty: Sendable { resolver.resolveEnum(property) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getOptionalExpressionField("property", context: context) + ) + } + init( property: Expression? = nil ) { diff --git a/client/ios/DivKitTests/Entities/generated_sources/EntityWithPropertyWithDefaultValue.swift b/client/ios/DivKitTests/Entities/generated_sources/EntityWithPropertyWithDefaultValue.swift index 9aa77cae4..4d5fa4521 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EntityWithPropertyWithDefaultValue.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EntityWithPropertyWithDefaultValue.swift @@ -31,6 +31,14 @@ public final class EntityWithPropertyWithDefaultValue: Sendable { static let urlValidator: AnyValueValidator = makeURLValidator(schemes: ["https"]) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + int: try dictionary.getOptionalExpressionField("int", validator: Self.intValidator, context: context), + nonOptional: try dictionary.getExpressionField("non_optional", context: context), + url: try dictionary.getOptionalExpressionField("url", transform: URL.makeFromNonEncodedString, validator: Self.urlValidator, context: context) + ) + } + init( int: Expression? = nil, nonOptional: Expression, @@ -61,6 +69,14 @@ public final class EntityWithPropertyWithDefaultValue: Sendable { static let urlValidator: AnyValueValidator = makeURLValidator(schemes: ["https"]) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + int: try dictionary.getOptionalExpressionField("int", validator: Self.intValidator, context: context), + nested: try dictionary.getOptionalField("nested", transform: { (dict: [String: Any]) in try EntityWithPropertyWithDefaultValue.Nested(dictionary: dict, context: context) }), + url: try dictionary.getOptionalExpressionField("url", transform: URL.makeFromNonEncodedString, validator: Self.urlValidator, context: context) + ) + } + init( int: Expression? = nil, nested: Nested? = nil, diff --git a/client/ios/DivKitTests/Entities/generated_sources/EntityWithRawArray.swift b/client/ios/DivKitTests/Entities/generated_sources/EntityWithRawArray.swift index 8c26f1bb2..e64fe93a2 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EntityWithRawArray.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EntityWithRawArray.swift @@ -15,6 +15,12 @@ public final class EntityWithRawArray: @unchecked Sendable { resolver.resolveArray(array) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + array: try dictionary.getExpressionField("array", context: context) + ) + } + init( array: Expression<[Any]> ) { diff --git a/client/ios/DivKitTests/Entities/generated_sources/EntityWithRequiredProperty.swift b/client/ios/DivKitTests/Entities/generated_sources/EntityWithRequiredProperty.swift index 71b3af7e8..6d1fc3d13 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EntityWithRequiredProperty.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EntityWithRequiredProperty.swift @@ -18,6 +18,12 @@ public final class EntityWithRequiredProperty: Sendable { static let propertyValidator: AnyValueValidator = makeStringValidator(minLength: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getExpressionField("property", validator: Self.propertyValidator, context: context) + ) + } + init( property: Expression ) { diff --git a/client/ios/DivKitTests/Entities/generated_sources/EntityWithSimpleProperties.swift b/client/ios/DivKitTests/Entities/generated_sources/EntityWithSimpleProperties.swift index f66700bb5..f0daf12ce 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EntityWithSimpleProperties.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EntityWithSimpleProperties.swift @@ -54,6 +54,20 @@ public final class EntityWithSimpleProperties: EntityProtocol, Sendable { static let positiveIntegerValidator: AnyValueValidator = makeValueValidator(valueValidator: { $0 > 0 }) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + boolean: try dictionary.getOptionalExpressionField("boolean", context: context), + booleanInt: try dictionary.getOptionalExpressionField("boolean_int", context: context), + color: try dictionary.getOptionalExpressionField("color", transform: Color.color(withHexString:), context: context), + double: try dictionary.getOptionalExpressionField("double", context: context), + id: try dictionary.getOptionalField("id", context: context), + integer: try dictionary.getOptionalExpressionField("integer", context: context), + positiveInteger: try dictionary.getOptionalExpressionField("positive_integer", validator: Self.positiveIntegerValidator, context: context), + string: try dictionary.getOptionalExpressionField("string", context: context), + url: try dictionary.getOptionalExpressionField("url", transform: URL.makeFromNonEncodedString, context: context) + ) + } + init( boolean: Expression? = nil, booleanInt: Expression? = nil, diff --git a/client/ios/DivKitTests/Entities/generated_sources/EntityWithStringArrayProperty.swift b/client/ios/DivKitTests/Entities/generated_sources/EntityWithStringArrayProperty.swift index 485b7c6af..e49e4d2f5 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EntityWithStringArrayProperty.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EntityWithStringArrayProperty.swift @@ -18,6 +18,12 @@ public final class EntityWithStringArrayProperty: Sendable { static let arrayValidator: AnyArrayValueValidator> = makeArrayValidator(minItems: 1) + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + array: try dictionary.getExpressionArray("array", validator: Self.arrayValidator, context: context) + ) + } + init( array: [Expression] ) { diff --git a/client/ios/DivKitTests/Entities/generated_sources/EntityWithStringEnumProperty.swift b/client/ios/DivKitTests/Entities/generated_sources/EntityWithStringEnumProperty.swift index f65adf9d2..5dc83c0f2 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EntityWithStringEnumProperty.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EntityWithStringEnumProperty.swift @@ -21,6 +21,12 @@ public final class EntityWithStringEnumProperty: Sendable { resolver.resolveEnum(property) } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + property: try dictionary.getExpressionField("property", context: context) + ) + } + init( property: Expression ) { diff --git a/client/ios/DivKitTests/Entities/generated_sources/EntityWithStringEnumPropertyWithDefaultValue.swift b/client/ios/DivKitTests/Entities/generated_sources/EntityWithStringEnumPropertyWithDefaultValue.swift index 657529fd0..195295f9b 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EntityWithStringEnumPropertyWithDefaultValue.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EntityWithStringEnumPropertyWithDefaultValue.swift @@ -22,6 +22,12 @@ public final class EntityWithStringEnumPropertyWithDefaultValue: Sendable { resolver.resolveEnum(value) ?? Value.second } + public convenience init(dictionary: [String: Any], context: ParsingContext) throws { + self.init( + value: try dictionary.getOptionalExpressionField("value", context: context) + ) + } + init( value: Expression? = nil ) { diff --git a/client/ios/DivKitTests/Entities/generated_sources/EntityWithoutProperties.swift b/client/ios/DivKitTests/Entities/generated_sources/EntityWithoutProperties.swift index 339b8f9c0..c2f460686 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EntityWithoutProperties.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EntityWithoutProperties.swift @@ -10,6 +10,8 @@ import enum DivKit.Expression public final class EntityWithoutProperties: Sendable { public static let type: String = "entity_without_properties" + public init(dictionary: [String: Any], context: ParsingContext) throws {} + init() {} } diff --git a/client/ios/DivKitTests/Entities/generated_sources/EnumWithDefaultType.swift b/client/ios/DivKitTests/Entities/generated_sources/EnumWithDefaultType.swift index 211090603..39e9866f3 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/EnumWithDefaultType.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/EnumWithDefaultType.swift @@ -22,6 +22,20 @@ public enum EnumWithDefaultType: Sendable { } } +extension EnumWithDefaultType { + public init(dictionary: [String: Any], context: ParsingContext) throws { + let blockType = try dictionary.getField("type") as String + switch blockType { + case WithDefault.type: + self = .withDefault(try WithDefault(dictionary: dictionary, context: context)) + case WithoutDefault.type: + self = .withoutDefault(try WithoutDefault(dictionary: dictionary, context: context)) + default: + throw DeserializationError.invalidFieldRepresentation(field: "enum_with_default_type", representation: dictionary) + } + } +} + #if DEBUG extension EnumWithDefaultType: Equatable { public static func ==(lhs: EnumWithDefaultType, rhs: EnumWithDefaultType) -> Bool { diff --git a/client/ios/DivKitTests/Entities/generated_sources/WithDefault.swift b/client/ios/DivKitTests/Entities/generated_sources/WithDefault.swift index 208410735..117b65fc3 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/WithDefault.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/WithDefault.swift @@ -10,6 +10,8 @@ import enum DivKit.Expression public final class WithDefault: Sendable { public static let type: String = "default" + public init(dictionary: [String: Any], context: ParsingContext) throws {} + init() {} } diff --git a/client/ios/DivKitTests/Entities/generated_sources/WithoutDefault.swift b/client/ios/DivKitTests/Entities/generated_sources/WithoutDefault.swift index 566677d48..01a573e8e 100644 --- a/client/ios/DivKitTests/Entities/generated_sources/WithoutDefault.swift +++ b/client/ios/DivKitTests/Entities/generated_sources/WithoutDefault.swift @@ -10,6 +10,8 @@ import enum DivKit.Expression public final class WithoutDefault: Sendable { public static let type: String = "non_default" + public init(dictionary: [String: Any], context: ParsingContext) throws {} + init() {} } diff --git a/client/ios/DivKitTests/IntegrationTests.swift b/client/ios/DivKitTests/IntegrationTests.swift index 722d91bd9..06b466d91 100644 --- a/client/ios/DivKitTests/IntegrationTests.swift +++ b/client/ios/DivKitTests/IntegrationTests.swift @@ -151,10 +151,25 @@ private struct IntegrationTest: Decodable, @unchecked Sendable { let templates = divDataJson["templates"] as? [String: Any] ?? [:] self.description = json["description"] as! String - let result = DivData.resolve(card: card, templates: templates) - let errors = result.errorsOrWarnings?.asArray() ?? [] + let typedResult = DivData.resolve( + card: card, + templates: templates, + flagsInfo: DivFlagsInfo(useUntypedTemplateResolver: false) + ) + let untypedResult = DivData.resolve( + card: card, + templates: templates, + flagsInfo: DivFlagsInfo(useUntypedTemplateResolver: true) + ) + XCTAssertEqual(typedResult.value, untypedResult.value) + XCTAssertEqual( + typedResult.errorsOrWarnings?.count ?? 0, + untypedResult.errorsOrWarnings?.count ?? 0 + ) + + let errors = typedResult.errorsOrWarnings?.asArray() ?? [] self.deserializationErrorMessages = errors.map(\.errorMessage) - self.divData = try? DivData.resolve(card: card, templates: templates).unwrap() + self.divData = try? typedResult.unwrap() self.cases = try! JSONDecoder().decode( [IntegrationTestCase].self, from: try JSONSerialization.data(withJSONObject: casesJson) diff --git a/client/ios/DivKitTests/Templates/DivTemplatesTests.swift b/client/ios/DivKitTests/Templates/DivTemplatesTests.swift index be09183fe..aebeb8e04 100644 --- a/client/ios/DivKitTests/Templates/DivTemplatesTests.swift +++ b/client/ios/DivKitTests/Templates/DivTemplatesTests.swift @@ -230,4 +230,53 @@ final class DivTemplatesTests: XCTestCase { XCTFail("Can't get template `text` property") } } + + func test_untypedResolver_matchesTypedResolver() { + let templates: [String: Any] = [ + "base_text": [ + "type": "text", + "font_size": 14, + "$text": "text_value", + ], + "list_item": [ + "type": "container", + "orientation": "vertical", + "items": [ + [ + "type": "base_text", + "$text_value": "title", + ], + ], + ], + ] + let card: [String: Any] = [ + "log_id": "test", + "states": [ + [ + "state_id": 0, + "div": [ + "type": "list_item", + "title": "Resolved through chain", + ], + ], + ], + ] + + let typedResult = DivData.resolve( + card: card, + templates: templates, + flagsInfo: DivFlagsInfo(useUntypedTemplateResolver: false) + ) + let untypedResult = DivData.resolve( + card: card, + templates: templates, + flagsInfo: DivFlagsInfo(useUntypedTemplateResolver: true) + ) + + XCTAssertEqual(typedResult.value, untypedResult.value) + XCTAssertEqual( + typedResult.errorsOrWarnings?.count ?? 0, + untypedResult.errorsOrWarnings?.count ?? 0 + ) + } } diff --git a/client/ios/Serialization/Deserializable.swift b/client/ios/Serialization/Deserializable.swift index a760b4625..46b5089d3 100644 --- a/client/ios/Serialization/Deserializable.swift +++ b/client/ios/Serialization/Deserializable.swift @@ -1,5 +1,45 @@ import Foundation +public final class ParsingContext: @unchecked Sendable { + public private(set) var warnings: [DeserializationError] = [] + public private(set) var errors: [DeserializationError] = [] + public private(set) var path: [String] = [] + + public init() {} + + public func appendWarning(_ warning: DeserializationError) { + warnings.append(warning) + } + + public func appendError(_ error: DeserializationError) { + errors.append(error) + } + + public func appendWarnings(_ warnings: [DeserializationError]) { + self.warnings.append(contentsOf: warnings) + } + + public func appendErrors(_ errors: [DeserializationError]) { + self.errors.append(contentsOf: errors) + } + + public func append(result: DeserializationResult) { + if let warnings = result.warnings { + appendWarnings(Array(warnings)) + } + if let errors = result.errors { + appendErrors(Array(errors)) + } + } + + @discardableResult + public func withPath(_ component: String, _ body: () throws -> T) rethrows -> T { + path.append(component) + defer { _ = path.popLast() } + return try body() + } +} + public protocol Deserializable { init(dictionary: [String: Any]) throws } diff --git a/client/ios/Serialization/Dictionary+Serialization.swift b/client/ios/Serialization/Dictionary+Serialization.swift index bb96b1250..dd2660e4a 100644 --- a/client/ios/Serialization/Dictionary+Serialization.swift +++ b/client/ios/Serialization/Dictionary+Serialization.swift @@ -29,6 +29,40 @@ func getResult(_ block: () throws -> U) -> DeserializationResult { } } +@usableFromInline +func unwrapOptionalTransformedValue( + _ value: T, + key: [some Any], + transform: (T) -> U? +) throws -> U { + guard let transformed = transform(value) else { + throw invalidFieldErrorForKey(key, representation: value) + } + return transformed +} + +@usableFromInline +func rawRepresentableValue( + _ raw: T.RawValue, + key: [some Any] +) throws -> T { + guard let value = T(rawValue: raw) else { + throw invalidFieldErrorForKey(key, representation: raw) + } + return value +} + +@usableFromInline +func castValidSerializationValue( + _ value: Any, + key: [some Any] +) throws -> T { + guard let transformed = value as? T else { + throw invalidFieldErrorForKey(key, representation: value) + } + return transformed +} + extension Dictionary where Key == String { @usableFromInline func enclosedDictForKeySequence(_ keys: [Key]) throws -> Self { @@ -151,18 +185,80 @@ extension Dictionary where Key == String { extension Dictionary where Key == String { @usableFromInline - func getOptionalField( + func getOptionalFieldCore( _ key: [Key], transform: (T) throws -> U, - validator: AnyValueValidator? + validator: AnyValueValidator?, + invalidValueHandler: ((Any) -> Void)? ) throws -> U? { guard let dict = try? enclosedDictForKeySequence(key), let value = dict[key.last!] else { return nil } - guard let valueBeforeConversion = value as? T, - let result = try? transform(valueBeforeConversion), + guard let valueBeforeConversion = value as? T else { + invalidValueHandler?(value) + return nil + } + + guard let result = try? transform(valueBeforeConversion), validator?.isValid(result) != false else { + invalidValueHandler?(valueBeforeConversion) + return nil + } + + return result + } + + @usableFromInline + func getOptionalField( + _ key: [Key], + transform: (T) throws -> U, + validator: AnyValueValidator? + ) throws -> U? { + try getOptionalFieldCore( + key, + transform: transform, + validator: validator, + invalidValueHandler: nil + ) + } + + @usableFromInline + func getOptionalArrayCore( + _ key: [Key], + transform: (T) throws -> U, + validator: AnyArrayValueValidator?, + invalidContainerHandler: ((Any) -> Void)?, + invalidElementHandler: ((Int, Any) throws -> Void)?, + invalidTransformedElementHandler: ((Int, Any) -> Void)? + ) throws -> [U]? { + guard let dict = try? enclosedDictForKeySequence(key), let value = dict[key.last!] else { + return nil + } + + guard let valueBeforeConversion = value as? NSArray else { + invalidContainerHandler?(value) + return nil + } + + var result: [U] = [] + result.reserveCapacity(valueBeforeConversion.count) + for (index, element) in valueBeforeConversion.enumerated() { + guard let typedElement = element as? T else { + try invalidElementHandler?(index, element) + continue + } + + guard let transformed = try? transform(typedElement) else { + invalidTransformedElementHandler?(index, element) + continue + } + + result.append(transformed) + } + + if validator?.isValid(result) == false { + invalidContainerHandler?(valueBeforeConversion) return nil } @@ -175,30 +271,16 @@ extension Dictionary where Key == String { transform: (T) throws -> U, validator: AnyArrayValueValidator? ) throws -> [U]? { - guard let dict = try? enclosedDictForKeySequence(key), let value = dict[key.last!] else { - return nil - } - - guard let valueBeforeConversion = value as? NSArray else { - return nil - } - - let result: [U] = try valueBeforeConversion.enumerated().compactMap { - guard let element = $0.element as? T else { - throw invalidFieldErrorForKey( - key, - element: $0.offset, - representation: $0.element - ) - } - return try? transform(element) - } - - if validator?.isValid(result) == false { - return nil - } - - return result + try getOptionalArrayCore( + key, + transform: transform, + validator: validator, + invalidContainerHandler: nil, + invalidElementHandler: { index, element in + throw invalidFieldErrorForKey(key, element: index, representation: element) + }, + invalidTransformedElementHandler: nil + ) } } @@ -213,11 +295,8 @@ extension Dictionary where Key == String { ) throws -> U { try getField( key, - transform: { (value: T) throws -> U in - guard let result = transform(value) else { - throw invalidFieldErrorForKey(key, representation: value) - } - return result + transform: { value in + try unwrapOptionalTransformedValue(value, key: key, transform: transform) }, validator: validator ) @@ -256,12 +335,13 @@ extension Dictionary where Key == String { transform: (T) -> U?, validator: AnyValueValidator? ) throws -> U? { - try getOptionalField(key, transform: { (value: T) throws -> U in - guard let result = transform(value) else { - throw invalidFieldErrorForKey(key, representation: value) - } - return result - }, validator: validator) + try getOptionalField( + key, + transform: { value in + try unwrapOptionalTransformedValue(value, key: key, transform: transform) + }, + validator: validator + ) } @usableFromInline @@ -270,18 +350,87 @@ extension Dictionary where Key == String { transform: (T) -> U?, validator: AnyArrayValueValidator? ) throws -> [U]? { - try getOptionalArray(key, transform: { (value: T) throws -> U in - guard let result = transform(value) else { - throw invalidFieldErrorForKey(key, representation: value) - } - return result - }, validator: validator) + try getOptionalArray( + key, + transform: { value in + try unwrapOptionalTransformedValue(value, key: key, transform: transform) + }, + validator: validator + ) } } // MARK: Required values (public interface) extension Dictionary where Key == String { + @usableFromInline + func getFieldWithContext( + _ key: [Key], + transform: (T) throws -> U, + validator: AnyValueValidator? = nil, + context: ParsingContext + ) throws -> U { + let result: DeserializationResult = getResult { + try getField(key, transform: transform, validator: validator) + } + context.append(result: result) + return try result.unwrap() + } + + @usableFromInline + func getArrayWithContext( + _ key: [Key], + transform: (T) throws -> U, + validator: AnyArrayValueValidator? = nil, + context: ParsingContext + ) throws -> [U] { + let result: DeserializationResult<[U]> = getResult { + try getArray(key, transform: transform, validator: validator) + } + context.append(result: result) + return try result.unwrap() + } + + @usableFromInline + func getOptionalFieldWithContext( + _ key: [Key], + transform: (T) throws -> U, + validator: AnyValueValidator? = nil, + context: ParsingContext + ) throws -> U? { + try getOptionalFieldCore( + key, + transform: transform, + validator: validator, + invalidValueHandler: { value in + context.appendWarning(invalidFieldErrorForKey(key, representation: value)) + } + ) + } + + @usableFromInline + func getOptionalArrayWithContext( + _ key: [Key], + transform: (T) throws -> U, + validator: AnyArrayValueValidator? = nil, + context: ParsingContext + ) throws -> [U]? { + try getOptionalArrayCore( + key, + transform: transform, + validator: validator, + invalidContainerHandler: { value in + context.appendWarning(invalidFieldErrorForKey(key, representation: value)) + }, + invalidElementHandler: { index, element in + context.appendWarning(invalidFieldErrorForKey(key, element: index, representation: element)) + }, + invalidTransformedElementHandler: { index, element in + context.appendWarning(invalidFieldErrorForKey(key, element: index, representation: element)) + } + ) + } + @inlinable public func getField( _ key: Key..., @@ -295,7 +444,13 @@ extension Dictionary where Key == String { _ key: Key..., validator: AnyValueValidator? = nil ) throws -> T { - try getField(key, transform: T.init(rawValue:), validator: validator) + try getField( + key, + transform: { raw in + try rawRepresentableValue(raw, key: key) + }, + validator: validator + ) } @inlinable @@ -318,14 +473,6 @@ extension Dictionary where Key == String { try getArray(key, transform: { (value: Any) throws -> Any in value }, validator: validator) } - @inlinable - public func getArray( - _ key: Key..., - validator: AnyArrayValueValidator? = nil - ) -> DeserializationResult<[Any]> { - getArray(key, transform: { .success($0) }, validator: validator) - } - @inlinable public func getArray( _ key: Key..., @@ -344,15 +491,6 @@ extension Dictionary where Key == String { try getArray(key, transform: transform, validator: validator) } - @inlinable - public func getArray( - _ key: Key..., - transform: (T) -> U?, - validator: AnyArrayValueValidator? = nil - ) -> DeserializationResult<[U]> { - getArray(key, transform: transform, validator: validator) - } - @inlinable public func getArray( _ key: Key..., @@ -360,18 +498,9 @@ extension Dictionary where Key == String { ) throws -> [T] { try getArray( key, - transform: { (obj: Any) -> T? in obj as? T }, - validator: validator - ) - } - - @inlinable - public func getArray( - _ key: Key..., - validator: AnyArrayValueValidator? = nil - ) -> DeserializationResult<[T]> { - getArray( - key, transform: { (obj: Any) -> T? in obj as? T }, + transform: { (obj: Any) -> T? in + try? castValidSerializationValue(obj, key: key) + }, validator: validator ) } @@ -388,18 +517,6 @@ extension Dictionary where Key == String { ) } - @inlinable - public func getArray( - _ key: Key..., - validator: AnyArrayValueValidator? = nil - ) -> DeserializationResult<[T]> { - getArray( - key, - transform: { (dict: Self) in try T(dictionary: dict) }, - validator: validator - ) - } - @inlinable public func getField( _ key: Key..., @@ -451,7 +568,13 @@ extension Dictionary where Key == String { _ key: Key..., validator: AnyValueValidator? = nil ) throws -> T? { - try getOptionalField(key, transform: T.init(rawValue:), validator: validator) + try getOptionalField( + key, + transform: { raw in + try rawRepresentableValue(raw, key: key) + }, + validator: validator + ) } @inlinable @@ -503,7 +626,9 @@ extension Dictionary where Key == String { ) throws -> [T]? { try getOptionalArray( key, - transform: { (obj: Any) -> T? in (obj as? T.RawValue).flatMap { T(rawValue: $0) } }, + transform: { (obj: Any) -> T? in + (obj as? T.RawValue).flatMap { try? rawRepresentableValue($0, key: key) } + }, validator: validator ) } @@ -537,3 +662,259 @@ extension Dictionary where Key == String { ) } } + +// MARK: Context-aware values (public interface) + +extension Dictionary where Key == String { + @inlinable + public func getField( + _ key: Key..., + validator: AnyValueValidator? = nil, + context: ParsingContext + ) throws -> T { + try getFieldWithContext( + key, + transform: { value in + try castValidSerializationValue(value, key: key) + }, + validator: validator, + context: context + ) + } + + @inlinable + public func getField( + _ key: Key..., + validator: AnyValueValidator? = nil, + context: ParsingContext + ) throws -> T { + try getFieldWithContext( + key, + transform: { raw in + try rawRepresentableValue(raw, key: key) + }, + validator: validator, + context: context + ) + } + + @inlinable + public func getField( + _ key: Key..., + transform: (T) throws -> U, + validator: AnyValueValidator? = nil, + context: ParsingContext + ) throws -> U { + try getFieldWithContext(key, transform: transform, validator: validator, context: context) + } + + @inlinable + public func getField( + _ key: Key..., + transform: (T) -> U?, + validator: AnyValueValidator? = nil, + context: ParsingContext + ) throws -> U { + try getFieldWithContext( + key, + transform: { value in + try unwrapOptionalTransformedValue(value, key: key, transform: transform) + }, + validator: validator, + context: context + ) + } + + @inlinable + public func getArray( + _ key: Key..., + validator: AnyArrayValueValidator? = nil, + context: ParsingContext + ) throws -> [T] { + try getArrayWithContext( + key, + transform: { value in + try castValidSerializationValue(value, key: key) + }, + validator: validator, + context: context + ) + } + + @inlinable + public func getArray( + _ key: Key..., + validator: AnyArrayValueValidator? = nil, + context: ParsingContext + ) throws -> [T] { + try getArrayWithContext( + key, + transform: { (obj: Any) throws -> T in + guard let rawValue = obj as? T.RawValue else { + throw invalidFieldErrorForKey(key, representation: obj) + } + return try rawRepresentableValue(rawValue, key: key) + }, + validator: validator, + context: context + ) + } + + @inlinable + public func getArray( + _ key: Key..., + transform: (T) throws -> U, + validator: AnyArrayValueValidator? = nil, + context: ParsingContext + ) throws -> [U] { + try getArrayWithContext(key, transform: transform, validator: validator, context: context) + } + + @inlinable + public func getArray( + _ key: Key..., + transform: (T) -> U?, + validator: AnyArrayValueValidator? = nil, + context: ParsingContext + ) throws -> [U] { + try getArrayWithContext( + key, + transform: { value in + try unwrapOptionalTransformedValue(value, key: key, transform: transform) + }, + validator: validator, + context: context + ) + } + + @inlinable + public func getOptionalField( + _ key: Key..., + validator: AnyValueValidator? = nil, + context: ParsingContext + ) throws -> T? { + try getOptionalFieldWithContext( + key, + transform: { value in + try castValidSerializationValue(value, key: key) + }, + validator: validator, + context: context + ) + } + + @inlinable + public func getOptionalField( + _ key: Key..., + validator: AnyValueValidator? = nil, + context: ParsingContext + ) throws -> T? { + try getOptionalFieldWithContext( + key, + transform: { raw in + try rawRepresentableValue(raw, key: key) + }, + validator: validator, + context: context + ) + } + + @inlinable + public func getOptionalField( + _ key: Key..., + transform: (T) throws -> U, + validator: AnyValueValidator? = nil, + context: ParsingContext + ) throws -> U? { + try getOptionalFieldWithContext( + key, + transform: transform, + validator: validator, + context: context + ) + } + + @inlinable + public func getOptionalField( + _ key: Key..., + transform: (T) -> U?, + validator: AnyValueValidator? = nil, + context: ParsingContext + ) throws -> U? { + try getOptionalFieldWithContext( + key, + transform: { value in + try unwrapOptionalTransformedValue(value, key: key, transform: transform) + }, + validator: validator, + context: context + ) + } + + @inlinable + public func getOptionalArray( + _ key: Key..., + validator: AnyArrayValueValidator? = nil, + context: ParsingContext + ) throws -> [T]? { + try getOptionalArrayWithContext( + key, + transform: { value in + try castValidSerializationValue(value, key: key) + }, + validator: validator, + context: context + ) + } + + @inlinable + public func getOptionalArray( + _ key: Key..., + validator: AnyArrayValueValidator? = nil, + context: ParsingContext + ) throws -> [T]? { + try getOptionalArrayWithContext( + key, + transform: { (obj: Any) throws -> T in + guard let rawValue = obj as? T.RawValue else { + throw invalidFieldErrorForKey(key, representation: obj) + } + return try rawRepresentableValue(rawValue, key: key) + }, + validator: validator, + context: context + ) + } + + @inlinable + public func getOptionalArray( + _ key: Key..., + transform: (T) throws -> U, + validator: AnyArrayValueValidator? = nil, + context: ParsingContext + ) throws -> [U]? { + try getOptionalArrayWithContext( + key, + transform: transform, + validator: validator, + context: context + ) + } + + @inlinable + public func getOptionalArray( + _ key: Key..., + transform: (T) -> U?, + validator: AnyArrayValueValidator? = nil, + context: ParsingContext + ) throws -> [U]? { + try getOptionalArrayWithContext( + key, + transform: { value in + try unwrapOptionalTransformedValue(value, key: key, transform: transform) + }, + validator: validator, + context: context + ) + } +}