from collections.abc import Iterator from dataclasses import dataclass, field from typing import Callable, ClassVar, Self, final, override from docker_compose.cfg.org_yaml import OrgDataYaml from docker_compose.cfg.record import Record, RecordCls, RecordName @final @dataclass(frozen=True, slots=True) class OrgVal(RecordCls[str]): old: ClassVar[RecordName] = RecordName("org") @final @dataclass(frozen=True, slots=True) class Org: val: str replace: OrgVal = field(init=False) def __post_init__(self) -> None: setter = super(Org, self).__setattr__ setter("replace", OrgVal(self.val)) @final @dataclass(frozen=True, slots=True) class AppVal(RecordCls[str]): old: ClassVar[RecordName] = RecordName("name") @final @dataclass(frozen=True, slots=True) class App: val: str replace: AppVal = field(init=False) def __post_init__(self) -> None: setter = super(App, self).__setattr__ setter("replace", AppVal(self.val)) @final @dataclass(frozen=True, slots=True) class UrlValNew: val: str | None @override def __str__(self) -> str: if not self.val: return "" return ".".join((self.val, "ccamper7", "net")) @final @dataclass(frozen=True, slots=True) class UrlVal(RecordCls[UrlValNew]): old = RecordName("url") @final @dataclass(frozen=True, slots=True) class Url: val: str | None replace: UrlVal = field(init=False) def __post_init__(self) -> None: setter = super(Url, self).__setattr__ setter("replace", UrlVal(UrlValNew(self.val))) @final @dataclass(frozen=True, slots=True) class OrgData: org_app = Record[RecordName, str]( RecordName(f"{OrgVal.old.val}_{AppVal.old.val}"), f"{OrgVal.old!s}_{AppVal.old!s}", ) app: App org: Org url: Url @classmethod def from_dict(cls, app: str, org: str, data: OrgDataYaml) -> Self: return cls( App(app), Org(org), Url(data.get("url")), ) @property def render_funcs(self) -> Iterator[Callable[[str], str]]: yield self.app.replace yield self.org.replace yield self.url.replace @property def pre_render_funcs(self) -> Iterator[Callable[[str], str]]: yield self.org_app # def render_yaml(self, yaml: str) -> str: # for func in self.render_funcs: # yaml = func(yaml) # return yaml