Skip to content

Commit 3808e18

Browse files
committed
feat(json-pack): 🎸 add Bencode Map encoding support
1 parent 0b82925 commit 3808e18

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

src/json-pack/bencode/BencodeEncoder.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ export class BencodeEncoder implements BinaryJsonEncoder {
4040
return this.writeArr(value as unknown[]);
4141
case Uint8Array:
4242
return this.writeBin(value as Uint8Array);
43+
case Map:
44+
return this.writeMap(value as Map<unknown, unknown>);
4345
default:
4446
return this.writeUnknown(value);
4547
}
@@ -140,4 +142,17 @@ export class BencodeEncoder implements BinaryJsonEncoder {
140142
}
141143
writer.u8(0x65); // 'e'
142144
}
145+
146+
public writeMap(obj: Map<unknown, unknown>): void {
147+
const writer = this.writer;
148+
writer.u8(0x64); // 'd'
149+
const keys = sort([...obj.keys()]);
150+
const length = keys.length;
151+
for (let i = 0; i < length; i++) {
152+
const key = keys[i];
153+
this.writeStr(key + '');
154+
this.writeAny(obj.get(key));
155+
}
156+
writer.u8(0x65); // 'e'
157+
}
143158
}

src/json-pack/bencode/__tests__/BencodeEncoder.spec.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {BencodeEncoder} from '../BencodeEncoder';
66
const writer = new Writer(32);
77
const encoder = new BencodeEncoder(writer);
88

9-
const assertEncoder = (value: PackValue, expected: Uint8Array) => {
9+
const assertEncoder = (value: unknown, expected: Uint8Array) => {
1010
const encoded = encoder.encode(value);
1111
expect(encoded).toEqual(expected);
1212
};
@@ -156,3 +156,29 @@ describe('object', () => {
156156
}, utf8`d3:arrli1ei2ei3ee3:numi123e3:objd3:foo3:bare3:str6:qwertye`);
157157
});
158158
});
159+
160+
describe('map', () => {
161+
test('empty object', () => {
162+
assertEncoder(new Map(), utf8`de`);
163+
});
164+
165+
test('object with one key', () => {
166+
assertEncoder(new Map([['foo', 'bar']]), utf8`d3:foo3:bare`);
167+
});
168+
169+
test('object with two keys (sorted)', () => {
170+
assertEncoder(new Map<unknown, unknown>([
171+
['foo', 'bar'],
172+
['baz', 123],
173+
]), utf8`d3:bazi123e3:foo3:bare`);
174+
});
175+
176+
test('object with various nested types', () => {
177+
assertEncoder(new Map<unknown, unknown>([
178+
['str', 'qwerty'],
179+
['num', 123],
180+
['arr', [1, 2, 3]],
181+
['obj', {foo: 'bar'}],
182+
]), utf8`d3:arrli1ei2ei3ee3:numi123e3:objd3:foo3:bare3:str6:qwertye`);
183+
});
184+
});

0 commit comments

Comments
 (0)