Mac-utlity-app / MUA / Models / DiskInfo.swift Blame
6dacfa4 Mitchel Jan 17, 2026
//
//  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 == "/" }
    }
}