This repository has been archived by the owner on May 12, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
AttachInfo.swift
45 lines (41 loc) · 1.51 KB
/
AttachInfo.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
import Foundation
/**
Decode the property list resulting from `hdiutil attach` and extract the primary mountable volume.
*/
struct AttachInfo: Decodable {
let device: String
let type: String
let mounted: Bool
private enum AttachKeys: String, CodingKey {
case systemEntities = "system-entities"
}
private enum EntityKeys: String, CodingKey {
case device = "dev-entry"
case mountable = "potentially-mountable"
case volumeType = "volume-kind"
case mountPoint = "mount-point"
}
init(from data: Data) throws {
let decoder = PropertyListDecoder()
self = try decoder.decode(AttachInfo.self, from: data)
}
init(from decoder: Decoder) throws {
let allowedVolumeTypes = ["apfs", "hfs"]
var entities = try decoder
.container(keyedBy: AttachKeys.self)
.nestedUnkeyedContainer(forKey: .systemEntities)
while !entities.isAtEnd {
let entity = try entities.nestedContainer(keyedBy: EntityKeys.self)
let mountable = try entity.decodeIfPresent(Bool.self, forKey: .mountable) ?? false
let volumeType = try entity.decodeIfPresent(String.self, forKey: .volumeType) ?? ""
if mountable && allowedVolumeTypes.contains(volumeType) {
device = try entity.decode(String.self, forKey: .device)
type = volumeType
mounted = (try entity.decodeIfPresent(String.self, forKey: .mountPoint)) != nil
return
}
}
let context = DecodingError.Context(codingPath: [AttachKeys.systemEntities], debugDescription: "no matching mountable volume found")
throw DecodingError.keyNotFound(EntityKeys.device, context)
}
}