summaryrefslogtreecommitdiffstats
path: root/front_end/src/not_found_page.rs
blob: f293c449d08ed3b8d18b3fcc705b9335983ab57f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use crate::templates;
use crate::Page;
use crate::Urler;
use render_readme::Renderer;
use std::io::Write;

pub struct NotFoundPage<'a> {
    markup: &'a Renderer,
    pub results: &'a [search_index::CrateFound],
    pub query: &'a str,
    pub item_name: &'a str,
}

impl NotFoundPage<'_> {
    pub fn new<'a>(query: &'a str, item_name: &'a str, results: &'a [search_index::CrateFound], markup: &'a Renderer) -> NotFoundPage<'a> {
        NotFoundPage { query, markup, results, item_name }
    }

    pub fn page(&self) -> Page {
        Page {
            title: "Crate not found".into(),
            description: Some("Error".into()),
            noindex: true,
            search_meta: true,
            critical_css_data: Some(include_str!("../../style/public/search.css")),
            ..Default::default()
        }
    }

    /// For color of the version
    ///
    /// It tries to guess which versions seem "unstable".
    ///
    /// TODO: Merge with the better version history analysis from the individual crate page.
    pub fn version_class(&self, ver: &str) -> &str {
        let v = semver::Version::parse(ver).expect("semver");
        match (v.major, v.minor, v.patch, v.is_prerelease()) {
            (1..=15, _, _, false) => "stable",
            (0, m, p, false) if m >= 2 && p >= 3 => "stable",
            (m, ..) if m >= 1 => "okay",
            (0, 1, p, _) if p >= 10 => "okay",
            (0, 3..=10, p, _) if p > 0 => "okay",
            _ => "unstable",
        }
    }

    /// Nicely rounded number of downloads
    ///
    /// To show that these numbers are just approximate.
    pub fn downloads(&self, num: u64) -> (String, &str) {
        match num {
            a @ 0..=99 => (format!("{}", a), ""),
            a @ 0..=500 => (format!("{}", a / 10 * 10), ""),
            a @ 0..=999 => (format!("{}", a / 50 * 50), ""),
            a @ 0..=9999 => (format!("{}.{}", a / 1000, a % 1000 / 100), "K"),
            a @ 0..=999_999 => (format!("{}", a / 1000), "K"),
            a => (format!("{}.{}", a / 1_000_000, a % 1_000_000 / 100_000), "M"),
        }
    }

    /// Used to render descriptions
    pub fn render_markdown_str(&self, s: &str) -> templates::Html<String> {
        templates::Html(self.markup.markdown_str(s, false, None))
    }
}

pub fn render_404_page(out: &mut dyn Write, query: &str, item_name: &str, results: &[search_index::CrateFound], markup: &Renderer) -> Result<(), failure::Error> {
    let urler = Urler::new(None);
    let page = NotFoundPage::new(query, item_name, results, markup);
    templates::not_found(out, &page, &urler)?;
    Ok(())
}