diff options
Diffstat (limited to 'Hotline/Library/NetSocket/FileProgress.swift')
| -rw-r--r-- | Hotline/Library/NetSocket/FileProgress.swift | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/Hotline/Library/NetSocket/FileProgress.swift b/Hotline/Library/NetSocket/FileProgress.swift new file mode 100644 index 0000000..2064c59 --- /dev/null +++ b/Hotline/Library/NetSocket/FileProgress.swift @@ -0,0 +1,71 @@ +// NetSocket FileProgress +// Dustin Mierau • @mierau +// MIT License + +import Foundation + +public extension NetSocket { + + /// Progress information for file uploads/downloads + struct FileProgress: Sendable { + /// Number of bytes sent/received so far + public let sent: Int + /// Total file size (may be nil if unknown) + public let total: Int? + /// Size of most recent packet + public let now: Int + /// Total progress so far (0.0 to 1.0) + public let progress: Double + /// Smoothed transfer rate in bytes per second (EMA), if enough samples collected + public let bytesPerSecond: Double? + /// Estimated time remaining (seconds) based on smoothed rate, if available + public let estimatedTimeRemaining: TimeInterval? + + public init(sent: Int, total: Int?, now: Int = 0, bytesPerSecond: Double? = nil, estimatedTimeRemaining: TimeInterval? = nil) { + self.sent = sent + self.total = total + self.now = now + + if let t = total { + self.progress = max(0.0, min(1.0, Double(sent) / Double(t))) + } + else { + self.progress = 0.0 + } + + self.bytesPerSecond = bytesPerSecond + self.estimatedTimeRemaining = estimatedTimeRemaining + } + + /// Format transfer speed in human-readable format + /// + /// Automatically selects appropriate unit (B/sec, KB/sec, MB/sec, GB/sec) + /// based on the magnitude of the speed. + /// + /// - Returns: Formatted string like "45KB/sec", "5B/sec", "12.5MB/sec", or nil if speed unavailable + /// + /// Example: + /// ```swift + /// if let speedString = progress.formattedSpeed { + /// print(speedString) // "2.5MB/sec" + /// } + /// ``` + public var formattedSpeed: String? { + guard let bytesPerSecond = bytesPerSecond, bytesPerSecond > 0 else { return nil } + + let kb = 1024.0 + let mb = kb * 1024.0 + let gb = mb * 1024.0 + + if bytesPerSecond >= gb { + return String(format: "%.1fGB/sec", bytesPerSecond / gb) + } else if bytesPerSecond >= mb { + return String(format: "%.1fMB/sec", bytesPerSecond / mb) + } else if bytesPerSecond >= kb { + return String(format: "%.0fKB/sec", bytesPerSecond / kb) + } else { + return String(format: "%.0fB/sec", bytesPerSecond) + } + } + } +} |