wip render repo

This commit is contained in:
Pascal Engélibert 2026-03-29 12:00:57 +02:00
commit 145e3c592e
6 changed files with 190 additions and 50 deletions

View file

@ -1,3 +1,9 @@
use std::{
collections::{BTreeMap, BTreeSet, HashMap, btree_map, btree_set},
iter::Peekable,
};
use log::warn;
use trillium_askama::Template;
#[derive(Template)]
@ -8,4 +14,88 @@ pub struct Home {}
#[template(path = "repo.html")]
pub struct Repo {
pub content: String,
pub entries: BTreeSet<Entry>,
}
#[derive(Template)]
#[template(
source = r#"
{% match self %}
{% when Entry::Directory(dir) %}
<li class="tree-dir">
<details>
<summary><span class="filename">{{ dir.name|escape }}</span></summary>
<ul class="tree">
{% for entry in dir.entries.values() %}
{{ entry.render()? }}
{% endfor %}
</ul>
</details>
</li>
{% when Entry::File(file) %}
<li class="tree-file"><span class="filename">{{ file.name|escape }}</span></li>
{% endmatch %}
"#,
ext = "html",
escape = "none"
)]
pub enum Entry {
Directory(Directory),
File(File),
}
pub struct File {
name: String,
path: String,
}
#[derive(Default)]
pub struct Directory {
name: String,
path: String,
entries: BTreeMap<String, Entry>,
}
impl Entry {
fn name(&self) -> &str {
match self {
Entry::Directory(dir) => &dir.name,
Entry::File(file) => &file.name,
}
}
}
impl PartialEq<Entry> for Entry {
fn eq(&self, other: &Entry) -> bool {
self.name() == other.name()
}
}
impl PartialOrd<Entry> for Entry {
fn partial_cmp(&self, other: &Entry) -> Option<std::cmp::Ordering> {
self.name().partial_cmp(other.name())
}
}
impl Directory {
pub fn insert<'a>(&mut self, entry: Entry, mut path: Peekable<impl Iterator<Item = &'a str>>) {
let Some(next_path_level) = path.next() else {
warn!("Cannot insert entry: no more path");
return;
};
if path.peek().is_some() {
if let Some(parent) = self.entries.get_mut(next_path_level) {
match parent {
Entry::Directory(dir) => dir.insert(entry, path),
Entry::File(_file) => {
warn!("Cannot insert entry: file");
}
}
} else {
warn!("Cannot insert entry: not found");
}
} else {
self.entries.insert(entry.name().to_string(), entry);
}
}
}