1from __future__ import annotations
2
3from typing import List, Optional, Sequence, Tuple
4
5from .. import frames
6from ..typing import ExtensionName, ExtensionParameter
7
8
9__all__ = ["Extension", "ClientExtensionFactory", "ServerExtensionFactory"]
10
11
12class Extension:
13    """
14    Base class for extensions.
15
16    """
17
18    name: ExtensionName
19    """Extension identifier."""
20
21    def decode(
22        self,
23        frame: frames.Frame,
24        *,
25        max_size: Optional[int] = None,
26    ) -> frames.Frame:
27        """
28        Decode an incoming frame.
29
30        Args:
31            frame (Frame): incoming frame.
32            max_size: maximum payload size in bytes.
33
34        Returns:
35            Frame: Decoded frame.
36
37        Raises:
38            PayloadTooBig: if decoding the payload exceeds ``max_size``.
39
40        """
41
42    def encode(self, frame: frames.Frame) -> frames.Frame:
43        """
44        Encode an outgoing frame.
45
46        Args:
47            frame (Frame): outgoing frame.
48
49        Returns:
50            Frame: Encoded frame.
51
52        """
53
54
55class ClientExtensionFactory:
56    """
57    Base class for client-side extension factories.
58
59    """
60
61    name: ExtensionName
62    """Extension identifier."""
63
64    def get_request_params(self) -> List[ExtensionParameter]:
65        """
66        Build parameters to send to the server for this extension.
67
68        Returns:
69            List[ExtensionParameter]: Parameters to send to the server.
70
71        """
72
73    def process_response_params(
74        self,
75        params: Sequence[ExtensionParameter],
76        accepted_extensions: Sequence[Extension],
77    ) -> Extension:
78        """
79        Process parameters received from the server.
80
81        Args:
82            params (Sequence[ExtensionParameter]): parameters received from
83                the server for this extension.
84            accepted_extensions (Sequence[Extension]): list of previously
85                accepted extensions.
86
87        Returns:
88            Extension: An extension instance.
89
90        Raises:
91            NegotiationError: if parameters aren't acceptable.
92
93        """
94
95
96class ServerExtensionFactory:
97    """
98    Base class for server-side extension factories.
99
100    """
101
102    name: ExtensionName
103    """Extension identifier."""
104
105    def process_request_params(
106        self,
107        params: Sequence[ExtensionParameter],
108        accepted_extensions: Sequence[Extension],
109    ) -> Tuple[List[ExtensionParameter], Extension]:
110        """
111        Process parameters received from the client.
112
113        Args:
114            params (Sequence[ExtensionParameter]): parameters received from
115                the client for this extension.
116            accepted_extensions (Sequence[Extension]): list of previously
117                accepted extensions.
118
119        Returns:
120            Tuple[List[ExtensionParameter], Extension]: To accept the offer,
121            parameters to send to the client for this extension and an
122            extension instance.
123
124        Raises:
125            NegotiationError: to reject the offer, if parameters received from
126                the client aren't acceptable.
127
128        """
129