Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion library/api/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ package me.saket.bytesize {
method @kotlin.jvm.JvmSynthetic public static inline operator long times(Number, long other);
}

@kotlin.jvm.JvmInline public final value class Bitrate {
ctor public Bitrate(@kotlin.PublishedApi me.saket.bytesize.ByteSize bytesPerSecond);
method public inline operator int compareTo(me.saket.bytesize.ByteSize other);
method public inline operator me.saket.bytesize.ByteSize div(double divisor);
method public inline operator me.saket.bytesize.ByteSize minus(me.saket.bytesize.ByteSize other);
method public inline operator me.saket.bytesize.ByteSize plus(me.saket.bytesize.ByteSize other);
method public inline operator me.saket.bytesize.ByteSize times(double multiplier);
method public inline String toString();
}

public final class BitrateKt {
method @kotlin.jvm.JvmSynthetic public static inline operator me.saket.bytesize.ByteSize div(me.saket.bytesize.ByteSize, long duration);
method @kotlin.jvm.JvmSynthetic public static inline operator me.saket.bytesize.ByteSize times(long, me.saket.bytesize.ByteSize bitrate);
method @kotlin.jvm.JvmSynthetic public static inline operator me.saket.bytesize.ByteSize times(me.saket.bytesize.ByteSize, long duration);
}

public sealed interface ByteSize {
method public operator me.saket.bytesize.ByteSize div(Number other);
method public operator double div(me.saket.bytesize.ByteSize other);
Expand All @@ -44,7 +60,7 @@ package me.saket.bytesize {

@kotlin.jvm.JvmInline public final value class DecimalBitSize implements me.saket.bytesize.ByteSize {
ctor public DecimalBitSize(Number bits);
ctor public DecimalBitSize(@kotlin.PublishedApi inline long bits);
ctor public DecimalBitSize(@kotlin.PublishedApi long bits);
method public inline int compareTo(me.saket.bytesize.ByteSize other);
method public inline long div(Number other);
method public inline double div(me.saket.bytesize.ByteSize other);
Expand Down Expand Up @@ -94,6 +110,17 @@ package me.saket.bytesize {

public final class ErrorsKt {
method @Deprecated @kotlin.jvm.JvmSynthetic public static me.saket.bytesize.ByteSize ByteSize(long bytes);
method @kotlin.jvm.JvmSynthetic public long getBinaryBytes();
method @kotlin.jvm.JvmSynthetic public long getBinaryBytes();
method @kotlin.jvm.JvmSynthetic public me.saket.bytesize.ByteSize getBytes();
method @kotlin.jvm.JvmSynthetic public long getDecimalBits();
method @kotlin.jvm.JvmSynthetic public long getDecimalBits();
method @kotlin.jvm.JvmSynthetic public long getDecimalBytes();
method @kotlin.jvm.JvmSynthetic public long getDecimalBytes();
property @kotlin.jvm.JvmSynthetic public long binaryBytes;
property @kotlin.jvm.JvmSynthetic public me.saket.bytesize.ByteSize bytes;
property @kotlin.jvm.JvmSynthetic public long decimalBits;
property @kotlin.jvm.JvmSynthetic public long decimalBytes;
}

}
Expand Down
43 changes: 43 additions & 0 deletions library/src/commonMain/kotlin/me/saket/bytesize/Bitrate.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
@file:Suppress("INAPPLICABLE_JVM_NAME", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")

package me.saket.bytesize

import kotlin.jvm.JvmInline
import kotlin.jvm.JvmSynthetic
import kotlin.time.Duration
import kotlin.time.DurationUnit

/** Represents a byte or bit size per second. */
@JvmInline
value class Bitrate(
@PublishedApi
@get:JvmSynthetic
internal val bytesPerSecond: ByteSize,
) : Comparable<Bitrate> {
override inline operator fun compareTo(other: Bitrate): Int = bytesPerSecond.compareTo(other.bytesPerSecond)

inline operator fun plus(other: Bitrate): Bitrate = Bitrate(bytesPerSecond + other.bytesPerSecond)

inline operator fun minus(other: Bitrate): Bitrate = Bitrate(bytesPerSecond - other.bytesPerSecond)

inline operator fun times(multiplier: Double): Bitrate = Bitrate(bytesPerSecond * multiplier)

inline operator fun div(divisor: Double): Bitrate = Bitrate(bytesPerSecond / divisor)

override inline fun toString(): String = "$bytesPerSecond/s"
}

@JvmSynthetic
inline operator fun ByteSize.div(duration: Duration): Bitrate {
return Bitrate(this / duration.toDouble(DurationUnit.SECONDS))
}

@JvmSynthetic
inline operator fun Bitrate.times(duration: Duration): ByteSize {
return bytesPerSecond * duration.toDouble(DurationUnit.SECONDS)
}

@JvmSynthetic
inline operator fun Duration.times(bitrate: Bitrate): ByteSize {
return bitrate * this
}
80 changes: 80 additions & 0 deletions library/src/commonTest/kotlin/me/saket/bytesize/BitrateTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package me.saket.bytesize

import assertk.assertThat
import assertk.assertions.hasToString
import assertk.assertions.isEqualTo
import assertk.assertions.isGreaterThan
import assertk.assertions.isLessThan
import kotlin.test.Test
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds

class BitrateTest {
@Test fun plus() {
val rate1 = 10.megabytes / 1.seconds
val rate2 = 5.megabytes / 1.seconds
assertThat(rate1 + rate2).isEqualTo(15.megabytes / 1.seconds)
}

@Test fun minus() {
val rate1 = 10.megabytes / 1.seconds
val rate2 = 5.megabytes / 1.seconds
assertThat(rate1 - rate2).isEqualTo(5.megabytes / 1.seconds)
}

@Test fun times_double() {
val rate = 10.megabytes / 1.seconds
assertThat(rate * 2.5).isEqualTo(25.megabytes / 1.seconds)
}

@Test fun div_double() {
val rate = 10.megabytes / 1.seconds
assertThat(rate / 2.5).isEqualTo(4.megabytes / 1.seconds)
}

@Test fun binary_byte_size_div_duration() {
val rate = 100.mebibytes / 3.2.seconds
assertThat(rate).hasToString("31.25 MiB/s")
}

@Test fun decimal_byte_size_div_duration() {
val rate = 100.megabytes / 4.seconds
assertThat(rate).hasToString("25 MB/s")
}

@Test fun decimal_bit_size_div_duration() {
val rate = 100.megabits / 2.seconds
assertThat(rate).hasToString("50 Mb/s")
}

@Test fun bitrate_times_duration() {
val rate = 10.megabytes / 1.seconds
val size = rate * 5.seconds
assertThat(size).isEqualTo(50.megabytes)
}

@Test fun duration_times_bitrate() {
val rate = 10.megabytes / 1.seconds
val size = 5.seconds * rate
assertThat(size).isEqualTo(50.megabytes)
}

@Test fun bitrate_times_duration_with_minutes() {
val rate = 1.megabytes / 1.seconds
val size = rate * 1.minutes
assertThat(size).isEqualTo(60.megabytes)
}

@Test fun comparison() {
val slow = 10.megabytes / 1.seconds
val fast = 100.megabytes / 1.seconds
assertThat(slow).isLessThan(fast)
assertThat(fast).isGreaterThan(slow)
}

@Test fun comparison_across_types() {
val binary = 1.gibibytes / 1.seconds
val decimal = 1.gigabytes / 1.seconds
assertThat(binary).isGreaterThan(decimal)
}
}
Loading