Files
divkit/client/ios/DivKit/Expressions/Serialization/FieldExtensions.swift
T
feldspar e234cd83fa Added untyped template resolver
commit_hash:299c999f2d6caad74d8568059e890770d7a6b1f2
2026-02-13 12:08:22 +03:00

150 lines
4.0 KiB
Swift

import Foundation
import Serialization
import VGSL
extension Field {
@inlinable
func resolveValue<E: ValidSerializationValue>(
context: TemplatesContext,
validator: AnyValueValidator<E>? = nil
) -> DeserializationResult<T> where T == Expression<E> {
resolveValue(
context: context,
transform: { $0 as E },
validator: validator
)
}
@inlinable
func resolveValue<E: RawRepresentable>(
context: TemplatesContext,
validator: AnyValueValidator<E>? = nil
) -> DeserializationResult<T> where T == Expression<E>, E.RawValue == String {
switch self {
case let .value(value):
.success(value)
case let .link(link):
safeValueForLink {
try context.templateData.getField(
link,
transform: {
expressionTransform($0, transform: E.init(rawValue:), validator: validator)
}
)
}
}
}
@inlinable
func resolveValue<U: ValidSerializationValue, E>(
context: TemplatesContext,
transform: (U) -> E?,
validator: AnyValueValidator<E>? = nil
) -> DeserializationResult<T> where T == Expression<E> {
switch self {
case let .value(value):
.success(value)
case let .link(link):
safeValueForLink {
try context.templateData.getField(
link,
transform: { expressionTransform($0, transform: transform, validator: validator) }
)
}
}
}
@inlinable
func resolveValue<U: ValidSerializationValue, E>(
context: TemplatesContext,
transform: (U) -> E?,
validator: AnyArrayValueValidator<Expression<E>>
) -> DeserializationResult<T> where T == [Expression<E>] {
switch self {
case let .value(value):
guard validator.isValid(value) != false else {
return .failure(NonEmptyArray(.invalidValue(result: value, value: nil)))
}
return .success(value)
case let .link(link):
return context.templateData.getArray(
link,
transform: { (value: U) -> DeserializationResult<Expression<E>> in
guard let transformed = expressionTransform(value, transform: transform) else {
return .noValue
}
return .success(transformed)
},
validator: validator
)
}
}
@inlinable
func resolveOptionalValue<E: ValidSerializationValue>(
context: TemplatesContext,
validator: AnyValueValidator<E>? = nil
) -> DeserializationResult<T> where T == Expression<E> {
resolveOptionalValue(
context: context,
transform: { $0 as E },
validator: validator
)
}
@inlinable
func resolveOptionalValue<E: RawRepresentable>(
context: TemplatesContext,
validator: AnyValueValidator<E>? = nil
) -> DeserializationResult<T> where T == Expression<E>, E.RawValue == String {
let result = resolveValue(
context: context,
validator: validator
)
if case let .failure(errors) = result,
errors.count == 1,
case .noData = errors.first {
return .noValue
}
return result
}
@inlinable
func resolveOptionalValue<U: ValidSerializationValue, E>(
context: TemplatesContext,
transform: (U) -> E?,
validator: AnyValueValidator<E>? = nil
) -> DeserializationResult<T> where T == Expression<E> {
let result = resolveValue(
context: context,
transform: transform,
validator: validator
)
if case let .failure(errors) = result,
errors.count == 1,
case .noData = errors.first {
return .noValue
}
return result
}
@inlinable
func resolveOptionalValue<U: ValidSerializationValue, E>(
context: TemplatesContext,
transform: (U) -> E?,
validator: AnyArrayValueValidator<Expression<E>>
) -> DeserializationResult<T> where T == [Expression<E>] {
let result = resolveValue(
context: context,
transform: transform,
validator: validator
)
if case let .failure(errors) = result,
errors.count == 1,
case .noData = errors.first {
return .noValue
}
return result
}
}