-
Notifications
You must be signed in to change notification settings - Fork 384
/
Copy pathCustomListRepository.swift
87 lines (72 loc) · 2.36 KB
/
CustomListRepository.swift
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
//
// CustomListRepository.swift
// MullvadVPN
//
// Created by Mojgan on 2024-01-25.
// Copyright © 2024 Mullvad VPN AB. All rights reserved.
//
import Combine
import Foundation
import MullvadLogging
import MullvadTypes
public enum CustomRelayListError: LocalizedError, Equatable {
case duplicateName
public var errorDescription: String? {
switch self {
case .duplicateName:
NSLocalizedString(
"DUPLICATE_CUSTOM_LISTS_ERROR",
tableName: "CustomLists",
value: "Name is already taken.",
comment: ""
)
}
}
}
public struct CustomListRepository: CustomListRepositoryProtocol {
private let logger = Logger(label: "CustomListRepository")
private let settingsParser: SettingsParser = {
SettingsParser(decoder: JSONDecoder(), encoder: JSONEncoder())
}()
public init() {}
public func save(list: CustomList) throws {
var lists = fetchAll()
if let listWithSameName = lists.first(where: { $0.name.caseInsensitiveCompare(list.name) == .orderedSame }),
listWithSameName.id != list.id {
throw CustomRelayListError.duplicateName
} else if let index = lists.firstIndex(where: { $0.id == list.id }) {
lists[index] = list
try write(lists)
} else {
lists.append(list)
try write(lists)
}
}
public func delete(id: UUID) {
do {
var lists = fetchAll()
if let index = lists.firstIndex(where: { $0.id == id }) {
lists.remove(at: index)
try write(lists)
}
} catch {
logger.error(error: error)
}
}
public func fetch(by id: UUID) -> CustomList? {
try? read().first(where: { $0.id == id })
}
public func fetchAll() -> [CustomList] {
(try? read()) ?? []
}
}
extension CustomListRepository {
private func read() throws -> [CustomList] {
let data = try SettingsManager.store.read(key: .customRelayLists)
return try settingsParser.parseUnversionedPayload(as: [CustomList].self, from: data)
}
private func write(_ list: [CustomList]) throws {
let data = try settingsParser.produceUnversionedPayload(list)
try SettingsManager.store.write(data, for: .customRelayLists)
}
}