repo.rs
raw
use std::sync::Arc;
use anyhow::Error;
use poem::{
IntoResponse, Request, Result, handler,
web::{Data, Path},
};
use sailfish::TemplateOnce;
use crate::{
App,
render::{Links, Presentation, View},
repos::Summary,
};
#[derive(TemplateOnce)]
#[template(path = "pages/repo.stpl.html")]
struct RepoPage {
summary: Summary,
clone_url: String,
browse_url: String,
readme: Option<Readme>,
}
struct Readme {
file_name: String,
url: String,
raw_url: String,
presentation: Presentation,
}
#[handler]
pub async fn handler(
app: Data<&Arc<App>>,
Path(repo): Path<String>,
req: &Request,
) -> Result<impl IntoResponse> {
let name = super::repo_name(&repo)?;
let lookup_name = name.clone();
let found = app
.blocking(move |store| {
let Some(repo) = store.open(&lookup_name)? else {
return Ok(None);
};
let readme = repo
.readme()?
.map(|file| {
let links = Links::for_document(&lookup_name, &file.path);
Ok::<_, Error>(Readme {
file_name: file.path.file_name().unwrap_or_default().to_owned(),
url: links.url(View::File, &file.path),
raw_url: links.url(View::Raw, &file.path),
presentation: Presentation::of(&repo, &file, &links)?,
})
})
.transpose()?;
Ok(Some((repo.summary(), readme)))
})
.await?;
let (summary, readme) = super::found(found)?;
let links = Links::for_document(&name, &Default::default());
let title = summary.name.to_string();
Ok(super::page(
&app,
title,
RepoPage {
clone_url: app.clone_url(req, &name),
browse_url: links.url(View::File, &Default::default()),
summary,
readme,
},
)?)
}