Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A not-quite-functional way to simplify string interpolation conformances.
struct _AppendingStringInterpolation<Result: ExpressibleByStringInterpolation> {
var result: Result
}
protocol ExpressibleByAppendingStringInterpolation: ExpressibleByStringInterpolation where StringInterpolation == _AppendingStringInterpolation<Self> {
init(stringLiteral: String)
mutating func append(_ value: Self)
}
extension ExpressibleByAppendingStringInterpolation where StringInterpolation == _AppendingStringInterpolation<Self> {
init(stringInterpolation value: _AppendingStringInterpolation<Self>) {
self = value.result
}
}
extension _AppendingStringInterpolation: StringInterpolationProtocol where Result: ExpressibleByAppendingStringInterpolation {
init(literalCapacity: Int, interpolationCount: Int) {
var string = ""
string.reserveCapacity(literalCapacity + interpolationCount * 2)
result = Result(stringLiteral: string)
}
mutating func appendLiteral(_ literal: Result.StringLiteralType) {
result.append(Result(stringLiteral: literal))
}
mutating func appendInterpolation(_ similar: Result) {
result.append(similar)
}
}
// *********************
typealias SQLValue = String // Stub
struct QueryPart {
var sql: String
var values: [SQLValue]
}
extension QueryPart: ExpressibleByAppendingStringInterpolation {
init(stringLiteral value: String) {
self.init(sql: value, values: [])
}
mutating func append(_ part: QueryPart) {
sql += part.sql
values += part.values
}
}
extension QueryPart.StringInterpolation {
mutating func appendInterpolation(raw: String) {
result.append(QueryPart(sql: raw, values: []))
}
mutating func appendInterpolation(param: SQLValue) {
let placeholder = "$\(result.values.count + 1)"
result.append(QueryPart(sql: placeholder, values: [param]))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment