aboutsummaryrefslogtreecommitdiffstats
path: root/src/bbss/lists.py
blob: 6fa757f8861ca1c4b81f92db2abce5c53ea8e854 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
from dataclasses import dataclass
from collections.abc import Iterable, Iterator, Sequence
from typing import Optional, overload, List, Callable, TypeVar, Self
import requests

T = TypeVar('T')
def parse_listfile(contents: str, ctor: Callable[[str, Optional[str]], T]) -> List[T]:
  acc = []
  comment_acc = []
  for line in contents.splitlines():
    if not len(line):
      continue
    elif line.startswith("##"):
      comment_acc.append(line[2:].strip())
    elif line.startswith("#"):
      continue
    else:
      acc.append(ctor(line, " ".join(comment_acc) if len(comment_acc) else None))
      comment_acc = []
  return acc

@dataclass(frozen=True)
class ListFileEntry:
  entry: str
  comment: Optional[str]

L = TypeVar('L', bound=ListFileEntry)
class BaseListFile(Sequence[L]):
  def __init__(self, contents: str):
    self._contents: str = contents
    self._entries: List[L] = []

  @overload
  def __getitem__(self, key: int) -> L:
    pass
  @overload
  def __getitem__(self, key: slice) -> Sequence[L]:
    pass
  def __getitem__(self, key):
    return self._entries[key]

  def __len__(self) -> int:
    return self._entries.__len__()

  @classmethod
  def from_url(cls, url: str) -> Optional[Self]:
    req = requests.get(url, stream = False)
    if not req.ok:
      return None
    return cls(req.text)

class ListFile(BaseListFile[ListFileEntry]):
  def __init__(self, contents: str):
    super().__init__(contents)
    self._entries = parse_listfile(contents, ListFileEntry)

__all__ = ["parse_listfile", "ListFileEntry", "BaseListFile", "ListFIle"]