Created
June 8, 2022 18:46
-
-
Save Shilo/e5ae91c75bf9f63233b550d3cf430a7d to your computer and use it in GitHub Desktop.
String additions to simplify handling.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// String+Additions.swift | |
// | |
// | |
// Created by Shilo White on 6/6/22. | |
// | |
import Foundation | |
extension String { | |
func indicesRange(range: NSRange) -> Range<String.Index>? { | |
return indicesRange(position: range.location, length: range.length) | |
} | |
func indicesRange(position: Int, length: Int) -> Range<String.Index>? { | |
guard | |
let start = index(startIndex, offsetBy: position, limitedBy: endIndex), | |
start < endIndex, | |
let end = index(start, offsetBy: length, limitedBy: endIndex), | |
end > start | |
else { return nil } | |
return start..<end | |
} | |
var leadingWhitespaceCount: Int { | |
var i = 0 | |
let count = self.count | |
while (i < count) | |
&& CharacterSet.whitespaces.hasMember(inPlane: UInt8(i)) { | |
i += 1 | |
} | |
return i | |
} | |
var trailingWhitespaceCount: Int { | |
var i = self.count - 1 | |
var count = 0 | |
//todo: fix crash "Fatal error: not enought bits to represent the passed value" | |
while (i >= 0) | |
&& CharacterSet.whitespaces.hasMember(inPlane: UInt8(i)) { | |
i -= 1 | |
count += 1 | |
} | |
return count | |
} | |
@inlinable public func offsetStartIndex(_ offsetBy: String.IndexDistance) -> String.Index { | |
return self.index(self.startIndex, offsetBy: offsetBy) | |
} | |
@inlinable public func offsetEndIndex(_ offsetBy: String.IndexDistance) -> String.Index { | |
return self.index(self.endIndex, offsetBy: offsetBy) | |
} | |
@inlinable public func suffix(fromOffset start: String.IndexDistance) -> Substring { | |
let index = self.offsetStartIndex(start) | |
return self.suffix(from: index) | |
} | |
@inlinable public func suffixStr(fromOffset start: String.IndexDistance) -> String { | |
return String(self.suffix(fromOffset: start)) | |
} | |
@inlinable public func prefixStr(_ maxLength: Int) -> String { | |
return String(self.prefix(maxLength)) | |
} | |
@discardableResult | |
public mutating func remove(atOffset start: String.IndexDistance) -> Character { | |
let index = self.offsetStartIndex(start) | |
return self.remove(at: index) | |
} | |
public mutating func insert<S>(contentsOf newElements: S, atOffset start: String.IndexDistance) where S : Collection, S.Element == Character { | |
let index = self.offsetStartIndex(start) | |
self.insert(contentsOf: newElements, at: index) | |
} | |
var fullRange: NSRange { | |
return NSRange(location: 0, length: count) | |
} | |
func substring(with range: NSRange) -> String? { | |
guard let range = Range(range) else { return nil } | |
return substring(fromOffset: range.lowerBound, toOffset: range.upperBound) | |
} | |
func substring(fromOffset from: String.IndexDistance, toOffset to: String.IndexDistance) -> String? { | |
let from = self.offsetStartIndex(from) | |
let to = self.offsetStartIndex(to) | |
return String(self[from..<to]) | |
} | |
public mutating func replaceSubrange<C>(_ range: NSRange, with newElements: C) where C : Collection, C.Element == Character { | |
guard let range = Range(range) else { return } | |
return replaceSubrange(fromOffset: range.lowerBound, toOffset: range.upperBound, with: newElements) | |
} | |
public mutating func replaceSubrange<C>(fromOffset from: String.IndexDistance, toOffset to: String.IndexDistance, with newElements: C) where C : Collection, C.Element == Character { | |
let from = self.offsetStartIndex(from) | |
let to = self.offsetStartIndex(to) | |
self.replaceSubrange(from..<to, with: newElements) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment