Skip to content

Commit 948c6cf

Browse files
committed
feat(json-pack): 🎸 add skipping ability to streaming RESP decoder
1 parent 61f4d3a commit 948c6cf

File tree

2 files changed

+51
-11
lines changed

2 files changed

+51
-11
lines changed

src/json-pack/resp/RespStreamingDecoder.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,26 @@ export class RespStreamingDecoder {
6666
} else throw error;
6767
}
6868
}
69+
70+
/**
71+
* Skips one value from the stream. If `undefined` is returned, then
72+
* there is not enough data to skip or the stream is finished.
73+
* @returns `null` if a value was skipped, `undefined` if there is not
74+
* enough data to skip.
75+
*/
76+
public skip(): null | undefined {
77+
const reader = this.reader;
78+
if (reader.size() === 0) return undefined;
79+
const x = reader.x;
80+
try {
81+
this.decoder.skipAny();
82+
reader.consume();
83+
return null;
84+
} catch (error) {
85+
if (error instanceof RangeError) {
86+
reader.x = x;
87+
return undefined;
88+
} else throw error;
89+
}
90+
}
6991
}
Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,41 @@
11
import {RespEncoder} from '../RespEncoder';
22
import {RespDecoder} from '../RespDecoder';
3+
import {RespStreamingDecoder} from '../RespStreamingDecoder';
34
import {documents} from '../../../__tests__/json-documents';
45
import {binaryDocuments} from '../../../__tests__/binary-documents';
56

67
const docs = [...documents, ...binaryDocuments];
78

89
const encoder = new RespEncoder();
910
const decoder = new RespDecoder();
11+
const streamingDecoder = new RespStreamingDecoder();
1012

1113
describe('skipping', () => {
12-
for (const t of docs) {
13-
(t.only ? test.only : test)(t.name, () => {
14-
encoder.writeAny(t.json);
15-
encoder.writeAny({foo: 'bar'});
16-
const encoded = encoder.writer.flush();
17-
decoder.reader.reset(encoded);
18-
decoder.skipAny();
19-
const decoded = decoder.val();
20-
expect(decoded).toEqual({foo: 'bar'});
21-
});
22-
}
14+
describe('RespDecoder', () => {
15+
for (const t of docs) {
16+
(t.only ? test.only : test)(t.name, () => {
17+
encoder.writeAny(t.json);
18+
encoder.writeAny({foo: 'bar'});
19+
const encoded = encoder.writer.flush();
20+
decoder.reader.reset(encoded);
21+
decoder.skipAny();
22+
const decoded = decoder.val();
23+
expect(decoded).toEqual({foo: 'bar'});
24+
});
25+
}
26+
});
27+
28+
describe('RespStreamingDecoder', () => {
29+
for (const t of docs) {
30+
(t.only ? test.only : test)(t.name, () => {
31+
encoder.writeAny(t.json);
32+
encoder.writeAny({foo: 'bar'});
33+
const encoded = encoder.writer.flush();
34+
streamingDecoder.push(encoded);
35+
streamingDecoder.skip();
36+
const decoded = streamingDecoder.read();
37+
expect(decoded).toEqual({foo: 'bar'});
38+
});
39+
}
40+
});
2341
});

0 commit comments

Comments
 (0)