import json import pathlib import typing T = typing.TypeVar("T") class Cache: __slots__ = ["__data", "__filepath", "__no_load"] def __init__(self, filepath: str, no_load: bool) -> None: # noqa: FBT001 self.__filepath = pathlib.Path(filepath) self.__no_load = no_load self.__data: dict[str, typing.Any] | None = None def load(self) -> None: if not self.__no_load and self.__filepath.exists(): self.__data = json.loads(self.__filepath.read_text()) else: self.__data = {} def write(self) -> None: self.__filepath.write_text(json.dumps(self.__data)) def __enter__(self) -> typing.Self: self.load() return self def __exit__(self, *_: object) -> None: self.write() def has(self, key: str) -> bool: return self.__data is not None and key in self.__data def get(self, key: str) -> typing.Any: if self.__data is not None and key in self.__data: return self.__data[key] return None def set(self, key: str, value: typing.Any) -> None: if self.__data is not None: self.__data[key] = value self.write() def get_or_set(self, key: str, callback: typing.Callable[[], T]) -> T: if not self.has(key): self.set(key, callback()) return self.get(key)