|
1 | | -from typing import Any, ClassVar, Protocol, TypeVar |
| 1 | +from typing import Any, Protocol, TypeVar |
2 | 2 |
|
3 | 3 |
|
4 | 4 | Actor = TypeVar("Actor", contravariant=True) |
5 | 5 |
|
6 | 6 |
|
7 | 7 | class RuleProto(Protocol[Actor]): |
8 | | - async def __call__(self, actor: Actor, *args: Any, **kwargs: Any) -> bool: ... |
| 8 | + async def __call__( |
| 9 | + self, actor: Actor, *args: Any, **kwargs: Any |
| 10 | + ) -> bool | None: ... |
9 | 11 |
|
10 | 12 |
|
11 | 13 | class Rule[Actor]: |
12 | | - _registry: ClassVar[dict[str, RuleProto[Any]]] = {} |
13 | | - _before_callback: RuleProto[Any] | None = None |
| 14 | + def __init__(self, name: str, callable: RuleProto[Actor]) -> None: |
| 15 | + self.name = name |
| 16 | + self.callable = callable |
| 17 | + self._before_callbacks: list[RuleProto[Actor]] = [] |
14 | 18 |
|
15 | | - @classmethod |
16 | | - def define(cls, name: str, closure: RuleProto[Actor]) -> None: |
17 | | - cls._registry[name] = closure |
| 19 | + def before(self, *rule: RuleProto[Actor]): |
| 20 | + self._before_callbacks = list(rule) |
18 | 21 |
|
19 | | - @classmethod |
20 | | - def before(cls, rule: RuleProto[Actor] | None): |
21 | | - cls._before_callback = rule |
22 | | - |
23 | | - @classmethod |
24 | 22 | async def allows( |
25 | | - cls, |
26 | | - name: str, |
| 23 | + self, |
27 | 24 | actor: Actor, |
28 | 25 | *args: Any, |
29 | 26 | **kwargs: Any, |
30 | 27 | ) -> bool: |
31 | | - if name in cls._registry: |
32 | | - return await cls._registry[name](actor, args, kwargs) |
33 | | - |
34 | | - return False |
| 28 | + response = await self.callable(actor, args, kwargs) |
| 29 | + return response if response is not None else False |
35 | 30 |
|
36 | | - @classmethod |
37 | 31 | async def denies( |
38 | | - cls, |
39 | | - name: str, |
40 | | - actor: Actor, |
41 | | - *args: Any, |
42 | | - **kwargs: Any, |
43 | | - ) -> bool: |
44 | | - return not await cls.allows(name, actor) |
45 | | - |
46 | | - @classmethod |
47 | | - async def any( |
48 | | - cls, |
49 | | - names: list[str], |
50 | | - actor: Actor, |
51 | | - *args: Any, |
52 | | - **kwargs: Any, |
53 | | - ) -> bool: |
54 | | - return any([await cls.allows(name, actor, args, kwargs) for name in names]) |
55 | | - |
56 | | - @classmethod |
57 | | - async def none( |
58 | | - cls, |
59 | | - names: list[str], |
| 32 | + self, |
60 | 33 | actor: Actor, |
61 | 34 | *args: Any, |
62 | 35 | **kwargs: Any, |
63 | 36 | ) -> bool: |
64 | | - return not await cls.any(names, actor, args, kwargs) |
| 37 | + return not await self.allows(actor) |
0 commit comments