from abc import ABCMeta, abstractmethod from dataclasses import dataclass from pathlib import Path from typing import final, override @dataclass(frozen=True, slots=True) class RecordVal(metaclass=ABCMeta): @property @abstractmethod def str(self) -> str: pass @final @dataclass(frozen=True, slots=True) class Record[T: RecordVal]: name: str val: T def replace(self, string: str) -> str: return string.replace(self.replace_name, self.val.str) @property def replace_name(self) -> str: return self.get_replace_name(self.name) @staticmethod def get_replace_name(string: str) -> str: return f"${{_{string.upper()}}}" @final @dataclass(frozen=True, slots=True) class OrgVal(RecordVal): val: str | None @property @override def str(self) -> str: if self.val is None: return "personal" return self.val def is_valid(self) -> bool: return self.val is not None @final @dataclass(frozen=True, slots=True) class NameVal(RecordVal): val: str @property @override def str(self) -> str: return self.val @final @dataclass(frozen=True, slots=True) class DataDir(RecordVal): path: Path @property @override def str(self) -> str: return str(self.path) @final @dataclass(frozen=True, slots=True) class Url(RecordVal): sub_url: str | None @property @override def str(self) -> str: if self.sub_url is None: return "" return ".".join([self.sub_url, "ccamper7", "net"])