func applyCombineVariableTemplate()

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
        }
    }