diff --git a/royalnet/scroll/__init__.py b/royalnet/scroll/__init__.py index 54dc963f..99fc3444 100644 --- a/royalnet/scroll/__init__.py +++ b/royalnet/scroll/__init__.py @@ -2,6 +2,8 @@ from royalnet.typing import * import os import json import re +import toml +import json from .errors import * @@ -11,10 +13,40 @@ class Scroll: key_validator = re.compile(r"^[A-Z.]+$") + loaders = { + ".json": json.load, + ".toml": toml.load + } + def __init__(self, namespace: str, config: Optional[Dict[str, JSON]] = None): self.namespace: str = namespace self.config: Optional[Dict[str, JSON]] = config + @classmethod + def from_toml(cls, namespace: str, file_path: os.PathLike): + with open(file_path) as file: + config = toml.load(file) + return cls(namespace, config) + + @classmethod + def from_json(cls, namespace: str, file_path: os.PathLike): + with open(file_path) as file: + config = json.load(file) + return cls(namespace, config) + + @classmethod + def from_file(cls, namespace: str, file_path: os.PathLike): + file, ext = os.path.splitext(file_path) + lext = ext.lower() + + with open(file_path) as file: + try: + config = cls.loaders[lext](file) + except KeyError: + raise InvalidFileType(f"Invalid extension: {lext}") + + return cls(namespace, config) + @classmethod def _validate_key(cls, item: str): check = cls.key_validator.match(item) diff --git a/royalnet/scroll/errors.py b/royalnet/scroll/errors.py index 229e8322..eeeb40bd 100644 --- a/royalnet/scroll/errors.py +++ b/royalnet/scroll/errors.py @@ -17,9 +17,14 @@ class ParseError(ScrollException): """The config value could not be parsed correctly.""" +class InvalidFileType(ParseError): + """The type of the specified config file is not currently supported.""" + + __all__ = ( "ScrollException", "NotFoundError", "InvalidFormatError", "ParseError", + "InvalidFileType", )