Skip to content

Commit 9b2a45a

Browse files
authored
feat(core): Size.bytes() (#24136)
This PR adds Size.bytes(), which allows to specify a Size class from an amount of bytes. Within the Size class, `Size.bytes( )` is the additional method added here to enable support for bytes as well as conversion to bytes with `Size.toBytes`. For example, ```ts const size = new Size.bytes(1024); expect(size.toKibibytes).toEqual(1); ``` creates a new object of the Size class with a size of 1024 bytes and which is equivalent to 1 kibibyte. Closes #24106. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 12e13c1 commit 9b2a45a

File tree

2 files changed

+46
-9
lines changed

2 files changed

+46
-9
lines changed

packages/@aws-cdk/core/lib/size.ts

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,17 @@ import { Token } from './token';
99
* When the amount is passed as a token, unit conversion is not possible.
1010
*/
1111
export class Size {
12+
/**
13+
* Create a Storage representing an amount bytes.
14+
*
15+
* @param amount the amount of bytes to be represented
16+
*
17+
* @returns a new `Size` instance
18+
*/
19+
public static bytes(amount: number): Size {
20+
return new Size(amount, StorageUnit.Bytes);
21+
}
22+
1223
/**
1324
* Create a Storage representing an amount kibibytes.
1425
* 1 KiB = 1024 bytes
@@ -90,6 +101,17 @@ export class Size {
90101
this.unit = unit;
91102
}
92103

104+
/**
105+
* Return this storage as a total number of bytes.
106+
*
107+
* @param opts the conversion options
108+
*
109+
* @returns the quantity expressed in bytes
110+
*/
111+
public toBytes(opts: SizeConversionOptions = {}): number {
112+
return convert(this.amount, this.unit, StorageUnit.Bytes, opts);
113+
}
114+
93115
/**
94116
* Return this storage as a total number of kibibytes.
95117
*
@@ -177,13 +199,14 @@ export interface SizeConversionOptions {
177199
}
178200

179201
class StorageUnit {
180-
public static readonly Kibibytes = new StorageUnit('kibibytes', 1);
181-
public static readonly Mebibytes = new StorageUnit('mebibytes', 1024);
182-
public static readonly Gibibytes = new StorageUnit('gibibytes', 1024 * 1024);
183-
public static readonly Tebibytes = new StorageUnit('tebibytes', 1024 * 1024 * 1024);
184-
public static readonly Pebibytes = new StorageUnit('pebibytes', 1024 * 1024 * 1024 * 1024);
185-
186-
private constructor(public readonly label: string, public readonly inKibiBytes: number) {
202+
public static readonly Bytes = new StorageUnit('bytes', 1);
203+
public static readonly Kibibytes = new StorageUnit('kibibytes', 1024);
204+
public static readonly Mebibytes = new StorageUnit('mebibytes', 1024 * 1024);
205+
public static readonly Gibibytes = new StorageUnit('gibibytes', 1024 * 1024 * 1024);
206+
public static readonly Tebibytes = new StorageUnit('tebibytes', 1024 * 1024 * 1024 * 1024);
207+
public static readonly Pebibytes = new StorageUnit('pebibytes', 1024 * 1024 * 1024 * 1024 * 1024);
208+
209+
private constructor(public readonly label: string, public readonly inBytes: number) {
187210
// MAX_SAFE_INTEGER is 2^53, so by representing storage in kibibytes,
188211
// the highest storage we can represent is 8 exbibytes.
189212
}
@@ -195,12 +218,12 @@ class StorageUnit {
195218

196219
function convert(amount: number, fromUnit: StorageUnit, toUnit: StorageUnit, options: SizeConversionOptions = {}) {
197220
const rounding = options.rounding ?? SizeRoundingBehavior.FAIL;
198-
if (fromUnit.inKibiBytes === toUnit.inKibiBytes) { return amount; }
221+
if (fromUnit.inBytes === toUnit.inBytes) { return amount; }
199222
if (Token.isUnresolved(amount)) {
200223
throw new Error(`Size must be specified as 'Size.${toUnit}()' here since its value comes from a token and cannot be converted (got Size.${fromUnit})`);
201224
}
202225

203-
const multiplier = fromUnit.inKibiBytes / toUnit.inKibiBytes;
226+
const multiplier = fromUnit.inBytes / toUnit.inBytes;
204227
const value = amount * multiplier;
205228
switch (rounding) {
206229
case SizeRoundingBehavior.NONE:

packages/@aws-cdk/core/test/size.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,20 @@ describe('size', () => {
1515
);
1616
});
1717

18+
test('Size in bytes', () => {
19+
const size = Size.bytes(1_099_511_627_776);
20+
21+
expect(size.toBytes()).toEqual(1_099_511_627_776);
22+
expect(size.toKibibytes()).toEqual(1_073_741_824);
23+
expect(size.toMebibytes()).toEqual(1_048_576);
24+
expect(size.toGibibytes()).toEqual(1024);
25+
expect(size.toTebibytes()).toEqual(1);
26+
expect(() => size.toPebibytes()).toThrow(/'1099511627776 bytes' cannot be converted into a whole number/);
27+
floatEqual(size.toPebibytes({ rounding: SizeRoundingBehavior.NONE }), 1_099_511_627_776 / (1024 * 1024 * 1024 * 1024 * 1024));
28+
29+
expect(Size.bytes(4 * 1024 * 1024 * 1024).toGibibytes()).toEqual(4);
30+
});
31+
1832
test('Size in kibibytes', () => {
1933
const size = Size.kibibytes(4_294_967_296);
2034

0 commit comments

Comments
 (0)