-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #20063 from baude/strongunits
introduce pkg/strongunits
- Loading branch information
Showing
2 changed files
with
253 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package strongunits | ||
|
||
// supported units | ||
|
||
// B represents bytes | ||
type B uint64 | ||
|
||
// KiB represents KiB | ||
type KiB uint64 | ||
|
||
// MiB represents MiB | ||
type MiB uint64 | ||
|
||
// GiB represents GiB | ||
type GiB uint64 | ||
|
||
const ( | ||
// kibToB is the math convert from bytes to KiB | ||
kibToB = 1 << 10 | ||
// mibToB is the math to convert from bytes to MiB | ||
mibToB = 1 << 20 | ||
// gibToB s the math to convert from bytes to GiB | ||
gibToB = 1 << 30 | ||
) | ||
|
||
// StorageUnits is an interface for converting disk/memory storage | ||
// units amongst each other. | ||
type StorageUnits interface { | ||
ToBytes() B | ||
} | ||
|
||
// ToBytes is a pass-through function for bytes | ||
func (b B) ToBytes() B { | ||
return b | ||
} | ||
|
||
// ToBytes converts KiB to bytes | ||
func (k KiB) ToBytes() B { | ||
return B(k * kibToB) | ||
} | ||
|
||
// ToBytes converts MiB to bytes | ||
func (m MiB) ToBytes() B { | ||
return B(m * mibToB) | ||
} | ||
|
||
// ToBytes converts GiB to bytes | ||
func (g GiB) ToBytes() B { | ||
return B(g * gibToB) | ||
} | ||
|
||
// ToKiB converts any StorageUnit type to KiB | ||
func ToKiB(b StorageUnits) KiB { | ||
return KiB(b.ToBytes() >> 10) | ||
} | ||
|
||
// ToMib converts any StorageUnit type to MiB | ||
func ToMib(b StorageUnits) MiB { | ||
return MiB(b.ToBytes() >> 20) | ||
} | ||
|
||
// ToGiB converts any StorageUnit type to GiB | ||
func ToGiB(b StorageUnits) GiB { | ||
return GiB(b.ToBytes() >> 30) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
package strongunits | ||
|
||
import "testing" | ||
|
||
func TestGiB_toBytes(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
g GiB | ||
want B | ||
}{ | ||
{ | ||
name: "good-1", | ||
g: 1, | ||
want: 1073741824, | ||
}, | ||
{ | ||
name: "good-2", | ||
g: 2, | ||
want: 2147483648, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
if got := tt.g.ToBytes(); got != tt.want { | ||
t.Errorf("ToBytes() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestKiB_toBytes(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
k KiB | ||
want B | ||
}{ | ||
{ | ||
name: "good-1", | ||
k: 100, | ||
want: 102400, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
if got := tt.k.ToBytes(); got != tt.want { | ||
t.Errorf("ToBytes() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestMiB_toBytes(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
m MiB | ||
want B | ||
}{ | ||
{ | ||
name: "good-1", | ||
m: 1024, | ||
want: 1073741824, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
if got := tt.m.ToBytes(); got != tt.want { | ||
t.Errorf("ToBytes() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestToGiB(t *testing.T) { | ||
type args struct { | ||
b StorageUnits | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
want GiB | ||
}{ | ||
{ | ||
name: "bytes to gib", | ||
args: args{B(5368709120)}, | ||
want: 5, | ||
}, | ||
{ | ||
name: "kib to gib", | ||
args: args{KiB(3145728 * 2)}, | ||
want: 6, | ||
}, | ||
{ | ||
name: "mib to gib", | ||
args: args{MiB(2048)}, | ||
want: 2, | ||
}, | ||
{ | ||
name: "gib to gib", | ||
args: args{GiB(2)}, | ||
want: 2, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
if got := ToGiB(tt.args.b); got != tt.want { | ||
t.Errorf("ToGiB() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestToKiB(t *testing.T) { | ||
type args struct { | ||
b StorageUnits | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
want KiB | ||
}{ | ||
{ | ||
name: "bytes to kib", | ||
args: args{B(1024)}, | ||
want: 1, | ||
}, | ||
{ | ||
name: "mib to kib", | ||
args: args{MiB(2)}, | ||
want: 2048, | ||
}, | ||
{ | ||
name: "kib to kib", | ||
args: args{KiB(800)}, | ||
want: 800, | ||
}, | ||
{ | ||
name: "gib to mib", | ||
args: args{GiB(3)}, | ||
want: 3145728, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
if got := ToKiB(tt.args.b); got != tt.want { | ||
t.Errorf("ToKiB() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestToMib(t *testing.T) { | ||
type args struct { | ||
b StorageUnits | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
want MiB | ||
}{ | ||
{ | ||
name: "bytes to mib", | ||
args: args{B(3145728)}, | ||
want: 3, | ||
}, | ||
{ | ||
name: "kib to mib", | ||
args: args{KiB(2048)}, | ||
want: 2, | ||
}, | ||
{ | ||
name: "mib to mib", | ||
args: args{MiB(2)}, | ||
want: 2, | ||
}, | ||
{ | ||
name: "gib to mib", | ||
args: args{GiB(3)}, | ||
want: 3072, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
if got := ToMib(tt.args.b); got != tt.want { | ||
t.Errorf("ToMib() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} |