Coverage for src/blob_dict/blob/__init__.py: 0%
47 statements
« prev ^ index » next coverage.py v7.8.1, created at 2025-05-23 02:51 -0700
« prev ^ index » next coverage.py v7.8.1, created at 2025-05-23 02:51 -0700
1from __future__ import annotations
3from base64 import b64decode, b64encode
4from pathlib import Path
5from typing import Any, Self, override
7from simple_zstd import compress, decompress
10class BytesBlob:
11 def __init__(self, blob: bytes) -> None:
12 super().__init__()
14 self._blob_bytes: bytes = blob
16 def as_blob(
17 self,
18 blob_class: type[BytesBlob],
19 blob_class_args: dict[str, Any] | None = None,
20 ) -> BytesBlob:
21 return blob_class(self._blob_bytes, **(blob_class_args or {}))
23 def as_bytes(self, *, compression: bool = False) -> bytes:
24 return compress(self._blob_bytes) if compression else self._blob_bytes
26 @staticmethod
27 def from_bytes(b: bytes, *, compression: bool = False) -> BytesBlob:
28 return BytesBlob(decompress(b) if compression else b)
30 @staticmethod
31 def from_b64_str(s: str) -> BytesBlob:
32 return BytesBlob(b64decode(s))
34 def as_b64_str(self) -> str:
35 return b64encode(self._blob_bytes).decode("ascii")
37 def __repr__(self) -> str:
38 return f"{self.__class__.__name__}({self.as_bytes().__repr__()})"
40 @classmethod
41 def load(cls: type[Self], f: Path | str) -> Self:
42 return cls(Path(f).expanduser().read_bytes())
44 def dump(self, f: Path | str) -> None:
45 Path(f).expanduser().write_bytes(self.as_bytes())
47 @override
48 def __eq__(self, value: object) -> bool:
49 if isinstance(value, bytes):
50 return self._blob_bytes == value
52 if isinstance(value, BytesBlob):
53 return self._blob_bytes == value._blob_bytes
55 return False
58class StrBlob(BytesBlob):
59 def __init__(self, blob: bytes | str) -> None:
60 if isinstance(blob, str):
61 blob = blob.encode()
63 super().__init__(blob)
65 def as_str(self) -> str:
66 return self._blob_bytes.decode()
68 def __str__(self) -> str:
69 return self.as_str()
71 @override
72 def __repr__(self) -> str:
73 return f"{self.__class__.__name__}({self.as_str().__repr__()})"