Created
January 10, 2020 11:49
-
-
Save danielctull/fff429fbc04a1b8e7264b969f7f116ea to your computer and use it in GitHub Desktop.
Trying to created nested property wrappers in Swift by conforming the property wrappers themselves to StringProtocol.
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
@propertyWrapper | |
struct B { | |
var wrappedValue: Int | |
} | |
@propertyWrapper | |
struct Clamp { | |
var wrappedValue: Int | |
} | |
struct C { | |
@Uppercased @Lowercased var foo = "HeelOLllo" | |
} | |
//func g() { | |
// var c = C() | |
// c.foo = 3 | |
//} | |
@propertyWrapper | |
struct Lowercased<S: StringProtocol> { | |
private var text: S | |
var wrappedValue: S { | |
get { S(string: text.lowercased()) } | |
set { text = newValue } | |
} | |
init<AnyString: StringProtocol>(_ wrappedValue: AnyString) { | |
self.text = S(string: wrappedValue) | |
} | |
} | |
extension Lowercased: StringProtocol { | |
typealias UTF8View = S.UTF8View | |
typealias UTF16View = S.UTF16View | |
typealias UnicodeScalarView = S.UnicodeScalarView | |
var utf8: S.UTF8View { wrappedValue.utf8 } | |
var utf16: S.UTF16View { wrappedValue.utf16 } | |
var unicodeScalars: S.UnicodeScalarView { wrappedValue.unicodeScalars } | |
func lowercased() -> String { wrappedValue.lowercased() } | |
func uppercased() -> String { wrappedValue.uppercased() } | |
init(stringLiteral: String) { | |
self.init(S(string: stringLiteral)) | |
} | |
init<C, Encoding>(decoding codeUnits: C, as sourceEncoding: Encoding.Type) where C : Collection, Encoding : _UnicodeEncoding, C.Element == Encoding.CodeUnit { | |
self.init(String(decoding: codeUnits, as: sourceEncoding)) | |
} | |
init(cString nullTerminatedUTF8: UnsafePointer<CChar>) { | |
self.init(String(cString: nullTerminatedUTF8)) | |
} | |
init<Encoding>(decodingCString nullTerminatedCodeUnits: UnsafePointer<Encoding.CodeUnit>, as sourceEncoding: Encoding.Type) where Encoding : _UnicodeEncoding { | |
self.init(String(decodingCString: nullTerminatedCodeUnits, as: sourceEncoding)) | |
} | |
func withCString<Result>(_ body: (UnsafePointer<CChar>) throws -> Result) rethrows -> Result { try wrappedValue.withCString(body) } | |
func withCString<Result, Encoding>(encodedAs targetEncoding: Encoding.Type, _ body: (UnsafePointer<Encoding.CodeUnit>) throws -> Result) rethrows -> Result where Encoding : _UnicodeEncoding { | |
try wrappedValue.withCString(encodedAs: targetEncoding, body) | |
} | |
func index(before i: String.Index) -> String.Index { wrappedValue.index(before: i) } | |
func index(after i: String.Index) -> String.Index { wrappedValue.index(after: i) } | |
subscript(position: String.Index) -> Character { wrappedValue[position] } | |
var startIndex: String.Index { wrappedValue.startIndex } | |
var endIndex: String.Index { wrappedValue.endIndex } | |
var description: String { wrappedValue.description } | |
mutating func write(_ string: String) { text = S(string: string) } | |
func write<Target>(to target: inout Target) where Target : TextOutputStream { | |
wrappedValue.write(to: &target) | |
} | |
} | |
@propertyWrapper | |
struct Uppercased<S: StringProtocol> { | |
private var text: S | |
var wrappedValue: S { | |
get { S(string: text.uppercased()) } | |
set { text = newValue } | |
} | |
init<AnyString: StringProtocol>(_ wrappedValue: AnyString) { | |
self.text = S(string: wrappedValue) | |
} | |
} | |
extension Uppercased: StringProtocol { | |
typealias UTF8View = S.UTF8View | |
typealias UTF16View = S.UTF16View | |
typealias UnicodeScalarView = S.UnicodeScalarView | |
var utf8: S.UTF8View { wrappedValue.utf8 } | |
var utf16: S.UTF16View { wrappedValue.utf16 } | |
var unicodeScalars: S.UnicodeScalarView { wrappedValue.unicodeScalars } | |
func lowercased() -> String { wrappedValue.lowercased() } | |
func uppercased() -> String { wrappedValue.uppercased() } | |
init(stringLiteral: String) { | |
self.init(S(string: stringLiteral)) | |
} | |
init<C, Encoding>(decoding codeUnits: C, as sourceEncoding: Encoding.Type) where C : Collection, Encoding : _UnicodeEncoding, C.Element == Encoding.CodeUnit { | |
self.init(String(decoding: codeUnits, as: sourceEncoding)) | |
} | |
init(cString nullTerminatedUTF8: UnsafePointer<CChar>) { | |
self.init(String(cString: nullTerminatedUTF8)) | |
} | |
init<Encoding>(decodingCString nullTerminatedCodeUnits: UnsafePointer<Encoding.CodeUnit>, as sourceEncoding: Encoding.Type) where Encoding : _UnicodeEncoding { | |
self.init(String(decodingCString: nullTerminatedCodeUnits, as: sourceEncoding)) | |
} | |
func withCString<Result>(_ body: (UnsafePointer<CChar>) throws -> Result) rethrows -> Result { try wrappedValue.withCString(body) } | |
func withCString<Result, Encoding>(encodedAs targetEncoding: Encoding.Type, _ body: (UnsafePointer<Encoding.CodeUnit>) throws -> Result) rethrows -> Result where Encoding : _UnicodeEncoding { | |
try wrappedValue.withCString(encodedAs: targetEncoding, body) | |
} | |
func index(before i: String.Index) -> String.Index { wrappedValue.index(before: i) } | |
func index(after i: String.Index) -> String.Index { wrappedValue.index(after: i) } | |
subscript(position: String.Index) -> Character { wrappedValue[position] } | |
var startIndex: String.Index { wrappedValue.startIndex } | |
var endIndex: String.Index { wrappedValue.endIndex } | |
var description: String { wrappedValue.description } | |
mutating func write(_ string: String) { text = S(string: string) } | |
func write<Target>(to target: inout Target) where Target : TextOutputStream { | |
wrappedValue.write(to: &target) | |
} | |
} | |
extension StringProtocol { | |
init<AnyString: StringProtocol>(string: AnyString) { | |
var me = Self(stringLiteral: "") | |
string.withCString { me = Self.init(cString: $0) } | |
self = me | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment