From d17f8a01047446c2eec8502e456e34eeff9d72f9 Mon Sep 17 00:00:00 2001 From: ApolloZhu Date: Fri, 16 Aug 2019 17:24:17 +0800 Subject: [PATCH] Add migrator --- README.md | 17 +++++++++++++++++ Sources/EFStorageCore/EFStorage.swift | 23 +++++++++++++++++++++++ Tests/EFStorageTests/EFStorageTests.swift | 18 +++++++++++++++++- 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 42169a3..3e0b912 100644 --- a/README.md +++ b/README.md @@ -73,3 +73,20 @@ var isNewUser: Bool persistDefaultContent: true)) var hasPaidBefore: Bool ``` + +To migrate from another data type, you can use a migrator + +```swift +@EFStorageComposition( + EFStorageUserDefaults(forKey: "sameKey", + defaultsTo: "Nah"), + EFStorageMigrate( + from: EFStorageUserDefaults( + forKey: "sameKey", + defaultsTo: 1551, + persistDefaultContent: true), + by: { number in String(number) } + ) +) +var mixedType: String +``` diff --git a/Sources/EFStorageCore/EFStorage.swift b/Sources/EFStorageCore/EFStorage.swift index 9a83dff..2f07e20 100644 --- a/Sources/EFStorageCore/EFStorage.swift +++ b/Sources/EFStorageCore/EFStorage.swift @@ -64,3 +64,26 @@ public struct EFStorageComposition self.b = b } } + +/// Only for migration purposes. Setting the content/wrappedValue does nothing. +public struct EFStorageMigrate +: EFStorage where A.Content == OldContent { + public typealias Migrator = (OldContent) -> Content + + public var wrappedValue: Content { + get { return content ?? migrator(a.wrappedValue) } + set { } + } + + public var content: Content? { + get { return a.content.map(migrator) } + set { } + } + + private var a: A + private var migrator: Migrator + public init(from a: A, by migrator: @escaping Migrator) { + self.a = a + self.migrator = migrator + } +} diff --git a/Tests/EFStorageTests/EFStorageTests.swift b/Tests/EFStorageTests/EFStorageTests.swift index 09a3867..68cd388 100644 --- a/Tests/EFStorageTests/EFStorageTests.swift +++ b/Tests/EFStorageTests/EFStorageTests.swift @@ -43,6 +43,16 @@ final class EFStorageTests: XCTestCase { persistDefaultContent: true)) var hasPaidBefore: Bool + + @EFStorageComposition( + EFStorageUserDefaults(forKey: "sameKey", defaultsTo: "Nah"), + EFStorageMigrate(from: EFStorageUserDefaults(forKey: "sameKey", + defaultsTo: 1551, + persistDefaultContent: true), + by: { number in String(number) }) + ) + var mixedType: String + var storageText: EFStorageUserDefaultsRef = UserDefaults.efStorage.text func testExample() { @@ -51,13 +61,19 @@ final class EFStorageTests: XCTestCase { XCTAssertEqual(_text.wrappedValue, "meow") _text.removeContentFromUnderlyingStorage() XCTAssertEqual(text, EFStorageTests.defaultText) - // XCTAssertEqual(text, UserDefaults.efStorageContents.text) + XCTAssertEqual(text, UserDefaults.efStorage.text) XCTAssertEqual(storageText.content, text) let hasPaidBeforeRef: EFStorageUserDefaultsRef = UserDefaults.efStorage.oldHasPaidBeforeKey XCTAssertEqual(hasPaidBeforeRef.content, true) XCTAssertEqual(UserDefaults.standard.bool(forKey: "oldHasPaidBeforeKey"), true) debugPrint(efStorages) XCTAssertEqual(hasPaidBefore, true) + XCTAssertEqual(mixedType, "1551") + mixedType = "Brand New" + XCTAssertTrue(UserDefaults.standard.object(forKey: "sameKey") is String, "IS NOT STRING") + XCTAssertFalse(UserDefaults.standard.object(forKey: "sameKey") is Int, "IS NUMBER") + XCTAssertEqual(mixedType, "Brand New") + XCTAssertEqual(UserDefaults.efStorage.sameKey, "Brand New") } static var allTests = [