aboutsummaryrefslogtreecommitdiff
path: root/Hotline/Library/NetSocket/FileProgress.swift
diff options
context:
space:
mode:
authorRuben Beltran del Rio <git@r.bdr.sh>2025-11-27 23:38:04 +0100
committerRuben Beltran del Rio <git@r.bdr.sh>2025-11-27 23:38:04 +0100
commit213710bf5bd6413c747bf126db50816ef5de5a6e (patch)
tree912f8cf87955a08077c92fea8ad934f50b7ab975 /Hotline/Library/NetSocket/FileProgress.swift
parentf466b21dc02f78c984ba6748e703f6780a7a0db4 (diff)
parent6a95b53616a4abfa306ddce43151cf4fefbd20ed (diff)
Merge remote-tracking branch 'upstream/main'
Diffstat (limited to 'Hotline/Library/NetSocket/FileProgress.swift')
-rw-r--r--Hotline/Library/NetSocket/FileProgress.swift71
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)
+ }
+ }
+ }
+}