Files
2026-01-31 15:30:24 +08:00

81 lines
2.0 KiB
Swift

// Copyright (c) 2026 Timofey Solomko
// Licensed under MIT License
//
// See LICENSE for license information
struct SpeedFormatter {
static let `default`: SpeedFormatter = SpeedFormatter()
enum Units {
case bytes
case kB
case MB
case GB
case TB
init(_ speed: Double) {
if speed > 1_000_000_000_000 {
self = .TB
} else if speed > 1_000_000_000 {
self = .GB
} else if speed > 1_000_000 {
self = .MB
} else if speed > 1000 {
self = .kB
} else {
self = .bytes
}
}
fileprivate func unitsString() -> String {
switch self {
case .bytes:
return "B/s"
case .kB:
return "kB/s"
case .MB:
return "MB/s"
case .GB:
return "GB/s"
case .TB:
return "TB/s"
}
}
}
var units: Units?
var hideUnits: Bool
var fractionDigits: Int
init() {
self.units = nil
self.hideUnits = false
self.fractionDigits = 3
}
func string(from speed: Double, units: Units? = nil, hideUnits: Bool? = nil, fractionDigits: Int? = nil) -> String {
let actualUnits = units ?? self.units ?? Units(speed)
let speedInUnits: Double
switch actualUnits {
case .bytes:
speedInUnits = speed
case .kB:
speedInUnits = speed / 1000
case .MB:
speedInUnits = speed / 1_000_000
case .GB:
speedInUnits = speed / 1_000_000_000
case .TB:
speedInUnits = speed / 1_000_000_000_000
}
var formatString = "%.\(fractionDigits ?? self.fractionDigits)f"
if !(hideUnits ?? self.hideUnits) {
formatString += " " + actualUnits.unitsString()
}
return String(format: formatString, speedInUnits)
}
}