BOX_PREFIX = 'box:'
PARAM_Q_ID = 'id='
-PARAM_Q_STUDS = 'n_studs='
PARAM_Q_TEXT = 'text:'
-PARAMS_Q = (PARAM_Q_ID, PARAM_Q_STUDS, PARAM_Q_TEXT)
TOK_SORT_BOX = 'box'
TOK_SORT_ID = 'id'
-TOK_SORT_STUDS = 'n_studs'
BrickListing = tuple[int, str, str] # count, ID, comment
PageColumn = tuple[BrickListing, ...]
def matchers(
self
) -> dict[str, Callable[[str], bool]]:
- def q_studs(
- q_body
- ) -> bool:
- assert q_body.isdigit()
- return self.n_studs == int(q_body)
- return super().matchers | {PARAM_Q_STUDS: q_studs}
+ def attr_matcher(
+ attr_name: str
+ ) -> Callable[[str], bool]:
+ def match(
+ q_body: str
+ ) -> bool:
+ assert q_body.isdigit()
+ return getattr(self, attr_name) == int(q_body)
+ return match
+ return super().matchers | {
+ f'{attr_name}=': attr_matcher(attr_name)
+ for attr_name, attr_type in BrickDesignData.__annotations__.items()
+ if attr_type is int}
@property
def sorters(
self
) -> dict[str, Callable[['BricksDb', tuple[Self, ...]],
tuple[Self, ...]]]:
- return super().sorters | {
- TOK_SORT_BOX: self._by_box_sorter('design'),
- TOK_SORT_STUDS: lambda _, pre_sorted: tuple(
- sorted(pre_sorted, key=lambda item: item.n_studs))
- }
+ def attr_sorter(
+ attr_name: str,
+ ) -> Callable[[BricksDb, tuple[Self, ...]], tuple[Self, ...]]:
+ def f_sort(
+ _: BricksDb,
+ pre_sorted: tuple[Self, ...]
+ ) -> tuple[Self, ...]:
+ return tuple(sorted(pre_sorted,
+ key=lambda item: getattr(item, attr_name)))
+ return f_sort
+ return super().sorters\
+ | {TOK_SORT_BOX: self._by_box_sorter('design')}\
+ | {attr_name: attr_sorter(attr_name)
+ for attr_name in BrickDesignData.__annotations__}
@classmethod
def from_textfile(
items = tuple(table.values())
if items and sort_by:
items = items[0].sorters[sort_by](self, items)
- if match_by:
- candidates = [p for p in PARAMS_Q if match_by.startswith(p)]
- assert len(candidates) == 1
- p_key = candidates[0]
+ if items and match_by:
+ p_key = ''
+ for p_key in [p_key for p_key in items[0].matchers
+ if match_by.startswith(p_key)]:
+ break
+ assert p_key
p_val = match_by[len(p_key):]
items = tuple(item for item in items if item.match(p_key, p_val))
if len(items) == 1 and not show_raw: