from pathlib import Path import yaml as yams from configparser import ConfigParser as cfg from custtypes import ExecutedPath from re import compile as rgx, IGNORECASE from whereami import PROJ_ROOT from typing import Literal class Parser: def __init__(self): self.__is_yaml = rgx(r".*\.ya?ml$", flags=IGNORECASE).match self.__is_ini = rgx(r".*\.ini$", flags=IGNORECASE).match self.__is_config = rgx(r".*\.cfg$", flags=IGNORECASE).match self.__is_json = rgx(r".*\.[jb]son$", flags=IGNORECASE).match self.__data = None self.__content: str | None = None self.__is_path: bool = False # @TODO use Enum child class for below type hint instead self.__method: Literal["yaml", "config", "generic"] = "generic" self.__file: ExecutedPath | None = None def load(self, filepath: ExecutedPath | str, method: Literal["yaml", "config", "generic"] = "generic", **kwargs): if isinstance(filepath, ExecutedPath): self.__is_path = True self.__file = filepath filepath = str(filepath) else: self.__is_path = False if Path(filepath).exists(): self.__file = Path(filepath) else: self.__content = filepath if self.__is_yaml(filepath) or method == "yaml": self.__method = "yaml" if self.__is_path: filepath = open(str(filepath), "r") if len(kwargs) > 0: self.__data = yams.load(filepath, Loader=yams.Loader, **kwargs) else: self.__data = yams.load(filepath, Loader=yams.Loader) elif self.__is_config(filepath) or method == "config": self.__method = "config" self.__data = cfg() if self.__is_path: read = self.__data.read else: read = self.__data.read_string if len(kwargs) > 0: self.__data.read(filepath, **kwargs) else: self.__data.read(filepath) else: raise TypeError return self.__data def dump(self, obj = None, method: Literal["yaml", "config", "generic"] | None = "generic", **kwargs): if self.__method == "yaml" or method == "yaml": if obj is None: obj = self.__data if len(kwargs) > 0: self.__content = yams.dump(obj, Dumper=yams.Dumper, **kwargs) else: self.__content = yams.dump(obj, Dumper=yams.Dumper) elif self.__method == "config" or method == "config": if obj is None: if self.__is_path: return self.__file.read_text() else: if self.__file is None: return self.__content else: return self.__file.read_text() else: if isinstance(obj, ConfigParser): return obj else: raise TypeError else: raise TypeError return self.__content