from __future__ import annotations from typing import Any from .config import Config class DuplicateArgumentError(Exception): def __init__(self, key: str) -> None: self.message = f"Duplicate argument: {key}" def __str__(self) -> str: return self.message class MissingInfoError(Exception): def __init__(self, key: str) -> None: self.message = f"Missing info for argument: {key}" def __str__(self) -> str: return self.message class DuplicateInfoError(Exception): def __init__(self, key: str) -> None: self.message = f"Duplicate info for argument: {key}" def __str__(self) -> str: return self.message class ArgSpec: vinfo: str defaults: dict[str, Any] arguments: dict[str, Any] infos: list[str] @staticmethod def prepare() -> None: ArgSpec.vinfo = f"{Config.title} {Config.version}" ArgSpec.defaults = {} ArgSpec.arguments = {} ArgSpec.infos = [] ArgSpec.add_arguments() @staticmethod def add_argument(key: str, info: str, **kwargs: Any) -> None: if key in ArgSpec.arguments: raise DuplicateArgumentError(key) if not info: raise MissingInfoError(key) if info in ArgSpec.infos: raise DuplicateInfoError(key) ArgSpec.arguments[key] = { "help": info, **kwargs, } ArgSpec.infos.append(info) @staticmethod def add_arguments() -> None: ArgSpec.add_argument( "version", action="version", info="Check the version of the program", version=ArgSpec.vinfo, ) ArgSpec.add_argument( "names", type=str, info="Path to a JSON file with a list of names. Use these instead of the default ones", ) ArgSpec.add_argument( "ants", type=str, info="Path to a JSON file with ants data. Use this instead of the default one", ) ArgSpec.add_argument( "no_images", action="store_false", info="Don't show the images on the left", ) ArgSpec.add_argument( "no_header", action="store_false", info="Don't show the header controls", ) ArgSpec.add_argument( "no_footer", action="store_false", info="Don't show the footer controls", ) ArgSpec.add_argument( "no_intro", action="store_false", info="Don't show the intro message", ) ArgSpec.add_argument( "title", type=str, info="Custom title for the window", ) ArgSpec.add_argument( "width", type=int, info="The width of the window in pixels", ) ArgSpec.add_argument( "height", type=int, info="The height of the window in pixels", ) ArgSpec.add_argument( "program", type=str, info="The internal name of the program", ) ArgSpec.add_argument( "speed", type=str, choices=["fast", "normal", "slow", "paused"], info="Use this update speed", ) ArgSpec.add_argument( "clean", action="store_true", info="Start with clean ants data", ) ArgSpec.add_argument( "fast_seconds", type=int, info="The number of seconds between fast updates", ) ArgSpec.add_argument( "normal_minutes", type=float, info="The number of minutes between normal updates", ) ArgSpec.add_argument( "slow_minutes", type=float, info="The number of minutes between slow updates", ) ArgSpec.add_argument( "argdoc", action="store_true", info="Make the arguments document and exit", ) ArgSpec.add_argument( "score", action="store_true", info="Show the score on triumph or hits instead of the total of each", ) ArgSpec.add_argument( "mono", action="store_true", info="Use a monospace font", ) ArgSpec.add_argument( "no_fade", action="store_false", info="Don't apply a fade-in effect on new updates", )