Skip to content

Instantly share code, notes, and snippets.

@jamesujeon
Last active November 4, 2021 11:17
Show Gist options
  • Save jamesujeon/b13a9cb8d311fcdb5f768fb702529217 to your computer and use it in GitHub Desktop.
Save jamesujeon/b13a9cb8d311fcdb5f768fb702529217 to your computer and use it in GitHub Desktop.
Subscript `String` safely with `Optional`
import Foundation
extension String {
subscript(safe range: String.IndexDistance) -> Character? {
guard let index = index(at: range) else { return nil }
return self[index]
}
subscript(safe range: NSRange) -> Substring? {
guard let lowerBound = index(at: range.lowerBound),
let upperBound = index(at: range.upperBound)
else { return nil }
return self[lowerBound..<upperBound]
}
subscript(safe range: NSRange) -> String? {
guard let lowerBound = index(at: range.lowerBound),
let upperBound = index(at: range.upperBound)
else { return nil }
return String(self[lowerBound..<upperBound])
}
subscript(safe range: Range<String.IndexDistance>) -> Substring? {
guard let lowerBound = index(at: range.lowerBound),
let upperBound = index(at: range.upperBound)
else { return nil }
return self[lowerBound..<upperBound]
}
subscript(safe range: Range<String.IndexDistance>) -> String? {
guard let lowerBound = index(at: range.lowerBound),
let upperBound = index(at: range.upperBound)
else { return nil }
return String(self[lowerBound..<upperBound])
}
subscript(safe range: ClosedRange<String.IndexDistance>) -> Substring? {
guard let lowerBound = index(at: range.lowerBound),
let upperBound = index(at: range.upperBound)
else { return nil }
return self[lowerBound...upperBound]
}
subscript(safe range: ClosedRange<String.IndexDistance>) -> String? {
guard let lowerBound = index(at: range.lowerBound),
let upperBound = index(at: range.upperBound)
else { return nil }
return String(self[lowerBound...upperBound])
}
subscript(safe range: PartialRangeUpTo<String.IndexDistance>) -> Substring? {
guard let upperBound = index(at: range.upperBound) else { return nil }
return self[..<upperBound]
}
subscript(safe range: PartialRangeUpTo<String.IndexDistance>) -> String? {
guard let upperBound = index(at: range.upperBound) else { return nil }
return String(self[..<upperBound])
}
subscript(safe range: PartialRangeThrough<String.IndexDistance>) -> Substring? {
guard let upperBound = index(at: range.upperBound) else { return nil }
return self[...upperBound]
}
subscript(safe range: PartialRangeThrough<String.IndexDistance>) -> String? {
guard let upperBound = index(at: range.upperBound) else { return nil }
return String(self[...upperBound])
}
subscript(safe range: PartialRangeFrom<String.IndexDistance>) -> Substring? {
guard let lowerBound = index(at: range.lowerBound) else { return nil }
return self[lowerBound...]
}
subscript(safe range: PartialRangeFrom<String.IndexDistance>) -> String? {
guard let lowerBound = index(at: range.lowerBound) else { return nil }
return String(self[lowerBound...])
}
}
private extension String {
func index(at offset: String.IndexDistance) -> String.Index? {
index(startIndex, offsetBy: offset, limitedBy: endIndex)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment