home · contact · privacy
Put all formatting-choice logic, including former --raw, into -f/--format chooser.
authorPlom Heller <plom@plomlompom.com>
Sat, 1 Aug 2026 04:12:44 +0000 (06:12 +0200)
committerPlom Heller <plom@plomlompom.com>
Sat, 1 Aug 2026 04:12:44 +0000 (06:12 +0200)
bricksplom.py

index 85acfa87978c33dab2630f800b090e7c9a80e745..167a87c1d5b9ae6f04df6b5aad839cb232eca391 100755 (executable)
@@ -9,7 +9,7 @@ from argparse import (
 from dataclasses import dataclass
 from os import environ
 from pathlib import Path
-from typing import Any, Callable, Optional, Self
+from typing import Callable, Optional, Self
 
 NAME_ENV_DIRNAME = 'BRICKSPLOM_DIR'
 NAME_ENV_LDRAW = 'PATH_LDRAW'
@@ -147,6 +147,18 @@ class Lookupable:
         'Default single-item display of self.'
         return str(self)
 
+    @classmethod
+    def formatters(
+            cls
+            ) -> dict[str, Callable[[Self], str]]:
+        'Available per-item string formatters.'
+        formatters = {
+            'default': lambda item: item.show()
+            }
+        if issubclass(cls, Textfiled):
+            formatters['raw'] = lambda item: item.raw()
+        return formatters
+
     @classmethod
     def matchers(
             cls
@@ -667,7 +679,8 @@ class BricksDb:
             path_ldraw: str,
             ldraw_modes: str
             ) -> None:
-        for name, cls in self.textfiled_tables().items():
+        for name, cls in [(name, cls) for name, cls in self.lookupables.items()
+                          if issubclass(cls, Textfiled)]:
             kwargs = {'db': self} if issubclass(cls, WithDb) else {}
             setattr(self, name, cls.from_textfile((path_tables, f'{name}.txt'),
                                                   **kwargs))
@@ -682,14 +695,6 @@ class BricksDb:
                     design.direct_attrs.ldraw = filename
         self._check_consistencies()
 
-    @classmethod
-    def textfiled_tables(
-            cls
-            ) -> dict[str, Any]:
-        'Subset of .lookupables of only Textfiled subclasses.'
-        return {key: value for (key, value) in cls.lookupables.items()
-                if issubclass(value, Textfiled)}
-
     @property
     def boxes(
             self
@@ -803,18 +808,19 @@ class BricksDb:
             self,
             table_name: str,
             item_id: str,
-            show_raw: bool,
+            formatter: str,
             match_by: str,
             sort_by: str
             ) -> str:
         'Return result of inquiry on table of table_name.'
         assert table_name in self.lookupables
-        assert (not show_raw) or table_name in self.textfiled_tables()
         cls = self.lookupables[table_name]
-        if match_by == '?':
-            return CHAR_NEWLINE.join(cls.matchers().keys())
-        if sort_by == '?':
-            return CHAR_NEWLINE.join(cls.sorters().keys())
+        for argument, keys in [(arg, m().keys())
+                               for arg, m in ((match_by, cls.matchers),
+                                              (sort_by, cls.sorters),
+                                              (formatter, cls.formatters))]:
+            if argument == '?':
+                return CHAR_NEWLINE.join(keys)
         table = getattr(self, table_name)
         if item_id:
             match_by = PARAM_Q_ID + item_id
@@ -829,9 +835,7 @@ class BricksDb:
             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:
-            return items[0].show()
-        return CHAR_NEWLINE.join([item.raw() if show_raw else str(item)
+        return CHAR_NEWLINE.join([cls.formatters()[formatter](item)
                                   for item in items])
 
 
@@ -859,29 +863,25 @@ def main(
                    choices=choices, type=complete, metavar='TABLE', help=msg)
         parser = ArgumentParser()
         add_abbreviable_table_arg()
-        hint_sortmatch = 'use "?" to see what be available for chosen table'
-        hint_raw = ('only available for tables: '
-                    + ', '.join(BricksDb.textfiled_tables().keys()))
+        hint_qmark = 'use "?" to see what be available for chosen table'
         hint_ldraw = 'allowed: ' + ', '.join(sorted(list(LDRAW_MODES)))
         parser.add_argument(
                 'item_id',
                 nargs='?', metavar='ITEM_ID')
+        parser.add_argument(
+                '-f', '--format',
+                action='store', help=hint_qmark, default='default')
         parser.add_argument(
                 '-m', '--match-by',
-                action='store', help=hint_sortmatch)
+                action='store', help=hint_qmark)
         parser.add_argument(
                 '-s', '--sort-by',
-                action='store', help=hint_sortmatch, default=TOK_SORT_ID)
+                action='store', help=hint_qmark, default=TOK_SORT_ID)
         action_ldraw = parser.add_argument(
                 '-l', '--ldraw',
                 action='store', default='',
                 help=f'comma-separated; {hint_ldraw}')
-        action_raw = parser.add_argument(
-                '-r', '--raw',
-                action='store_true', help=f'NB: {hint_raw}')
         args = parser.parse_args()
-        if args.table not in BricksDb.textfiled_tables() and args.raw:
-            parser.error(str(ArgumentError(action_raw, hint_raw)))
         for _ in [m for m in args.ldraw.split(CHAR_SEP_LDRAW_MODES)
                   if m and m not in LDRAW_MODES]:
             parser.error(str(ArgumentError(action_ldraw, hint_ldraw)))
@@ -895,7 +895,7 @@ def main(
         db.lookup(
             table_name=args.table,
             item_id=args.item_id,
-            show_raw=args.raw,
+            formatter=args.format,
             match_by=args.match_by,
             sort_by=args.sort_by
         ).rstrip())