diff --git a/Sources/TwitchIRC/IncomingMessage/ClearMessage.swift b/Sources/TwitchIRC/IncomingMessage/ClearMessage.swift index 0c35529..97b0c29 100644 --- a/Sources/TwitchIRC/IncomingMessage/ClearMessage.swift +++ b/Sources/TwitchIRC/IncomingMessage/ClearMessage.swift @@ -28,8 +28,8 @@ public struct ClearMessage { self.channel = String(channel) /// `.unicodeScalars.dropFirst()` to remove ":", `componentsOneSplit(separatedBy: " :")` - /// normal methods like a simple `.dropFirst()` fail in rare cases. - /// Remove `.unicodeScalars` in `PrivateMessage`'s `message` and run tests to find out. + /// and other normal methods like a simple `.dropFirst()` fail in rare cases. + /// Remove `.unicodeScalars` of `PrivateMessage`'s `message` and run tests to find out. self.message = String(message.unicodeScalars.dropFirst()) guard contentLhs.count > 2, contentLhs.last == ":" else { diff --git a/Sources/TwitchIRC/IncomingMessage/PrivateMessage.swift b/Sources/TwitchIRC/IncomingMessage/PrivateMessage.swift index b45e673..10ce3d7 100644 --- a/Sources/TwitchIRC/IncomingMessage/PrivateMessage.swift +++ b/Sources/TwitchIRC/IncomingMessage/PrivateMessage.swift @@ -89,7 +89,7 @@ public struct PrivateMessage { } /// separating with " ", then lhs contains channel name and rhs is the actual message self.channel = channel /// `.unicodeScalars.dropFirst()` to remove ":", `componentsOneSplit(separatedBy: " :")` - /// normal methods like a simple `.dropFirst()` fail in rare cases. + /// and other normal methods like a simple `.dropFirst()` fail in rare cases. /// Remove `.unicodeScalars` and run tests to find out. self.message = String(message.unicodeScalars.dropFirst()) diff --git a/Sources/TwitchIRC/IncomingMessage/UserNotice.swift b/Sources/TwitchIRC/IncomingMessage/UserNotice.swift index 7b774bd..d03cd8e 100644 --- a/Sources/TwitchIRC/IncomingMessage/UserNotice.swift +++ b/Sources/TwitchIRC/IncomingMessage/UserNotice.swift @@ -175,8 +175,8 @@ public struct UserNotice { ) { self.channel = channel /// `.unicodeScalars.dropFirst()` to remove ":", `componentsOneSplit(separatedBy: " :")` - /// normal methods like a simple `.dropFirst()` fail in rare cases. - /// Remove `.unicodeScalars` in `PrivateMessage`'s `message` and run tests to find out. + /// and other normal methods like a simple `.dropFirst()` fail in rare cases. + /// Remove `.unicodeScalars` of `PrivateMessage`'s `message` and run tests to find out. self.message = String(message.unicodeScalars.dropFirst()) } else { self.channel = String(contentRhs.dropFirst()) diff --git a/Sources/TwitchIRC/IncomingMessage/Whisper.swift b/Sources/TwitchIRC/IncomingMessage/Whisper.swift index 9e12566..f0e8618 100644 --- a/Sources/TwitchIRC/IncomingMessage/Whisper.swift +++ b/Sources/TwitchIRC/IncomingMessage/Whisper.swift @@ -31,8 +31,8 @@ public struct Whisper { self.receiver = receiver /// `.unicodeScalars.dropFirst()` to remove ":", `componentsOneSplit(separatedBy: " :")` - /// normal methods like a simple `.dropFirst()` fail in rare cases. - /// Remove `.unicodeScalars` in `PrivateMessage`'s `message` and run tests to find out. + /// and other normal methods like a simple `.dropFirst()` fail in rare cases. + /// Remove `.unicodeScalars` of `PrivateMessage`'s `message` and run tests to find out. self.message = String(message.unicodeScalars.dropFirst()) var parser = ParametersParser(String(contentLhs.dropLast(2).dropFirst())) diff --git a/Sources/TwitchIRC/OutgoingMessage/1- OutgoingMessage.swift b/Sources/TwitchIRC/OutgoingMessage/1- OutgoingMessage.swift index 12dc3b0..7d090b0 100644 --- a/Sources/TwitchIRC/OutgoingMessage/1- OutgoingMessage.swift +++ b/Sources/TwitchIRC/OutgoingMessage/1- OutgoingMessage.swift @@ -18,6 +18,7 @@ public enum OutgoingMessage { /// Pong Twitch. case pong + /// Serializes this message into a string that can be sent to Twitch over IRC. public func serialize() -> String { switch self { case let .privateMessage(channel, message, msgIdToReply): diff --git a/Sources/TwitchIRC/Utils/String Extensions.swift b/Sources/TwitchIRC/Utils/String Extensions.swift index b41c1d2..9d0bbb0 100644 --- a/Sources/TwitchIRC/Utils/String Extensions.swift +++ b/Sources/TwitchIRC/Utils/String Extensions.swift @@ -1,68 +1,89 @@ -extension RangeReplaceableCollection where Element == Character { +extension RangeReplaceableCollection where Element == Character, Self.Index == String.Index { /// Separates the string by the given separator only with the first matching case. func components(separatedBy separator: String) -> [Self] { let separatorLength = separator.count guard separatorLength != 0 else { return [self] } - guard !(self.count < separatorLength) else { return [self] } + let selfLength = self.count + guard !(selfLength < separatorLength) else { return [self] } - let separatorChars = [Character](separator) + var endingIndices = ContiguousArray() - func oneSplit(_ string: [Character]) -> (lhs: Self, rhs: [Character])? { - guard !string.isEmpty else { return nil } - - let stringLength = string.count - let maxIdx = separatorLength - 1 - var lastIdx: Int? = nil - - for idx in 0.. [Self] { - if let (lhs, rhs) = oneSplit(string) { - return [lhs] + recursiveOneSplit(rhs) + let indicesLength = endingIndices.count + guard indicesLength != 0 else { return [self] } + let arrayLength = endingIndices.count + 1 + var array = Array() + array.reserveCapacity(arrayLength) + + for idx in 0..