forked from pointfreeco/sqlite-data
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDataManager.swift
More file actions
104 lines (94 loc) · 2.72 KB
/
DataManager.swift
File metadata and controls
104 lines (94 loc) · 2.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#if canImport(CloudKit) && canImport(CryptoKit)
import CryptoKit
import Dependencies
import Foundation
@available(macOS 13, iOS 16, tvOS 16, watchOS 9, *)
package protocol DataManager: Sendable {
func load(_ url: URL) throws -> Data
func save(_ data: Data, to url: URL) throws
func sha256(of fileURL: URL) -> Data?
var temporaryDirectory: URL { get }
}
@available(macOS 13, iOS 16, tvOS 16, watchOS 9, *)
struct LiveDataManager: DataManager {
func load(_ url: URL) throws -> Data {
try Data(contentsOf: url)
}
func save(_ data: Data, to url: URL) throws {
try data.write(to: url)
}
func sha256(of fileURL: URL) -> Data? {
do {
let fileHandle = try FileHandle(forReadingFrom: fileURL)
defer { try? fileHandle.close() }
var hasher = SHA256()
while true {
let finished = try autoreleasepool {
guard
let data = try fileHandle.read(upToCount: 1024 * 1024),
!data.isEmpty
else { return true }
hasher.update(data: data)
return false
}
guard !finished
else { break }
}
let digest = hasher.finalize()
return Data(digest)
} catch {
return nil
}
}
var temporaryDirectory: URL {
URL(fileURLWithPath: NSTemporaryDirectory())
}
}
@available(macOS 13, iOS 16, tvOS 16, watchOS 9, *)
package struct InMemoryDataManager: DataManager {
package let storage = LockIsolated<[URL: Data]>([:])
package init() {}
package func load(_ url: URL) throws -> Data {
try storage.withValue { storage in
guard let data = storage[url]
else {
struct FileNotFound: Error {}
throw FileNotFound()
}
return data
}
}
package func save(_ data: Data, to url: URL) throws {
storage.withValue { $0[url] = data }
}
package func sha256(of fileURL: URL) -> Data? {
storage.withValue {
$0[fileURL].map {
Data(SHA256.hash(data: $0))
}
}
}
package var temporaryDirectory: URL {
URL(fileURLWithPath: "/tmp")
}
}
@available(macOS 13, iOS 16, tvOS 16, watchOS 9, *)
private enum DataManagerKey: DependencyKey {
static var liveValue: any DataManager {
LiveDataManager()
}
static var previewValue: any DataManager {
InMemoryDataManager()
}
static var testValue: any DataManager {
InMemoryDataManager()
}
}
@available(macOS 13, iOS 16, tvOS 16, watchOS 9, *)
extension DependencyValues {
package var dataManager: DataManager {
get { self[DataManagerKey.self] }
set { self[DataManagerKey.self] = newValue }
}
}
#endif