in Sources/MockoloFramework/Templates/VariableTemplate.swift [134:218]
func applyCombineVariableTemplate(name: String,
type: SwiftType,
encloser: String,
shouldOverride: Bool,
isStatic: Bool,
accessLevel: String) -> String? {
let typeName = type.typeName
guard
typeName.starts(with: String.anyPublisherLeftAngleBracket),
let range = typeName.range(of: String.anyPublisherLeftAngleBracket),
let lastIdx = typeName.lastIndex(of: ">")
else {
return nil
}
let typeParamStr = typeName[range.upperBound..<lastIdx]
var subjectTypeStr = ""
var errorTypeStr = ""
if let lastCommaIndex = typeParamStr.lastIndex(of: ",") {
subjectTypeStr = String(typeParamStr[..<lastCommaIndex])
let nextIndex = typeParamStr.index(after: lastCommaIndex)
errorTypeStr = String(typeParamStr[nextIndex..<typeParamStr.endIndex]).trimmingCharacters(in: .whitespaces)
}
let subjectType = SwiftType(subjectTypeStr)
let subjectDefaultValue = subjectType.defaultVal()
let staticSpace = isStatic ? "\(String.static) " : ""
let acl = accessLevel.isEmpty ? "" : accessLevel + " "
let thisStr = isStatic ? encloser : "self"
let overrideStr = shouldOverride ? "\(String.override) " : ""
switch combineType {
case .property(_, var wrapperPropertyName):
// Using a property wrapper to back this publisher, such as @Published
var template = "\n"
var isWrapperPropertyOptionalOrForceUnwrapped = false
if let publishedAliasModel = wrapperAliasModel, let type = publishedAliasModel.type {
// If the property required by the protocol/class cannot be optional, the wrapper property will be the underlyingProperty
// i.e. @Published var _myType: MyType!
let wrapperPropertyDefaultValue = type.defaultVal()
if wrapperPropertyDefaultValue == nil {
wrapperPropertyName = "_\(wrapperPropertyName)"
}
isWrapperPropertyOptionalOrForceUnwrapped = wrapperPropertyDefaultValue == nil || type.isOptional
}
var mapping = ""
if !subjectType.isOptional, isWrapperPropertyOptionalOrForceUnwrapped {
// If the wrapper property is of type: MyType?/MyType!, but the publisher is of type MyType
mapping = ".map { $0! }"
} else if subjectType.isOptional, !isWrapperPropertyOptionalOrForceUnwrapped {
// If the wrapper property is of type: MyType, but the publisher is of type MyType?
mapping = ".map { $0 }"
}
let setErrorType = ".setFailureType(to: \(errorTypeStr).self)"
template += """
\(1.tab)\(acl)\(staticSpace)\(overrideStr)var \(name): \(typeName) { return \(thisStr).$\(wrapperPropertyName)\(mapping)\(setErrorType).\(String.eraseToAnyPublisher)() }
"""
return template
default:
// Using a combine subject to back this publisher
var combineSubjectType = combineType ?? .passthroughSubject
var defaultValue: String? = ""
if case .currentValueSubject = combineSubjectType {
defaultValue = subjectDefaultValue
}
// Unable to generate default value for this CurrentValueSubject. Default back to PassthroughSubject.
//
if defaultValue == nil {
combineSubjectType = .passthroughSubject
}
let underlyingSubjectName = "\(name)\(String.subjectSuffix)"
let template = """
\(1.tab)\(acl)\(staticSpace)\(overrideStr)var \(name): \(typeName) { return \(thisStr).\(underlyingSubjectName).\(String.eraseToAnyPublisher)() }
\(1.tab)\(acl)\(staticSpace)\(String.privateSet) var \(underlyingSubjectName) = \(combineSubjectType.typeName)<\(typeParamStr)>(\(defaultValue ?? ""))
"""
return template
}
}