CHAR_COLL_SEP_PAGE = '='
CHAR_COL_SOLID = '+'
CHAR_COL_TRANSPARENT = '-'
-CHAR_INQUIRY = '?'
+CHAR_Q_EQ_ID = ':'
+CHAR_Q_STUDS = 's'
+CHAR_Q_TEXT = '?'
BOX_PREFIX = 'box:'
PieceListing = tuple[int, str, str]
id_: str
@classmethod
- def indent_id(cls, id_: str) -> str:
+ def indent_id(
+ cls,
+ id_: str
+ ) -> str:
'id_ indented by value of cls._id_indent.'
return (max(0, cls._id_indent - len(id_)) * ' ') + id_
- def id_indented(self) -> str:
- 'self.id_ indented by value of self._id_indent.'
- return self.indent_id(self.id_)
-
- def searchable(
+ def id_indented(
self
) -> str:
- 'String analyzed by "?" full-text searches.'
- return str(self)
+ 'self.id_ indented by value of self._id_indent.'
+ return self.indent_id(self.id_)
def show(
self
'Default single-item display of self.'
return str(self)
+ @property
+ def matchers(
+ self
+ ) -> dict[str, Callable[[str], bool]]:
+ 'Available lookup matchers.'
+ return {
+ CHAR_Q_TEXT: lambda q_body: q_body.upper() in str(self).upper()
+ }
+
+ def match(
+ self,
+ query_char: str,
+ query_body: str
+ ) -> bool:
+ 'Return if self matches query.'
+ assert query_char in self.matchers
+ return self.matchers[query_char](query_body)
+
class Color(Textfiled, Lookupable):
'Color incl. solidness/transparency field.'
'Own .id_ plus (sorted) .alternate_ids.'
return tuple([self.id_] + sorted(list(self.alternate_ids)))
+ @property
+ 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 | {CHAR_Q_STUDS: q_studs}
+
@classmethod
def from_textfile(
cls,
) -> str:
return (f'{self.id_indented()} '
+ (f'={self.alternate_to.id_}' if self.alternate_to
- else ('_'
+ else (CHAR_DESIGN_DESC
+ ('?' if self._n_studs < 0 else str(self._n_studs))
+ f' {self._description}')))
) -> str:
return f'{self.id_} {self._is_in_str} {self.description}'
- def searchable(
+ @property
+ def matchers(
self
- ) -> str:
- return self.show()
+ ) -> dict[str, Callable[[str], bool]]:
+ return super().matchers | {
+ CHAR_Q_TEXT: lambda q_body: q_body.upper() in self.show().upper()
+ }
def _format_paginated(
self,
assert table_name in self.lookupable
maybe_dict = getattr(self, table_name)
table = maybe_dict if isinstance(maybe_dict, dict) else maybe_dict()
- if inquiry.startswith(CHAR_INQUIRY):
- return CHAR_NEWLINE.join(
- [(v.raw() if show_raw else str(v)) for
- v in sorted(table.values(),
- key=lambda v: f'{v.id_indented()}')
- if inquiry[1:].upper() in str(v.searchable()).upper()])
- if table_name == 'designs' and inquiry.startswith('s'):
- n_studs_str = inquiry[1:]
- assert n_studs_str.isdigit()
- return CHAR_NEWLINE.join(
- [(v.raw() if show_raw else str(v)) for
- v in sorted(table.values(),
- key=lambda v: f'{v.id_indented()}')
- if v.n_studs == int(n_studs_str)])
- item = table[inquiry]
- return item.raw() if show_raw else item.show()
+ query_char, query_body = inquiry[0], inquiry[1:]
+ if query_char == CHAR_Q_EQ_ID:
+ item = table[query_body]
+ return item.raw() if show_raw else item.show()
+ return CHAR_NEWLINE.join(
+ [(r.raw() if show_raw else str(r)) for
+ r in sorted(table.values(), key=lambda r: r.id_indented())
+ if r.match(query_char, query_body)])
def main(
db = BricksDb(environ.get(NAME_ENV_DIRNAME, '.'))
parser = ArgumentParser()
add_abbrev_choices_arg(parser, 'table', set(db.lookupable))
- parser.add_argument('inquiry', nargs='?', default=CHAR_INQUIRY)
+ parser.add_argument('inquiry', nargs='?', default=CHAR_Q_TEXT)
parser.add_argument('--raw', action='store_true')
args = parser.parse_args()
print(db.lookup(args.table, args.inquiry, args.raw).rstrip())