diff --git a/pkg/strongunits/config.go b/pkg/strongunits/config.go new file mode 100644 index 0000000000..35a6b0c3d1 --- /dev/null +++ b/pkg/strongunits/config.go @@ -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) +} diff --git a/pkg/strongunits/config_test.go b/pkg/strongunits/config_test.go new file mode 100644 index 0000000000..b698e63712 --- /dev/null +++ b/pkg/strongunits/config_test.go @@ -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) + } + }) + } +}