diff --git a/Cargo.lock b/Cargo.lock index c3779ccc7..dc3bd36f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5006,9 +5006,9 @@ dependencies = [ [[package]] name = "rinja" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d3762e3740cdbf2fd2be465cc2c26d643ad17353cc2e0223d211c1b096118bd" +checksum = "5bf96e290b3578af4ca20699abca2b90d5aba9eeae4acd123fd83c8547165eb4" dependencies = [ "humansize", "itoa 1.0.11", @@ -5019,9 +5019,9 @@ dependencies = [ [[package]] name = "rinja_derive" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd01fd8e15e7d19c8b8052c1d428325131e02ff1633cdcf695190c2e56ab682c" +checksum = "2fa31df46c7a8c125cfe8ec5f0b1d2689b65d4652fd8de9bf0ac41d6e0ac68f3" dependencies = [ "basic-toml", "memchr", @@ -5031,18 +5031,20 @@ dependencies = [ "proc-macro2", "quote", "rinja_parser", + "rustc-hash", "serde", "syn 2.0.72", ] [[package]] name = "rinja_parser" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2f6bf7cef118c6de21206edf0b3f19f5ede60006be674a58ca21b6e003a1b57" +checksum = "4ee3ef25da2517861878f58ecbd7b8ba6bebd5634fe1b4421df20d100fb75745" dependencies = [ "memchr", "nom", + "serde", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 78daf7903..8296232e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -100,7 +100,7 @@ tempfile = "3.1.0" fn-error-context = "0.2.0" # Templating -rinja = "0.3" +rinja = "0.3.2" walkdir = "2" # Date and Time utilities diff --git a/src/utils/html.rs b/src/utils/html.rs index c84867e15..49243a01c 100644 --- a/src/utils/html.rs +++ b/src/utils/html.rs @@ -1,4 +1,4 @@ -use crate::web::page::templates::{Body, Head, Topbar, Vendored}; +use crate::web::page::templates::{Body, Head, Vendored}; use crate::web::rustdoc::RustdocPage; use lol_html::element; use lol_html::errors::RewritingError; @@ -19,9 +19,9 @@ pub(crate) fn rewrite_lol( use lol_html::{HtmlRewriter, MemorySettings, Settings}; let head_html = Head::new(data).render().unwrap(); - let vendored_html = Vendored::new(data).render().unwrap(); - let body_html = Body::new(data).render().unwrap(); - let topbar_html = Topbar::new(data).render().unwrap(); + let vendored_html = Vendored.render().unwrap(); + let body_html = Body.render().unwrap(); + let topbar_html = data.render().unwrap(); // Before: ... rustdoc content ... // After: diff --git a/src/web/build_details.rs b/src/web/build_details.rs index 4bfbe5718..d0fee0a58 100644 --- a/src/web/build_details.rs +++ b/src/web/build_details.rs @@ -2,7 +2,6 @@ use crate::{ db::types::BuildStatus, impl_axum_webpage, web::{ - crate_details::CrateDetails, error::{AxumNope, AxumResult}, extractors::{DbConnection, Path}, file::File, @@ -45,15 +44,6 @@ impl_axum_webpage! { BuildDetailsPage } // Used for template rendering. impl BuildDetailsPage { - pub(crate) fn krate(&self) -> Option<&CrateDetails> { - None - } - pub(crate) fn permalink_path(&self) -> &str { - "" - } - pub(crate) fn get_metadata(&self) -> Option<&MetaData> { - Some(&self.metadata) - } pub(crate) fn use_direct_platform_links(&self) -> bool { true } diff --git a/src/web/builds.rs b/src/web/builds.rs index 45a1b6e3a..c63ef98f2 100644 --- a/src/web/builds.rs +++ b/src/web/builds.rs @@ -9,7 +9,6 @@ use crate::{ impl_axum_webpage, utils::spawn_blocking, web::{ - crate_details::CrateDetails, error::AxumResult, extractors::{DbConnection, Path}, filters, match_version, MetaData, ReqVersion, @@ -55,15 +54,6 @@ struct BuildsPage { impl_axum_webpage! { BuildsPage } impl BuildsPage { - pub(crate) fn krate(&self) -> Option<&CrateDetails> { - None - } - pub(crate) fn permalink_path(&self) -> &str { - "" - } - pub(crate) fn get_metadata(&self) -> Option<&MetaData> { - Some(&self.metadata) - } pub(crate) fn use_direct_platform_links(&self) -> bool { true } diff --git a/src/web/crate_details.rs b/src/web/crate_details.rs index a6218dd9b..214c3eaf9 100644 --- a/src/web/crate_details.rs +++ b/src/web/crate_details.rs @@ -1,7 +1,6 @@ use super::{match_version, MetaData}; use crate::registry_api::OwnerKind; use crate::utils::{get_correct_docsrs_style_file, report_error}; -use crate::web::rustdoc::RustdocHtmlParams; use crate::{ db::types::BuildStatus, impl_axum_webpage, @@ -12,6 +11,7 @@ use crate::{ error::{AxumNope, AxumResult}, extractors::{DbConnection, Path}, page::templates::filters, + rustdoc::RustdocHtmlParams, MatchedRelease, ReqVersion, }, AsyncStorage, @@ -31,7 +31,6 @@ use serde_json::Value; use std::sync::Arc; // TODO: Add target name and versions - #[derive(Debug, Clone, PartialEq)] pub(crate) struct CrateDetails { pub(crate) name: String, @@ -415,34 +414,41 @@ pub(crate) async fn releases_for_crate( #[template(path = "crate/details.html")] #[derive(Debug, Clone, PartialEq)] struct CrateDetailsPage { - details: CrateDetails, + version: Version, + name: String, + owners: Vec<(String, String, OwnerKind)>, + metadata: MetaData, + documented_items: Option, + total_items: Option, + total_items_needing_examples: Option, + items_with_examples: Option, + homepage_url: Option, + documentation_url: Option, + repository_url: Option, + repository_metadata: Option, + dependencies: Option, + releases: Vec, + readme: Option, + build_status: BuildStatus, + rustdoc_status: Option, + is_library: Option, + last_successful_build: Option, + rustdoc: Option, // this is description_long in database csp_nonce: String, } -impl_axum_webpage! { - CrateDetailsPage, - cpu_intensive_rendering = true, -} - -// Used by templates. impl CrateDetailsPage { - pub(crate) fn krate(&self) -> Option<&CrateDetails> { - None - } - - pub(crate) fn permalink_path(&self) -> &str { - "" - } - - pub(crate) fn get_metadata(&self) -> Option<&MetaData> { - Some(&self.details.metadata) - } - + // Used by templates. pub(crate) fn use_direct_platform_links(&self) -> bool { true } } +impl_axum_webpage! { + CrateDetailsPage, + cpu_intensive_rendering = true, +} + #[derive(Deserialize, Clone, Debug)] pub(crate) struct CrateDetailHandlerParams { name: String, @@ -479,8 +485,51 @@ pub(crate) async fn crate_details_handler( Err(e) => warn!("error fetching readme: {:?}", &e), } + let CrateDetails { + version, + name, + owners, + metadata, + documented_items, + total_items, + total_items_needing_examples, + items_with_examples, + homepage_url, + documentation_url, + repository_url, + repository_metadata, + dependencies, + releases, + readme, + build_status, + rustdoc_status, + is_library, + last_successful_build, + rustdoc, + .. + } = details; + let mut res = CrateDetailsPage { - details, + version, + name, + owners, + metadata, + documented_items, + total_items, + total_items_needing_examples, + items_with_examples, + homepage_url, + documentation_url, + repository_url, + repository_metadata, + dependencies, + releases, + readme, + build_status, + rustdoc_status, + is_library, + last_successful_build, + rustdoc, csp_nonce: String::new(), } .into_response(); diff --git a/src/web/features.rs b/src/web/features.rs index db3e5be93..9182c175a 100644 --- a/src/web/features.rs +++ b/src/web/features.rs @@ -3,7 +3,6 @@ use crate::{ impl_axum_webpage, web::{ cache::CachePolicy, - crate_details::CrateDetails, error::{AxumNope, AxumResult}, extractors::{DbConnection, Path}, filters, @@ -113,15 +112,6 @@ impl_axum_webpage! { } impl FeaturesPage { - pub(crate) fn krate(&self) -> Option<&CrateDetails> { - None - } - pub(crate) fn permalink_path(&self) -> &str { - "" - } - pub(crate) fn get_metadata(&self) -> Option<&MetaData> { - Some(&self.metadata) - } pub(crate) fn use_direct_platform_links(&self) -> bool { true } diff --git a/src/web/mod.rs b/src/web/mod.rs index b0cc58de6..319dd9db7 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -731,12 +731,6 @@ pub(crate) struct AxumErrorPage { pub csp_nonce: String, } -impl AxumErrorPage { - pub(crate) fn get_metadata(&self) -> Option<&MetaData> { - None - } -} - impl_axum_webpage! { AxumErrorPage, status = |err| err.status, diff --git a/src/web/page/templates.rs b/src/web/page/templates.rs index f00cbe92c..b312160d2 100644 --- a/src/web/page/templates.rs +++ b/src/web/page/templates.rs @@ -1,45 +1,31 @@ use crate::error::Result; use crate::web::rustdoc::RustdocPage; -use crate::web::MetaData; use anyhow::Context; use rinja::Template; -use std::{fmt, ops::Deref, sync::Arc}; +use std::{fmt, sync::Arc}; use tracing::trace; -macro_rules! rustdoc_page { - ($name:ident, $path:literal $(, $meta:ident)?) => { - #[derive(Template)] - #[template(path = $path)] - pub struct $name<'a> { - inner: &'a RustdocPage, - } - - impl<'a> $name<'a> { - pub fn new(inner: &'a RustdocPage) -> Self { - Self { inner } - } - - $( - pub(crate) fn $meta(&self) -> Option<&MetaData> { - Some(&self.inner.metadata) - } - )? - } - - impl<'a> Deref for $name<'a> { - type Target = RustdocPage; +#[derive(Template)] +#[template(path = "rustdoc/head.html")] +pub struct Head<'a> { + rustdoc_css_file: Option<&'a str>, +} - fn deref(&self) -> &Self::Target { - self.inner - } +impl<'a> Head<'a> { + pub fn new(inner: &'a RustdocPage) -> Self { + Self { + rustdoc_css_file: inner.metadata.rustdoc_css_file.as_deref(), } - }; + } } -rustdoc_page!(Head, "rustdoc/head.html"); -rustdoc_page!(Vendored, "rustdoc/vendored.html"); -rustdoc_page!(Body, "rustdoc/body.html"); -rustdoc_page!(Topbar, "rustdoc/topbar.html", get_metadata); +#[derive(Template)] +#[template(path = "rustdoc/vendored.html")] +pub struct Vendored; + +#[derive(Template)] +#[template(path = "rustdoc/body.html")] +pub struct Body; /// Holds all data relevant to templating #[derive(Debug)] diff --git a/src/web/releases.rs b/src/web/releases.rs index 477a05c80..61c3fee1a 100644 --- a/src/web/releases.rs +++ b/src/web/releases.rs @@ -12,7 +12,7 @@ use crate::{ extractors::{DbConnection, Path}, match_version, page::templates::filters, - MetaData, ReqVersion, + ReqVersion, }, BuildQueue, Config, InstanceMetrics, }; @@ -312,12 +312,6 @@ impl_axum_webpage! { cache_policy = |_| CachePolicy::ShortInCdnAndBrowser, } -impl HomePage { - pub(crate) fn get_metadata(&self) -> Option<&MetaData> { - None - } -} - pub(crate) async fn home_page(mut conn: DbConnection) -> AxumResult { let recent_releases = get_releases(&mut conn, 1, RELEASES_IN_HOME, Order::ReleaseTime, true).await?; @@ -366,12 +360,6 @@ struct ViewReleases { impl_axum_webpage! { ViewReleases } -impl ViewReleases { - pub(crate) fn get_metadata(&self) -> Option<&MetaData> { - None - } -} - #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub(crate) enum ReleaseType { Recent, @@ -525,12 +513,6 @@ impl Default for Search { } } -impl Search { - pub(crate) fn get_metadata(&self) -> Option<&MetaData> { - None - } -} - async fn redirect_to_random_crate( config: Arc, metrics: Arc, @@ -739,12 +721,6 @@ struct ReleaseActivity { csp_nonce: String, } -impl ReleaseActivity { - pub(crate) fn get_metadata(&self) -> Option<&MetaData> { - None - } -} - impl_axum_webpage! { ReleaseActivity } pub(crate) async fn activity_handler(mut conn: DbConnection) -> AxumResult { @@ -814,12 +790,6 @@ struct BuildQueuePage { impl_axum_webpage! { BuildQueuePage } -impl BuildQueuePage { - pub(crate) fn get_metadata(&self) -> Option<&MetaData> { - None - } -} - pub(crate) async fn build_queue_handler( Extension(build_queue): Extension>, Extension(pool): Extension, diff --git a/src/web/rustdoc.rs b/src/web/rustdoc.rs index bb3d99c1a..308d93ef3 100644 --- a/src/web/rustdoc.rs +++ b/src/web/rustdoc.rs @@ -14,6 +14,7 @@ use crate::{ extractors::{DbConnection, Path}, file::File, match_version, + page::templates::filters, page::TemplateData, MetaData, ReqVersion, }, @@ -27,6 +28,7 @@ use axum::{ }; use lol_html::errors::RewritingError; use once_cell::sync::Lazy; +use rinja::Template; use semver::Version; use serde::Deserialize; use std::{ @@ -257,6 +259,8 @@ pub(crate) async fn rustdoc_redirector_handler( } } +#[derive(Template)] +#[template(path = "rustdoc/topbar.html")] #[derive(Debug, Clone)] pub struct RustdocPage { pub latest_path: String, @@ -313,16 +317,6 @@ impl RustdocPage { .into_response()) } - // Used for template rendering. - pub(crate) fn krate(&self) -> Option<&CrateDetails> { - Some(&self.krate) - } - - // Used for template rendering. - pub(crate) fn permalink_path(&self) -> &str { - &self.permalink_path - } - pub(crate) fn use_direct_platform_links(&self) -> bool { !self.latest_path.contains("/target-redirect/") } diff --git a/src/web/sitemap.rs b/src/web/sitemap.rs index 614521e72..ca74417c8 100644 --- a/src/web/sitemap.rs +++ b/src/web/sitemap.rs @@ -7,7 +7,7 @@ use crate::{ error::{AxumNope, AxumResult}, extractors::{DbConnection, Path}, page::templates::filters, - AxumErrorPage, MetaData, + AxumErrorPage, }, Config, }; @@ -122,12 +122,6 @@ struct AboutBuilds { csp_nonce: String, } -impl AboutBuilds { - pub(crate) fn get_metadata(&self) -> Option<&MetaData> { - None - } -} - impl_axum_webpage!(AboutBuilds); pub(crate) async fn about_builds_handler( @@ -158,12 +152,6 @@ macro_rules! about_page { } impl_axum_webpage! { $ty } - - impl $ty { - pub(crate) fn get_metadata(&self) -> Option<&MetaData> { - None - } - } }; } diff --git a/src/web/source.rs b/src/web/source.rs index c1cbb55f3..840532c18 100644 --- a/src/web/source.rs +++ b/src/web/source.rs @@ -4,8 +4,8 @@ use crate::{ impl_axum_webpage, storage::PathNotFoundError, web::{ - cache::CachePolicy, crate_details::CrateDetails, error::AxumNope, extractors::Path, - file::File as DbFile, filters, headers::CanonicalUrl, MetaData, ReqVersion, + cache::CachePolicy, error::AxumNope, extractors::Path, file::File as DbFile, filters, + headers::CanonicalUrl, MetaData, ReqVersion, }, AsyncStorage, }; @@ -171,15 +171,6 @@ impl_axum_webpage! { // Used in templates. impl SourcePage { - pub(crate) fn get_metadata(&self) -> Option<&MetaData> { - Some(&self.metadata) - } - pub(crate) fn permalink_path(&self) -> &str { - "" - } - pub(crate) fn krate(&self) -> Option<&CrateDetails> { - None - } pub(crate) fn use_direct_platform_links(&self) -> bool { true } diff --git a/templates/crate/build_details.html b/templates/crate/build_details.html index 88a0270f0..3ff9eb0a9 100644 --- a/templates/crate/build_details.html +++ b/templates/crate/build_details.html @@ -10,9 +10,7 @@ {%- endblock body_classes -%} {%- block topbar -%} - {%- set current_target = String::new() -%} {%- set latest_version = "" -%} - {%- set latest_path = "" -%} {%- set target = "" -%} {%- set inner_path = metadata.target_name_url() -%} {%- set is_latest_version = true -%} diff --git a/templates/crate/builds.html b/templates/crate/builds.html index 9a34e6d75..19dca05d8 100644 --- a/templates/crate/builds.html +++ b/templates/crate/builds.html @@ -14,9 +14,7 @@ {%- endblock body_classes -%} {%- block topbar -%} - {%- set current_target = String::new() -%} {%- set latest_version = "" -%} - {%- set latest_path = "" -%} {%- set target = "" -%} {%- set inner_path = metadata.target_name_url() -%} {%- set is_latest_version = true -%} diff --git a/templates/crate/details.html b/templates/crate/details.html index 4ccf1e88a..e24d8f348 100644 --- a/templates/crate/details.html +++ b/templates/crate/details.html @@ -2,18 +2,15 @@ {%- import "header/package_navigation.html" as navigation -%} {%- block title -%} - {% call macros::doc_title(name=details.name, version=details.version) %} + {% call macros::doc_title(name=name, version=version) %} {%- endblock title -%} {%- block meta -%} - + {%- endblock meta -%} {%- block topbar -%} - {%- set current_target = String::new() -%} - {%- set metadata = details.metadata -%} - {%- set latest_path = "" -%} - {%- set inner_path = details.metadata.target_name_url() -%} + {%- set inner_path = metadata.target_name_url() -%} {%- set is_latest_version = true -%} {%- set is_prerelease = false -%} {%- include "rustdoc/topbar.html" -%} @@ -21,7 +18,7 @@ {%- block header -%} {# Set the active tab to the `crate` tab #} - {% call navigation::package_navigation(metadata=details.metadata, active_tab="crate") %} + {% call navigation::package_navigation(metadata=metadata, active_tab="crate") %} {%- endblock header -%} {%- block body -%} @@ -30,14 +27,14 @@