Skip to content

Instantly share code, notes, and snippets.

@dpmedeiros
Last active February 12, 2020 19:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dpmedeiros/59bc41ad1b8b7749ab260e100a4e3934 to your computer and use it in GitHub Desktop.
Save dpmedeiros/59bc41ad1b8b7749ab260e100a4e3934 to your computer and use it in GitHub Desktop.
A Kotlin class that embodies data rate. Provides methods to convert data rates from one unit to another as well as to a smallest value rounded data rate.
/**
* Units of speed
*/
enum class SpeedUnits {
BITS_PER_SEC { override fun toString(): String = "Bits/s" },
BYTES_PER_SEC { override fun toString(): String = "Bytes/s" },
KBITS_PER_SEC { override fun toString(): String = "KBits/s" },
MBITS_PER_SEC { override fun toString(): String = "MBits/s" }
}
/**
* Represents an arbitrary speed, e.g. 50 MBits/s
* @param value the speed value
* @param unit the unit measure of the speed value
*/
data class Speed(val value: Int, val unit: SpeedUnits) {
/**
* Convert arbitrary speed to (possibly fractional) Mbps
*/
fun asMbps(): Double {
return when (unit) {
SpeedUnits.BITS_PER_SEC -> value.toDouble() / BITS_IN_A_MBIT
SpeedUnits.BYTES_PER_SEC -> Speed(value * BITS_IN_A_BYTE, SpeedUnits.BITS_PER_SEC).asMbps()
SpeedUnits.KBITS_PER_SEC -> Speed(value * BITS_IN_A_KBIT, SpeedUnits.BITS_PER_SEC).asMbps()
SpeedUnits.MBITS_PER_SEC -> value.toDouble()
}
}
/**
* Convert arbitrary speed to bits/s
*/
fun asBitsPerSec(): Int {
return when (unit) {
SpeedUnits.BITS_PER_SEC -> value
SpeedUnits.BYTES_PER_SEC -> value * BITS_IN_A_BYTE
SpeedUnits.KBITS_PER_SEC -> value * BITS_IN_A_KBIT
SpeedUnits.MBITS_PER_SEC -> value * BITS_IN_A_MBIT
}
}
/**
* Convert arbitrary speed to (possibly fractional) bytes/s
*/
fun asBytesPerSec(): Double {
return when (unit) {
SpeedUnits.BITS_PER_SEC -> value.toDouble() / BITS_IN_A_BYTE
SpeedUnits.BYTES_PER_SEC -> value.toDouble()
SpeedUnits.KBITS_PER_SEC -> Speed(value * BITS_IN_A_KBIT, SpeedUnits.BITS_PER_SEC).asBytesPerSec()
SpeedUnits.MBITS_PER_SEC -> Speed(value * BITS_IN_A_MBIT, SpeedUnits.BITS_PER_SEC).asBytesPerSec()
}
}
/**
* Gets a smallest value round speed to display to a user
*
* Examples:
* 1000 bytes/s -> 8 KBits/s
* 10000 bytes/s -> 80 MBits/s
*/
fun toDisplayableSpeed(): Speed {
val bitsPerSec = asBitsPerSec()
return when {
bitsPerSec < BITS_IN_A_KBIT -> Speed(
bitsPerSec,
SpeedUnits.BITS_PER_SEC
)
bitsPerSec < BITS_IN_A_MBIT -> Speed(
bitsPerSec / BITS_IN_A_KBIT,
SpeedUnits.KBITS_PER_SEC
)
else -> Speed(
bitsPerSec / BITS_IN_A_MBIT,
SpeedUnits.MBITS_PER_SEC
)
}
}
override fun toString(): String = "$value $unit"
companion object {
private const val BITS_IN_A_BYTE = 8
private const val BITS_IN_A_KBIT = 1000
private const val BITS_IN_A_MBIT = BITS_IN_A_KBIT * 1000
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment