from typing import Optional, Any, Callable from base import Search type QueryCommand = Callable[[Any, Optional[str]], Search] class QueryParser(): def __init__(self, userdata: Any, default_command: str) -> Any: self.commands: dict[str, QueryCommand] = {} self.escaped_commands: dict[str, str] = {} self.userdata: Any = userdata self.default_command: str = default_command def add_command(self, name: str, search: QueryCommand) -> None: self.commands[name] = search self.escaped_commands['\\' + name] = name def parse_query(self, query: str) -> Search: arg = query search = self.commands[self.default_command] sp = query.split(' ') for index, word in enumerate(sp): col = word.find(':') if col == -1: continue command = word[0:col] if command in self.escaped_commands: query = query.replace(command, self.escaped_commands[command], 1) continue if command in self.commands: if col + 1 < len(word): arg = word[col+1:] else: arg = None search = self.commands[command] if index == 0: if len(sp) > 1: query = query.replace(word + ' ', '', 1) else: query = query.replace(word, '', 1) else: query = query.replace(' ' + word + ' ', '', 1) return search(self.userdata, arg)