util.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. from collections.abc import Callable, Coroutine
  2. from typing import TypeVar
  3. from ..types import Message, Context
  4. from .base import Injector, InjectorWithCleanup
  5. __all__ = [
  6. "Lazy",
  7. "MessageInjector",
  8. "ContextInjector",
  9. "Origin",
  10. "Channel",
  11. "Sender",
  12. "Timestamp",
  13. "OriginAdmin",
  14. "ChannelAdmin",
  15. "Text",
  16. "Attachments",
  17. "CommandInjector",
  18. ]
  19. Dep = TypeVar("Dep")
  20. class Simple(Injector[Dep]):
  21. def __init__(self, extract: Callable[[Message, Context], Dep]):
  22. self.extract = extract
  23. async def inject(self, message: Message, context: Context) -> Dep:
  24. return self.extract(message, context)
  25. MessageInjector = Simple(lambda m, c: m)
  26. ContextInjector = Simple(lambda m, c: c)
  27. Origin = Simple(lambda m, c: m.origin_id)
  28. Channel = Simple(lambda m, c: m.channel_id)
  29. Sender = Simple(lambda m, c: m.sender_id)
  30. Timestamp = Simple(lambda m, c: m.timestamp)
  31. OriginAdmin = Simple(lambda m, c: m.origin_admin)
  32. ChannelAdmin = Simple(lambda m, c: m.channel_admin)
  33. Text = Simple(lambda m, c: m.text)
  34. Attachments = Simple(lambda m, c: m.attachments)
  35. CommandInjector = Simple(lambda m, c: m.command)
  36. class Lazy(InjectorWithCleanup[Callable[[], Coroutine[None, None, Dep]]]):
  37. def __init__(self, deferred: Injector[Dep]):
  38. self.deferred = deferred
  39. async def inject(
  40. self, message: Message, context: Context
  41. ) -> Callable[[], Coroutine[None, None, Dep]]:
  42. class _Wrapper:
  43. def __init__(self, deferred):
  44. self._calculated = None
  45. async def call():
  46. if self._calculated is None:
  47. self._calculated = await deferred.inject(message, context)
  48. return self._calculated
  49. self._call = call
  50. def __call__(self):
  51. return self._call()
  52. return _Wrapper(self.deferred)
  53. async def cleanup(self, dep: Callable[[], Coroutine[None, None, Dep]]):
  54. if isinstance(self.deferred, InjectorWithCleanup) and dep._calculated is not None:
  55. await self.deferred.cleanup(dep._calculated)