Skip to content

Commit f720f3b

Browse files
committed
Experimental property wrapper
1 parent ca6eb5f commit f720f3b

File tree

3 files changed

+149
-0
lines changed

3 files changed

+149
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Scheme
3+
LastUpgradeVersion = "1250"
4+
version = "1.3">
5+
<BuildAction
6+
parallelizeBuildables = "YES"
7+
buildImplicitDependencies = "YES">
8+
<BuildActionEntries>
9+
<BuildActionEntry
10+
buildForTesting = "YES"
11+
buildForRunning = "YES"
12+
buildForProfiling = "YES"
13+
buildForArchiving = "YES"
14+
buildForAnalyzing = "YES">
15+
<BuildableReference
16+
BuildableIdentifier = "primary"
17+
BlueprintIdentifier = "Coding"
18+
BuildableName = "Coding"
19+
BlueprintName = "Coding"
20+
ReferencedContainer = "container:">
21+
</BuildableReference>
22+
</BuildActionEntry>
23+
<BuildActionEntry
24+
buildForTesting = "YES"
25+
buildForRunning = "YES"
26+
buildForProfiling = "NO"
27+
buildForArchiving = "NO"
28+
buildForAnalyzing = "YES">
29+
<BuildableReference
30+
BuildableIdentifier = "primary"
31+
BlueprintIdentifier = "CodingTests"
32+
BuildableName = "CodingTests"
33+
BlueprintName = "CodingTests"
34+
ReferencedContainer = "container:">
35+
</BuildableReference>
36+
</BuildActionEntry>
37+
</BuildActionEntries>
38+
</BuildAction>
39+
<TestAction
40+
buildConfiguration = "Debug"
41+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
42+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
43+
shouldUseLaunchSchemeArgsEnv = "YES">
44+
<Testables>
45+
<TestableReference
46+
skipped = "NO">
47+
<BuildableReference
48+
BuildableIdentifier = "primary"
49+
BlueprintIdentifier = "CodingTests"
50+
BuildableName = "CodingTests"
51+
BlueprintName = "CodingTests"
52+
ReferencedContainer = "container:">
53+
</BuildableReference>
54+
</TestableReference>
55+
</Testables>
56+
</TestAction>
57+
<LaunchAction
58+
buildConfiguration = "Debug"
59+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
60+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
61+
launchStyle = "0"
62+
useCustomWorkingDirectory = "NO"
63+
ignoresPersistentStateOnLaunch = "NO"
64+
debugDocumentVersioning = "YES"
65+
debugServiceExtension = "internal"
66+
allowLocationSimulation = "YES">
67+
</LaunchAction>
68+
<ProfileAction
69+
buildConfiguration = "Release"
70+
shouldUseLaunchSchemeArgsEnv = "YES"
71+
savedToolIdentifier = ""
72+
useCustomWorkingDirectory = "NO"
73+
debugDocumentVersioning = "YES">
74+
<MacroExpansion>
75+
<BuildableReference
76+
BuildableIdentifier = "primary"
77+
BlueprintIdentifier = "Coding"
78+
BuildableName = "Coding"
79+
BlueprintName = "Coding"
80+
ReferencedContainer = "container:">
81+
</BuildableReference>
82+
</MacroExpansion>
83+
</ProfileAction>
84+
<AnalyzeAction
85+
buildConfiguration = "Debug">
86+
</AnalyzeAction>
87+
<ArchiveAction
88+
buildConfiguration = "Release"
89+
revealArchiveInOrganizer = "YES">
90+
</ArchiveAction>
91+
</Scheme>

Sources/Coding/Encoding.swift

+17
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,20 @@ public extension Encoding {
159159
}
160160
}
161161
}
162+
163+
// MARK: - Property Wrapper
164+
165+
@propertyWrapper
166+
public struct UsesEncoding<Value>: Encodable {
167+
public let wrappedValue: Value
168+
public let encoding: Encoding<Value>
169+
170+
public init(wrappedValue: Value, _ encoding: Encoding<Value>) {
171+
self.wrappedValue = wrappedValue
172+
self.encoding = encoding
173+
}
174+
175+
public func encode(to encoder: Encoder) throws {
176+
try encoding.encode(wrappedValue, encoder)
177+
}
178+
}

Tests/CodingTests/EncodingTests.swift

+41
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,35 @@ final class EncodingTests: XCTestCase {
534534
)
535535
}
536536

537+
// MARK: - Encoding Property Wrapper
538+
539+
func testEncodingPropertyWrapper() {
540+
struct User: Encodable {
541+
@UsesEncoding(.lowercased)
542+
var id: UUID = UUID()
543+
544+
@UsesEncoding(.lowercased)
545+
var name: String = ""
546+
}
547+
548+
encoder.outputFormatting = .prettyPrinted
549+
550+
let user = User(
551+
id: UUID(uuidString: "3B0B3AFC-4C61-4251-8FC5-F046D06DC3EC")!,
552+
name: "Joe Bloggs"
553+
)
554+
555+
XCTAssertEqual(
556+
"""
557+
{
558+
"id" : "3b0b3afc-4c61-4251-8fc5-f046d06dc3ec",
559+
"name" : "joe bloggs"
560+
}
561+
""",
562+
stringValue(try encoder.encode(user))
563+
)
564+
}
565+
537566
private func stringValue(_ data: Data) -> String {
538567
String(data: data, encoding: .utf8)!
539568
}
@@ -573,6 +602,18 @@ struct Manufacturer {
573602
}
574603
}
575604

605+
extension Encoding where Value == String {
606+
static let lowercased: Self = Encoding<String>
607+
.singleValue
608+
.pullback { $0.lowercased() }
609+
}
610+
611+
extension Encoding where Value == UUID {
612+
static let lowercased: Self = Encoding<String>
613+
.lowercased
614+
.pullback { $0.uuidString }
615+
}
616+
576617
extension Encoding where Value == Manufacturer {
577618
static let name: Self = Encoding<String>
578619
.withKey(Model.CodingKeys.name)

0 commit comments

Comments
 (0)