// // DiskInfo.swift // MUA // // Created by Mitchel Volkering on 21/12/2025. // import Foundation /// Information about a disk/volume struct DiskInfo: Identifiable { let id = UUID() let name: String let mountPoint: URL let totalSpace: Int64 let freeSpace: Int64 let isRemovable: Bool let isInternal: Bool var usedSpace: Int64 { totalSpace - freeSpace } var usedPercentage: Double { guard totalSpace > 0 else { return 0 } return (Double(usedSpace) / Double(totalSpace)) * 100 } var formattedTotalSpace: String { ByteCountFormatter.string(fromByteCount: totalSpace, countStyle: .file) } var formattedFreeSpace: String { ByteCountFormatter.string(fromByteCount: freeSpace, countStyle: .file) } var formattedUsedSpace: String { ByteCountFormatter.string(fromByteCount: usedSpace, countStyle: .file) } var icon: String { if isRemovable { return "externaldrive.fill" } return isInternal ? "internaldrive.fill" : "externaldrive.fill" } /// Get disk info for all mounted volumes static func getAllDisks() -> [DiskInfo] { var disks: [DiskInfo] = [] let fileManager = FileManager.default let keys: [URLResourceKey] = [ .volumeNameKey, .volumeTotalCapacityKey, .volumeAvailableCapacityKey, .volumeIsRemovableKey, .volumeIsInternalKey ] guard let volumes = fileManager.mountedVolumeURLs(includingResourceValuesForKeys: keys, options: [.skipHiddenVolumes]) else { return disks } for volume in volumes { do { let resourceValues = try volume.resourceValues(forKeys: Set(keys)) let name = resourceValues.volumeName ?? volume.lastPathComponent let total = Int64(resourceValues.volumeTotalCapacity ?? 0) let free = Int64(resourceValues.volumeAvailableCapacity ?? 0) let isRemovable = resourceValues.volumeIsRemovable ?? false let isInternal = resourceValues.volumeIsInternal ?? true let disk = DiskInfo( name: name, mountPoint: volume, totalSpace: total, freeSpace: free, isRemovable: isRemovable, isInternal: isInternal ) disks.append(disk) } catch { continue } } return disks } /// Get the main system disk static func getSystemDisk() -> DiskInfo? { getAllDisks().first { $0.mountPoint.path == "/" } } }