func applyRxVariableTemplate()

in Sources/MockoloFramework/Templates/VariableTemplate.swift [220:332]


    func applyRxVariableTemplate(name: String,
                                 type: SwiftType,
                                 encloser: String,
                                 rxTypes: [String: String]?,
                                 shouldOverride: Bool,
                                 allowSetCallCount: Bool,
                                 isStatic: Bool,
                                 accessLevel: String) -> String? {

        let staticSpace = isStatic ? "\(String.static) " : ""
        let privateSetSpace = allowSetCallCount ? "" : "\(String.privateSet) "

        if let rxTypes = rxTypes, !rxTypes.isEmpty {
            let (subjectType, _, subjectVal) = type.parseRxVar(overrides: rxTypes, overrideKey: name, isInitParam: true)
            if let underlyingSubjectType = subjectType {

                let underlyingSubjectName = "\(name)\(String.subjectSuffix)"
                let underlyingSetCallCount = "\(underlyingSubjectName)\(String.setCallCountSuffix)"

                var defaultValAssignStr = ""
                if let underlyingSubjectTypeDefaultVal = subjectVal {
                    defaultValAssignStr = " = \(underlyingSubjectTypeDefaultVal)"
                } else {
                    defaultValAssignStr = ": \(underlyingSubjectType)!"
                }

                let acl = accessLevel.isEmpty ? "" : accessLevel + " "
                let overrideStr = shouldOverride ? "\(String.override) " : ""


                let setCallCountStmt = "\(underlyingSetCallCount) += 1"
                let fallbackName =  "\(String.underlyingVarPrefix)\(name)"
                var fallbackType = type.typeName
                if type.isIUO || type.isOptional {
                    fallbackType.removeLast()
                }

                let template = """

                \(1.tab)\(acl)\(staticSpace)\(privateSetSpace)var \(underlyingSetCallCount) = 0
                \(1.tab)\(staticSpace)var \(fallbackName): \(fallbackType)? { didSet { \(setCallCountStmt) } }
                \(1.tab)\(acl)\(staticSpace)var \(underlyingSubjectName)\(defaultValAssignStr) { didSet { \(setCallCountStmt) } }
                \(1.tab)\(acl)\(staticSpace)\(overrideStr)var \(name): \(type.typeName) {
                \(2.tab)get { return \(fallbackName) ?? \(underlyingSubjectName) }
                \(2.tab)set { if let val = newValue as? \(underlyingSubjectType) { \(underlyingSubjectName) = val } else { \(fallbackName) = newValue } }
                \(1.tab)}
                """

                return template
            }
        }

        let typeName = type.typeName
        if let range = typeName.range(of: String.observableLeftAngleBracket), let lastIdx = typeName.lastIndex(of: ">") {
            let typeParamStr = typeName[range.upperBound..<lastIdx]

            let underlyingSubjectName = "\(name)\(String.subjectSuffix)"
            let underlyingSetCallCount = "\(underlyingSubjectName)\(String.setCallCountSuffix)"
            let publishSubjectName = underlyingSubjectName
            let publishSubjectType = "\(String.publishSubject)<\(typeParamStr)>"
            let behaviorSubjectName = "\(name)\(String.behaviorSubject)"
            let behaviorSubjectType = "\(String.behaviorSubject)<\(typeParamStr)>"
            let replaySubjectName = "\(name)\(String.replaySubject)"
            let replaySubjectType = "\(String.replaySubject)<\(typeParamStr)>"

            let acl = accessLevel.isEmpty ? "" : accessLevel + " "
            let overrideStr = shouldOverride ? "\(String.override) " : ""

            let whichSubject = "\(underlyingSubjectName)Kind"
            let fallbackName = "_\(name)"
            let fallbackType = typeName[typeName.startIndex..<typeName.index(after: lastIdx)]
            let setCallCountStmt = "\(underlyingSetCallCount) += 1"

            let template = """
            \(1.tab)\(staticSpace)private var \(whichSubject) = 0
            \(1.tab)\(acl)\(staticSpace)\(privateSetSpace)var \(underlyingSetCallCount) = 0
            \(1.tab)\(acl)\(staticSpace)var \(publishSubjectName) = \(publishSubjectType)() { didSet { \(setCallCountStmt) } }
            \(1.tab)\(acl)\(staticSpace)var \(replaySubjectName) = \(replaySubjectType).create(bufferSize: 1) { didSet { \(setCallCountStmt) } }
            \(1.tab)\(acl)\(staticSpace)var \(behaviorSubjectName): \(behaviorSubjectType)! { didSet { \(setCallCountStmt) } }
            \(1.tab)\(acl)\(staticSpace)var \(fallbackName): \(fallbackType)! { didSet { \(setCallCountStmt) } }
            \(1.tab)\(acl)\(staticSpace)\(overrideStr)var \(name): \(typeName) {
            \(2.tab)get {
            \(3.tab)if \(whichSubject) == 0 {
            \(4.tab)return \(publishSubjectName)
            \(3.tab)} else if \(whichSubject) == 1 {
            \(4.tab)return \(behaviorSubjectName)
            \(3.tab)} else if \(whichSubject) == 2 {
            \(4.tab)return \(replaySubjectName)
            \(3.tab)} else {
            \(4.tab)return \(fallbackName)
            \(3.tab)}
            \(2.tab)}
            \(2.tab)set {
            \(3.tab)if let val = newValue as? \(publishSubjectType) {
            \(4.tab)\(publishSubjectName) = val
            \(4.tab)\(whichSubject) = 0
            \(3.tab)} else if let val = newValue as? \(behaviorSubjectType) {
            \(4.tab)\(behaviorSubjectName) = val
            \(4.tab)\(whichSubject) = 1
            \(3.tab)} else if let val = newValue as? \(replaySubjectType) {
            \(4.tab)\(replaySubjectName) = val
            \(4.tab)\(whichSubject) = 2
            \(3.tab)} else {
            \(4.tab)\(fallbackName) = newValue
            \(4.tab)\(whichSubject) = 3
            \(3.tab)}
            \(2.tab)}
            \(1.tab)}
            """
            return template
        }
        return nil
    }