-
Notifications
You must be signed in to change notification settings - Fork 392
/
Copy pathCustomListLocationNodeBuilder.swift
78 lines (67 loc) · 2.26 KB
/
CustomListLocationNodeBuilder.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
//
// CustomListLocationNodeBuilder.swift
// MullvadVPN
//
// Created by Mojgan on 2024-03-14.
// Copyright © 2024 Mullvad VPN AB. All rights reserved.
//
import Foundation
import MullvadSettings
import MullvadTypes
struct CustomListLocationNodeBuilder {
let customList: CustomList
let allLocations: [LocationNode]
var customListLocationNode: CustomListLocationNode {
let listNode = CustomListLocationNode(
name: customList.name,
code: customList.name.lowercased(),
locations: customList.locations,
isActive: !customList.locations.isEmpty,
customList: customList
)
listNode.children = listNode.locations.compactMap { location in
let rootNode = RootLocationNode(children: allLocations)
return switch location {
case let .country(countryCode):
rootNode
.countryFor(code: countryCode)?
.copy(withParent: listNode)
case let .city(countryCode, cityCode):
rootNode
.countryFor(code: countryCode)?
.cityFor(codes: [countryCode, cityCode])?
.copy(withParent: listNode)
case let .hostname(countryCode, cityCode, hostCode):
rootNode
.countryFor(code: countryCode)?
.cityFor(codes: [countryCode, cityCode])?
.hostFor(code: hostCode)?
.copy(withParent: listNode)
}
}
listNode.sort()
return listNode
}
}
private extension CustomListLocationNode {
func sort() {
let sortedChildren = Dictionary(grouping: children, by: {
return switch RelayLocation(dashSeparatedString: $0.code)! {
case .country:
LocationGroup.country
case .city:
LocationGroup.city
case .hostname:
LocationGroup.host
}
})
.sorted(by: { $0.key < $1.key })
.reduce([]) {
return $0 + $1.value.sorted(by: { $0.name < $1.name })
}
children = sortedChildren
}
}
private enum LocationGroup: CaseIterable, Comparable {
case country, city, host
}