1"""String dispatch class to match regexps and dispatch commands.
2"""
3
4# Stdlib imports
5import re
6
7# Our own modules
8from IPython.core.hooks import CommandChainDispatcher
9from typing import Callable
10
11# Code begins
12class StrDispatch:
13 """Dispatch (lookup) a set of strings / regexps for match.
14
15 Example:
16
17 >>> dis = StrDispatch()
18 >>> dis.add_s('hei',34, priority = 4)
19 >>> dis.add_s('hei',123, priority = 2)
20 >>> dis.add_re('h.i', 686)
21 >>> print(list(dis.flat_matches('hei')))
22 [123, 34, 686]
23 """
24
25 def __init__(self):
26 self.strs = {}
27 self.regexs = {}
28
29 def add_s(self, s: str, obj: Callable, priority: int= 0 ):
30 """ Adds a target 'string' for dispatching """
31
32 chain = self.strs.get(s, CommandChainDispatcher())
33 chain.add(obj,priority)
34 self.strs[s] = chain
35
36 def add_re(self, regex, obj, priority= 0 ):
37 """ Adds a target regexp for dispatching """
38
39 chain = self.regexs.get(regex, CommandChainDispatcher())
40 chain.add(obj,priority)
41 self.regexs[regex] = chain
42
43 def dispatch(self, key):
44 """ Get a seq of Commandchain objects that match key """
45 if key in self.strs:
46 yield self.strs[key]
47
48 for r, obj in self.regexs.items():
49 if re.match(r, key):
50 yield obj
51 else:
52 # print("nomatch",key) # dbg
53 pass
54
55 def __repr__(self):
56 return "<Strdispatch %s, %s>" % (self.strs, self.regexs)
57
58 def s_matches(self, key):
59 if key not in self.strs:
60 return
61 for el in self.strs[key]:
62 yield el[1]
63
64 def flat_matches(self, key):
65 """ Yield all 'value' targets, without priority """
66 for val in self.dispatch(key):
67 for el in val:
68 yield el[1] # only value, no priority
69 return