aboutsummaryrefslogblamecommitdiffstats
path: root/src/bbss/lists.py
blob: 5bcdddf05f21379c6208fccc2e89676ca8809f7d (plain) (tree)
1
2
3
4
5
6
7
8
9
                                 

                                                                    

               


                                                                                      
                  



                                    
                                          
         
                                                                                 

            


                       
                        
 

                                     
                                    

                                  
 







                                                   
 

                                  

              











                                                                         
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 line.startswith("#"):
      continue
    elif line.startswith("##"):
      comment_acc.append(line[2:].strip())
    else:
      acc.append(ctor(line, " ".join(comment_acc) if len(comment_acc) else None))
  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"]