uhhhhhhhhhhhhhhhhhhhhhhhh

This commit is contained in:
lda
2025-12-03 11:13:26 +07:00 Unverified
parent 2cb65d7ee6
commit cfba08c47a
2 changed files with 150 additions and 54 deletions
+122 -45
View File
@@ -4,7 +4,9 @@ from abc import ABC, abstractmethod
from collections.abc import Iterable from collections.abc import Iterable
from functools import wraps from functools import wraps
from pathlib import Path from pathlib import Path
from typing import Callable from pprint import pprint
from typing import Callable, TypedDict, overload
root = Path(__file__).parent.parent root = Path(__file__).parent.parent
static = root / "static" static = root / "static"
@@ -45,12 +47,16 @@ class RsAsset(ABC):
class RsAssetFile(RsAsset): class RsAssetFile(RsAsset):
def __init__(self, path: Path): def __init__(self, path: Path, name: str | None = None):
self.path = path self.path = path
if name is None:
self.name = sanitize(self.path.name).upper()
else:
self.name = name
def apply_template(self, template): def _apply_template(self, template):
return template.format( return template.format(
const_name=sanitize(self.path.name).upper(), const_name=self.name,
relative_path=self.path.relative_to(src, walk_up=True).as_posix(), relative_path=self.path.relative_to(src, walk_up=True).as_posix(),
) )
@@ -59,45 +65,46 @@ class RsAssetFile(RsAsset):
macroed_template = 'file {const_name} "{relative_path}"' macroed_template = 'file {const_name} "{relative_path}"'
def plain(self): def plain(self):
return self.apply_template(self.plain_template) return self._apply_template(self.plain_template)
def macroed(self): def macroed(self):
return self.apply_template(self.macroed_template) return self._apply_template(self.macroed_template)
class RsAssetModule(RsAsset): class RsAssetModule(RsAsset):
def __init__(self, path: Path, body_only: bool = False): def __init__(self, path: Path, name: str | None = None):
self.path = path self.path = path
self.full = not body_only if name is None:
self.name = sanitize(self.path.name).lower()
else:
self.name = name
plain_template = "pub mod {sanitized_name} {{\n{indented_body}\n}}" plain_template = "pub mod {sanitized_name} {{\n{indented_body}\n}}"
macroed_template = "folder {sanitized_name} {{\n{indented_body}\n}}" macroed_template = "folder {sanitized_name} {{\n{indented_body}\n}}"
sibling = "\n"
def plain(self): def plain(self):
return self.apply_template(self.plain_template, lambda it: it.plain()) return self._apply_template(self.plain_template, lambda it: it.plain())
def macroed(self): def macroed(self):
return self.apply_template(self.macroed_template, lambda it: it.macroed()) return self._apply_template(self.macroed_template, lambda it: it.macroed())
def apply_template(self, template: str, renderer: Callable[[RsAsset], str]): def _apply_template(self, template: str, renderer: Callable[[RsAsset], str]):
body = self.process_body(renderer) body = self._process_body(self.path, renderer)
if not self.full:
return body
return template.format( return template.format(
sanitized_name=sanitize(self.path.name).lower(), sanitized_name=self.name,
indented_body=indent(body, 4), indented_body=indent(body, 4),
) )
def process_body(self, renderer: Callable[[RsAsset], str]): @staticmethod
body = self.iterate_assets() def _process_body(path: Path, renderer: Callable[[RsAsset], str]):
return self.sibling.join(map(renderer, body)) body = RsAssetModule.iterate_assets(path)
return "\n".join(map(renderer, body))
def iterate_assets(self) -> Iterable[RsAsset]: @staticmethod
def iterate_assets(path: Path) -> "Iterable[RsAssetFile | RsAssetModule]":
subs = [] subs = []
for f in self.path.iterdir(): for f in path.iterdir():
if f.is_file(): if f.is_file():
yield RsAssetFile(f) yield RsAssetFile(f)
elif f.is_dir(): elif f.is_dir():
@@ -113,12 +120,12 @@ def render_pain(ass: RsAsset) -> str:
whats the point then. unless there is a `Intermediate Representation` whats the point then. whats the point then. unless there is a `Intermediate Representation` whats the point then.
""" """
match ass: match ass:
case RsAssetFile() as file:
return file.apply_template(file.plain_template)
case RsAssetModule() as folder:
return folder.apply_template(folder.plain_template, render_pain)
case RsAssetRoot() as r: case RsAssetRoot() as r:
return r.plain() return r.plain()
case RsAssetModule() as folder:
return folder.plain()
case RsAssetFile() as file:
return file.plain()
case _: case _:
raise TypeError("who are you?") raise TypeError("who are you?")
@@ -128,12 +135,58 @@ def render_macro(ass: RsAsset) -> str:
ts is ridiculous ts is ridiculous
""" """
match ass: match ass:
case RsAssetFile() as file:
return file.apply_template(file.macroed_template)
case RsAssetModule() as folder:
return folder.apply_template(folder.macroed_template, render_macro)
case RsAssetRoot() as r: case RsAssetRoot() as r:
return r.macroed() return r.macroed()
case RsAssetModule() as folder:
return folder.macroed()
case RsAssetFile() as file:
return file.macroed()
case _:
raise TypeError("who are you?")
class RsAssetModule2(TypedDict):
name: str
path: Path
children: "list[RsAssetModule2 | RsAssetFile2]"
class RsAssetFile2(TypedDict):
name: str
path: Path
@overload
def dictionary(im: "RsAssetRoot") -> RsAssetModule2: ...
@overload
def dictionary(im: RsAssetModule) -> RsAssetModule2: ...
@overload
def dictionary(im: RsAssetFile) -> RsAssetFile2: ...
@overload
def dictionary(im: RsAssetFile | RsAssetModule) -> RsAssetFile2 | RsAssetModule2: ...
def dictionary(im: RsAsset) -> RsAssetModule2 | RsAssetFile2:
match im:
case RsAssetRoot() as r:
return RsAssetModule2(
name="ROOT",
path=r.path,
children=list(map(dictionary, RsAssetModule.iterate_assets(r.path))),
)
case RsAssetModule() as folder:
return RsAssetModule2(
name=sanitize(folder.path.name).lower(),
path=folder.path,
children=list(
map(dictionary, RsAssetModule.iterate_assets(folder.path))
),
)
case RsAssetFile() as file:
return RsAssetFile2(
name=sanitize(file.path.name).upper(),
path=file.path,
)
case _: case _:
raise TypeError("who are you?") raise TypeError("who are you?")
@@ -172,31 +225,55 @@ def announce_yourself(*pa, **pkw):
class RsAssetRoot(RsAsset): class RsAssetRoot(RsAsset):
def __init__(self, asset: Path) -> None: plain_template = """{header}
self.path = asset
@property {body}
def a(self): """
return RsAssetModule(self.path, True) macroed_template = """{header}
@announce_yourself("generating code macro style")
def macroed(self):
return f"""{header}
{lda_macro} {lda_macro}
hehe! {{ hehe! {{
{indent(self.a.macroed(), 4)} {indented_body}
}} }}
""" """
@announce_yourself("generating code plain ahh style") def __init__(self, asset_root: Path) -> None:
self.path = asset_root
self._w = RsAssetModule(asset_root)
def plain(self) -> str: def plain(self) -> str:
return f"""{header} body = RsAssetModule._process_body(self.path, lambda it: it.plain())
return self.plain_template.format(
header=header,
body=body,
)
{self.a.plain()} def macroed(self) -> str:
""" body = RsAssetModule._process_body(self.path, lambda it: it.macroed())
return self.macroed_template.format(
header=header,
lda_macro=lda_macro,
indented_body=indent(body, 4),
)
rs_code = RsAssetRoot(static).plain() asset_root = RsAssetRoot(static)
pprint(dictionary(asset_root))
def render_ir(node: RsAssetModule2 | RsAssetFile2) -> str:
"gemini 3 pro"
if "children" in node:
body = "\n".join(map(render_ir, node["children"])) # type: ignore[typeddict-item]
if node["name"] == "ROOT":
return f"{header}\n\n{body}\n"
return f"pub mod {node['name']} {{\n{indent(body, 4)}\n}}"
rel = node["path"].relative_to(src, walk_up=True).as_posix()
return f'pub const {node["name"]}: &str = include_str!("{rel}");'
rs_code = render_macro(asset_root)
# generate # generate
out_rs.write_text(rs_code, encoding="utf-8") out_rs.write_text(rs_code, encoding="utf-8")
+28 -9
View File
@@ -1,12 +1,31 @@
// generated with ./scripts/map_static.py // generated with ./scripts/map_static.py
pub const HOME_2_HTML: &str = include_str!("../static/home_2.html"); macro_rules! hehe {
pub mod home_2 { // Folder
pub const DOM_JS: &str = include_str!("../static/home_2/dom.js"); (folder $name:ident { $($children:tt)* } $($rest:tt)*) => {
pub const LEASES_JS: &str = include_str!("../static/home_2/leases.js"); pub mod $name {
pub const MAIN_JS: &str = include_str!("../static/home_2/main.js"); hehe!{$($children)*}
pub const STATUS_JS: &str = include_str!("../static/home_2/status.js"); }
pub const STYLES_CSS: &str = include_str!("../static/home_2/styles.css"); hehe!{$($rest)*}
pub const UTILS_JS: &str = include_str!("../static/home_2/utils.js"); };
pub const WAKE_JS: &str = include_str!("../static/home_2/wake.js"); // File
(file $name:ident $file:literal $($rest:tt)*) => {
pub const $name: &str = include_str!($file);
hehe!{$($rest)*}
};
// Base case
() => {};
}
hehe! {
file HOME_2_HTML "../static/home_2.html"
folder home_2 {
file DOM_JS "../static/home_2/dom.js"
file LEASES_JS "../static/home_2/leases.js"
file MAIN_JS "../static/home_2/main.js"
file STATUS_JS "../static/home_2/status.js"
file STYLES_CSS "../static/home_2/styles.css"
file UTILS_JS "../static/home_2/utils.js"
file WAKE_JS "../static/home_2/wake.js"
}
} }