|
1 | 1 | from typing import Any, Callable |
| 2 | +from copy import deepcopy |
2 | 3 |
|
3 | 4 | _NONE = object() |
4 | 5 |
|
5 | 6 |
|
6 | | -class JsonL: |
7 | | - def __init__(self): |
8 | | - self._prev: dict[str, Any] = {'type': None} |
9 | | - |
10 | | - def __call__(self, d: dict[str, Any]) -> dict[str, Any]: |
11 | | - res = self._call(d) |
12 | | - self._prev = d |
13 | | - return res |
| 7 | +class Jsonl: |
| 8 | + def __init__(self) -> None: |
| 9 | + self._types: dict[str, dict[str, Any]] = {} |
14 | 10 |
|
15 | 11 | def _call(self, d: dict[str, Any]) -> dict[str, Any]: |
16 | 12 | raise NotImplementedError |
17 | 13 |
|
| 14 | + def __call__(self, it: Iterable[dict[str, Any]]) -> Iterator[dict[str, Any]]: |
| 15 | + yield from (self._call(i) for i in it) |
| 16 | + |
18 | 17 |
|
19 | | -class CompressJsonL(JsonL): |
| 18 | +class Decompress(Jsonl): |
20 | 19 | def _call(self, d: dict[str, Any]) -> dict[str, Any]: |
21 | | - if self._prev['type'] != d['type']: |
22 | | - return d |
23 | | - return {k: v for k, v in d.items() if self._prev.get(k, _NONE) != v} |
| 20 | + prev = self._types.setdefault(d['type'], {}) |
| 21 | + res = prev | d |
| 22 | + prev.update(d) |
| 23 | + return res |
24 | 24 |
|
25 | 25 |
|
26 | | -class DecompressJsonL(JsonL): |
| 26 | +class Compress(Jsonl): |
27 | 27 | def _call(self, d: dict[str, Any]) -> dict[str, Any]: |
28 | | - return d if 'type' in d else d | self._prev |
| 28 | + prev = self._types.setdefault(d['type'], {}) |
| 29 | + |
| 30 | + def accept(k: str, v: Any) -> bool: |
| 31 | + return k == 'type' or prev.get(k, _NONE) != v |
| 32 | + |
| 33 | + return {k: v for k, v in b.items() if accept(k, v)} |
0 commit comments