Skip to content

Commit d17f8a0

Browse files
committed
Add migrator
1 parent 06c0c96 commit d17f8a0

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,20 @@ var isNewUser: Bool
7373
persistDefaultContent: true))
7474
var hasPaidBefore: Bool
7575
```
76+
77+
To migrate from another data type, you can use a migrator
78+
79+
```swift
80+
@EFStorageComposition(
81+
EFStorageUserDefaults<String>(forKey: "sameKey",
82+
defaultsTo: "Nah"),
83+
EFStorageMigrate(
84+
from: EFStorageUserDefaults<Int>(
85+
forKey: "sameKey",
86+
defaultsTo: 1551,
87+
persistDefaultContent: true),
88+
by: { number in String(number) }
89+
)
90+
)
91+
var mixedType: String
92+
```

Sources/EFStorageCore/EFStorage.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,26 @@ public struct EFStorageComposition<A: EFStorage, B: EFStorage, Content>
6464
self.b = b
6565
}
6666
}
67+
68+
/// Only for migration purposes. Setting the content/wrappedValue does nothing.
69+
public struct EFStorageMigrate<A: EFStorage, OldContent, Content>
70+
: EFStorage where A.Content == OldContent {
71+
public typealias Migrator = (OldContent) -> Content
72+
73+
public var wrappedValue: Content {
74+
get { return content ?? migrator(a.wrappedValue) }
75+
set { }
76+
}
77+
78+
public var content: Content? {
79+
get { return a.content.map(migrator) }
80+
set { }
81+
}
82+
83+
private var a: A
84+
private var migrator: Migrator
85+
public init(from a: A, by migrator: @escaping Migrator) {
86+
self.a = a
87+
self.migrator = migrator
88+
}
89+
}

Tests/EFStorageTests/EFStorageTests.swift

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ final class EFStorageTests: XCTestCase {
4343
persistDefaultContent: true))
4444
var hasPaidBefore: Bool
4545

46+
47+
@EFStorageComposition(
48+
EFStorageUserDefaults<String>(forKey: "sameKey", defaultsTo: "Nah"),
49+
EFStorageMigrate(from: EFStorageUserDefaults<Int>(forKey: "sameKey",
50+
defaultsTo: 1551,
51+
persistDefaultContent: true),
52+
by: { number in String(number) })
53+
)
54+
var mixedType: String
55+
4656
var storageText: EFStorageUserDefaultsRef<String> = UserDefaults.efStorage.text
4757

4858
func testExample() {
@@ -51,13 +61,19 @@ final class EFStorageTests: XCTestCase {
5161
XCTAssertEqual(_text.wrappedValue, "meow")
5262
_text.removeContentFromUnderlyingStorage()
5363
XCTAssertEqual(text, EFStorageTests.defaultText)
54-
// XCTAssertEqual(text, UserDefaults.efStorageContents.text)
64+
XCTAssertEqual(text, UserDefaults.efStorage.text)
5565
XCTAssertEqual(storageText.content, text)
5666
let hasPaidBeforeRef: EFStorageUserDefaultsRef<Bool> = UserDefaults.efStorage.oldHasPaidBeforeKey
5767
XCTAssertEqual(hasPaidBeforeRef.content, true)
5868
XCTAssertEqual(UserDefaults.standard.bool(forKey: "oldHasPaidBeforeKey"), true)
5969
debugPrint(efStorages)
6070
XCTAssertEqual(hasPaidBefore, true)
71+
XCTAssertEqual(mixedType, "1551")
72+
mixedType = "Brand New"
73+
XCTAssertTrue(UserDefaults.standard.object(forKey: "sameKey") is String, "IS NOT STRING")
74+
XCTAssertFalse(UserDefaults.standard.object(forKey: "sameKey") is Int, "IS NUMBER")
75+
XCTAssertEqual(mixedType, "Brand New")
76+
XCTAssertEqual(UserDefaults.efStorage.sameKey, "Brand New")
6177
}
6278

6379
static var allTests = [

0 commit comments

Comments
 (0)