1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2025-03-26 18:10:31 +00:00
royalnet/royalnet/commands/commandargs.py
2019-10-24 12:39:17 +02:00

70 lines
2.7 KiB
Python

import re
import typing
from .commanderrors import InvalidInputError
class CommandArgs(list):
"""An interface to access the arguments of a command with ease."""
def __getitem__(self, item):
"""Arguments can be accessed with an array notation, such as ``args[0]``.
Raises:
royalnet.error.InvalidInputError: if the requested argument does not exist."""
if isinstance(item, int):
try:
return super().__getitem__(item)
except IndexError:
raise InvalidInputError(f'Missing argument #{item+1}.')
if isinstance(item, slice):
try:
return super().__getitem__(item)
except IndexError:
raise InvalidInputError(f'Cannot get arguments from #{item.start+1} to #{item.stop+1}.')
raise ValueError(f"Invalid type passed to CommandArgs.__getattr__: {type(item)}")
def joined(self, *, require_at_least=0) -> str:
"""Get the arguments as a space-joined string.
Parameters:
require_at_least: the minimum amount of arguments required, will raise :py:exc:`royalnet.error.InvalidInputError` if the requirement is not fullfilled.
Raises:
royalnet.error.InvalidInputError: if there are less than ``require_at_least`` arguments.
Returns:
The space-joined string."""
if len(self) < require_at_least:
raise InvalidInputError(f"Not enough arguments specified (minimum is {require_at_least}).")
return " ".join(self)
def match(self, pattern: typing.Union[str, typing.Pattern], *flags) -> typing.Sequence[typing.AnyStr]:
"""Match the :py:func:`royalnet.utils.commandargs.joined` to a regex pattern.
Parameters:
pattern: The regex pattern to be passed to :py:func:`re.match`.
Raises:
royalnet.error.InvalidInputError: if the pattern doesn't match.
Returns:
The matched groups, as returned by :py:func:`re.Match.groups`."""
text = self.joined()
match = re.match(pattern, text, *flags)
if match is None:
raise InvalidInputError("Invalid syntax.")
return match.groups()
def optional(self, index: int, default=None) -> typing.Optional[str]:
"""Get the argument at a specific index, but don't raise an error if nothing is found, instead returning the ``default`` value.
Parameters:
index: The index of the argument you want to retrieve.
default: The value returned if the argument is missing.
Returns:
Either the argument or the ``default`` value, defaulting to ``None``."""
try:
return self[index]
except InvalidInputError:
return default