func channelRead()

in NIOSMTP/NIOSMTP/SendEmailHandler.swift [111:180]


    func channelRead(context: ChannelHandlerContext, data: NIOAny) {
        let result = self.unwrapInboundIn(data)
        switch result {
        case .error(let message):
            self.allDonePromise.fail(NSError(domain: "sending email", code: 1, userInfo: ["reason": message]))
            return
        case .ok:
            () // cool
        }

        switch self.currentlyWaitingFor {
        case .initialMessageFromServer:
            self.send(context: context, command: .sayHello(serverName: self.serverConfiguration.hostname))
            self.currentlyWaitingFor = .okForOurHello
        case .okForOurHello:
            if self.useStartTLS {
                self.send(context: context, command: .startTLS)
                self.currentlyWaitingFor = .okForStartTLS
            } else {
                self.sendAuthenticationStart(context: context)
            }
        case .okForStartTLS:
            self.currentlyWaitingFor = .tlsHandlerToBeAdded
            context.channel.pipeline.addHandler(try! NIOSSLClientHandler(context: sslContext,
                                                                         serverHostname: serverConfiguration.hostname),
                                                position: .first).whenComplete { result in
                guard case .tlsHandlerToBeAdded = self.currentlyWaitingFor else {
                    preconditionFailure("wrong state \(self.currentlyWaitingFor)")
                }

                switch result {
                case .failure(let error):
                    self.currentlyWaitingFor = .error(error)
                case .success:
                    self.sendAuthenticationStart(context: context)
                }
            }
        case .okForOurAuthBegin:
            self.send(context: context, command: .authUser(self.serverConfiguration.username))
            self.currentlyWaitingFor = .okAfterUsername
        case .okAfterUsername:
            self.send(context: context, command: .authPassword(self.serverConfiguration.password))
            self.currentlyWaitingFor = .okAfterPassword
        case .okAfterPassword:
            self.send(context: context, command: .mailFrom(self.email.senderEmail))
            self.currentlyWaitingFor = .okAfterMailFrom
        case .okAfterMailFrom:
            self.send(context: context, command: .recipient(self.email.recipientEmail))
            self.currentlyWaitingFor = .okAfterRecipient
        case .okAfterRecipient:
            self.send(context: context, command: .data)
            self.currentlyWaitingFor = .okAfterDataCommand
        case .okAfterDataCommand:
            self.send(context: context, command: .transferData(email))
            self.currentlyWaitingFor = .okAfterMailData
        case .okAfterMailData:
            self.send(context: context, command: .quit)
            self.currentlyWaitingFor = .okAfterQuit
        case .okAfterQuit:
            self.allDonePromise.succeed(())
            context.close(promise: nil)
            self.currentlyWaitingFor = .nothing
        case .nothing:
            () // ignoring more data whilst quit (it's odd though)
        case .error:
            fatalError("error state")
        case .tlsHandlerToBeAdded:
            fatalError("bug in NIOTS: we shouldn't hit this state here")
        }
    }