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, } struct Readme { file_name: String, url: String, raw_url: String, presentation: Presentation, } #[handler] pub async fn handler( app: Data<&Arc>, Path(repo): Path, req: &Request, ) -> Result { 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, }, )?) }