Rather than using ExpressibleByXXXLiteral
, you can just declare your own ...
operator that returns a String
.
This code from your second link makes ClosedRange<UnicodeScalar>
conform to Sequence
, which allows us to initialise a string from a ClosedRange<UnicodeScalar>
:
extension Unicode.Scalar: Strideable {
public func advanced(by n: Int) -> Unicode.Scalar {
let value = self.value.advanced(by: n)
guard let scalar = Unicode.Scalar(value) else {
fatalError("Invalid Unicode.Scalar value:" + String(value, radix: 16))
}
return scalar
}
public func distance(to other: Unicode.Scalar) -> Int {
return Int(other.value - value)
}
}
extension String {
init<S: Sequence>(_ sequence: S) where S.Element == Unicode.Scalar {
self.init(UnicodeScalarView(sequence))
}
}
extension Sequence where Element == Unicode.Scalar {
var string: String { return String(self) }
}
Using that, our string-producing ...
operator is simple to define:
func ...(lhs: UnicodeScalar, rhs: UnicodeScalar) -> String {
// note that this is not recursive
// this calls the "..." that produces a closed range
(lhs...rhs).string
}
Usage:
let alphabet = "a"..."z"
print(alphabet)