Source code for spil.sid.read.finder

"""
This file is part of SPIL, The Simple Pipeline Lib.

(C) copyright 2019-2023 Michael Haussmann, spil@xeo.info

SPIL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

SPIL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with SPIL.
If not, see <https://www.gnu.org/licenses/>.
"""
from __future__ import annotations
from typing import Iterator, List, overload, Optional
from typing_extensions import Literal

from spil.sid.sid import Sid
from spil.sid.read.util import first
from spil.sid.read.tools import unfold_search


[docs]class Finder: """ Interface for Sid Finder. Implements common public Sid Search methods "find", "find_one", and "exists" The search process is as follows: find(): - the search sid string is "unfolded" into a list of typed search Sids. do_find() - runs the actual search on each typed search sid """ @overload def find(self, search_sid: str, as_sid: Literal[True]) -> Iterator[Sid]: ... @overload def find(self, search_sid: str, as_sid: Literal[False]) -> Iterator[str]: ... @overload def find(self, search_sid: Sid, as_sid: Literal[True]) -> Iterator[Sid]: ... @overload def find(self, search_sid: Sid, as_sid: Literal[False]) -> Iterator[str]: ... @overload def find(self, search_sid: str) -> Iterator[Sid]: ... @overload def find(self, search_sid: Sid) -> Iterator[Sid]: ...
[docs] def find( self, search_sid: str | Sid, as_sid: Optional[bool] = True ) -> Iterator[Sid] | Iterator[str]: """ Yields the Sids found using the given search_sid. Returns a generator over Sids, if as_sid is True (default), or over Sid strings. Example: >>> from spil import FindInAll >>> list(FindInAll().find('hamlet/a/*')) [Sid('asset__assettype:hamlet/a/char'), Sid('asset__assettype:hamlet/a/location'), Sid('asset__assettype:hamlet/a/prop'), Sid('asset__assettype:hamlet/a/fx')] Args: search_sid: typed or untyped Sid or string as_sid: if the result should be Sid objects or strings Returns: Generator over Sids or strings """ # shortcut if Sid is not a search sid = Sid(search_sid) if sid and not sid.is_search(): generator = self.do_find([sid], as_sid=as_sid) else: search_sids = unfold_search(search_sid) generator = self.do_find(search_sids, as_sid=as_sid) yield from generator
@overload def do_find(self, search_sids: List[Sid], as_sid: Literal[True]) -> Iterator[Sid]: ... @overload def do_find(self, search_sids: List[Sid], as_sid: Literal[False]) -> Iterator[str]: ... @overload def do_find( self, search_sids: List[Sid], as_sid: Optional[bool] ) -> Iterator[Sid] | Iterator[str]: ...
[docs] def do_find( self, search_sids: List[Sid], as_sid: Optional[bool] = True ) -> Iterator[Sid] | Iterator[str]: raise NotImplementedError( f"[Finder.do_find] is abstract, and seams not implemented. Class: {self.__class__}" )
@overload def find_one(self, search_sid: str | Sid, as_sid: Literal[True]) -> Sid: ... @overload def find_one(self, search_sid: str | Sid, as_sid: Literal[False]) -> str: ... @overload def find_one(self, search_sid: str | Sid, as_sid: Optional[bool]) -> Sid | str: ...
[docs] def find_one(self, search_sid: str | Sid, as_sid: Optional[bool] = True) -> Sid | str: """ Returns the first Sid found using the given search_sid. Returns a Sid, if as_sid is True (default), or a Sid strings. Internally calls "first" on "find". Example: >>> from spil import FindInAll >>> FindInAll().find_one('hamlet/a/char/ophelia') Sid('asset__asset:hamlet/a/char/ophelia') Args: search_sid: typed or untyped Sid or string as_sid: if the result should be a Sid object or string Returns: first found Sid or string """ found = first(self.find(search_sid, as_sid=False)) # read is faster if as_sid is False if as_sid: return Sid(found) else: return found
[docs] def exists(self, search_sid: str | Sid) -> bool: """ Returns True if the given search_sid returns a result. Else False. Internally calls "bool" on "find_one". Example: >>> from spil import FindInAll >>> FindInAll().exists('hamlet/a/char/ophelia') True >>> from spil import FindInAll >>> FindInAll().exists('hamlet/a/char/jimmy') False Args: search_sid: search_sid: typed or untyped Sid or string Returns: True if search_sid returns a result, else False """ return bool(self.find_one(search_sid, as_sid=False))
def __str__(self): return f"[spil.{self.__class__.__name__}]"
if __name__ == "__main__": print(Finder())