|
14 | 14 | from characteristic import attributes |
15 | 15 |
|
16 | 16 | from ._base import Effect, guard, _Box, NoPerformerFoundError |
17 | | -from ._sync import NotSynchronousError |
| 17 | +from ._sync import NotSynchronousError, sync_performer |
18 | 18 | from ._intents import Constant, Error, Func, ParallelEffects |
19 | 19 |
|
20 | 20 | import six |
@@ -164,3 +164,70 @@ def resolve_stubs(dispatcher, effect): |
164 | 164 | break |
165 | 165 |
|
166 | 166 | return effect |
| 167 | + |
| 168 | + |
| 169 | +class EQDispatcher(object): |
| 170 | + """ |
| 171 | + An equality-based (constant) dispatcher. |
| 172 | +
|
| 173 | + This dispatcher looks up intents by equality and performs them by returning |
| 174 | + an associated constant value. |
| 175 | +
|
| 176 | + Users provide a mapping of intents to results, where the intents are |
| 177 | + matched against the intents being performed with a simple equality check |
| 178 | + (not a type check!). |
| 179 | +
|
| 180 | + e.g.:: |
| 181 | +
|
| 182 | + >>> sync_perform(EQDispatcher({MyIntent(1, 2): 'the-result'}), |
| 183 | + ... Effect(MyIntent(1, 2))) |
| 184 | + 'the-result' |
| 185 | +
|
| 186 | + assuming MyIntent supports ``__eq__`` by value. |
| 187 | + """ |
| 188 | + def __init__(self, mapping): |
| 189 | + """ |
| 190 | + :param mapping: Mapping of intents to results. |
| 191 | + """ |
| 192 | + self.mapping = mapping |
| 193 | + |
| 194 | + def __call__(self, intent): |
| 195 | + # Avoid hashing, because a lot of intents aren't hashable. |
| 196 | + for k, v in self.mapping.items(): |
| 197 | + if k == intent: |
| 198 | + return sync_performer(lambda d, i: v) |
| 199 | + |
| 200 | + |
| 201 | +class EQFDispatcher(object): |
| 202 | + """ |
| 203 | + An Equality-based function dispatcher. |
| 204 | +
|
| 205 | + This dispatcher looks up intents by equality and performs them by invoking |
| 206 | + an associated function. |
| 207 | +
|
| 208 | + Users provide a mapping of intents to functions, where the intents are |
| 209 | + matched against the intents being performed with a simple equality check |
| 210 | + (not a type check!). The functions in the mapping will be passed only the |
| 211 | + intent and are expected to return the result or raise an exception. |
| 212 | +
|
| 213 | + e.g.:: |
| 214 | +
|
| 215 | + >>> sync_perform( |
| 216 | + ... EQFDispatcher({ |
| 217 | + ... MyIntent(1, 2): lambda i: 'the-result'}), |
| 218 | + ... Effect(MyIntent(1, 2))) |
| 219 | + 'the-result' |
| 220 | +
|
| 221 | + assuming MyIntent supports ``__eq__`` by value. |
| 222 | + """ |
| 223 | + def __init__(self, mapping): |
| 224 | + """ |
| 225 | + :param mapping: Mapping of intents to results. |
| 226 | + """ |
| 227 | + self.mapping = mapping |
| 228 | + |
| 229 | + def __call__(self, intent): |
| 230 | + # Avoid hashing, because a lot of intents aren't hashable. |
| 231 | + for k, v in self.mapping.items(): |
| 232 | + if k == intent: |
| 233 | + return sync_performer(lambda d, i: v(i)) |
0 commit comments