|
1 | | -use std::cell::Cell; |
2 | | - |
3 | 1 | use crate::cache::Key as CacheKey; |
4 | 2 | use crate::env; |
5 | 3 | use crate::highlight::Html; |
@@ -33,75 +31,78 @@ impl From<crate::Error> for ErrorResponse<'_> { |
33 | 31 |
|
34 | 32 | /// Index page displaying a form for paste insertion and a selection box for languages. |
35 | 33 | #[derive(Template)] |
36 | | -#[template(path = "index.html")] |
| 34 | +#[template(path = "index.html", print="code")] |
37 | 35 | pub struct Index<'a> { |
38 | 36 | meta: &'a env::Metadata<'a>, |
39 | 37 | base_path: &'static env::BasePath, |
40 | | - max_expiry: Option<u32>, |
41 | | - |
42 | | - /// SAFETY: calls in the template are always sequential |
43 | | - default_has_been_written: Cell<bool>, |
| 38 | + max_expiration: Option<u32>, |
44 | 39 | } |
45 | 40 |
|
46 | 41 | impl<'a> Default for Index<'a> { |
47 | 42 | fn default() -> Self { |
48 | 43 | Self { |
49 | 44 | meta: env::metadata(), |
50 | 45 | base_path: env::base_path(), |
51 | | - max_expiry: env::max_paste_expiry(), |
52 | | - default_has_been_written: Cell::new(false), |
| 46 | + // exception should already have been handled in main |
| 47 | + max_expiration: env::max_paste_expiration().unwrap(), |
53 | 48 | } |
54 | 49 | } |
55 | 50 | } |
56 | 51 |
|
57 | | -#[derive(Debug)] |
58 | | -enum Expiry<'a> { |
59 | | - Special(&'a str), |
| 52 | +#[derive(Debug, Clone, Copy, Eq, PartialEq)] |
| 53 | +enum Expiration { |
| 54 | + None, |
| 55 | + Burn, |
60 | 56 | Time(u32), |
61 | 57 | } |
62 | 58 |
|
63 | | -impl<'a> Expiry<'a> { |
64 | | - fn as_str(&self) -> String { |
| 59 | +impl std::fmt::Display for Expiration { |
| 60 | + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
65 | 61 | match self { |
66 | | - Expiry::Special(s) => s.to_string(), |
67 | | - Expiry::Time(u) => u.to_string(), |
| 62 | + Expiration::None => write!(f, ""), |
| 63 | + Expiration::Burn => write!(f, "burn"), |
| 64 | + Expiration::Time(t) => write!(f, "{}", t), |
68 | 65 | } |
69 | 66 | } |
70 | 67 | } |
71 | 68 |
|
72 | | -impl<'a> Index<'a> { |
73 | | - fn expiry(&self, name: &str, time: Expiry<'a>) -> String { |
74 | | - let sel_string = if self.default_has_been_written.get() { |
75 | | - "" |
76 | | - } else { |
77 | | - r#" selected"# |
78 | | - }; |
| 69 | +const EXPIRATION_OPTIONS: [(&'static str, Expiration); 8] = [ |
| 70 | + ("never", Expiration::None), |
| 71 | + ("10 minutes", Expiration::Time(600)), |
| 72 | + ("1 hour", Expiration::Time(3600)), |
| 73 | + ("1 day", Expiration::Time(86400)), |
| 74 | + ("1 week", Expiration::Time(604800)), |
| 75 | + ("1 month", Expiration::Time(2592000)), |
| 76 | + ("1 year", Expiration::Time(31536000)), |
| 77 | + ("🔥 after reading", Expiration::Burn), |
| 78 | +]; |
79 | 79 |
|
80 | | - match self.max_expiry { |
81 | | - Some(exp) => { |
82 | | - match time { |
83 | | - // never emit an never expire with a limit |
84 | | - Expiry::Special("") => String::new(), |
85 | | - Expiry::Special("burn") => { |
86 | | - self.default_has_been_written.set(true); |
87 | | - format!(r#"<option{} value="burn">{}</option>"#, sel_string, name) |
88 | | - } |
89 | | - Expiry::Special(_) => String::new(), |
90 | | - Expiry::Time(t) if t > exp => String::new(), |
91 | | - Expiry::Time(t) => { |
92 | | - self.default_has_been_written.set(true); |
93 | | - format!(r#"<option{} value="{}">{}</option>"#, sel_string, t, name) |
94 | | - } |
| 80 | +impl<'a> Index<'a> { |
| 81 | + fn expiry_options(&self) -> String { |
| 82 | + let mut option_set = String::new(); |
| 83 | + let mut wrote_first = false; |
| 84 | + |
| 85 | + option_set.push('\n'); |
| 86 | + |
| 87 | + for (opt_name, opt_val) in EXPIRATION_OPTIONS { |
| 88 | + if self.max_expiration.is_none() |
| 89 | + || opt_val == Expiration::Burn |
| 90 | + || matches!((self.max_expiration, opt_val), (Some(exp), Expiration::Time(time)) if time <= exp) |
| 91 | + { |
| 92 | + option_set.push_str("<option"); |
| 93 | + if !wrote_first { |
| 94 | + option_set.push_str(" selected"); |
| 95 | + wrote_first = true; |
95 | 96 | } |
96 | | - } |
97 | | - None => { |
98 | | - self.default_has_been_written.set(true); |
99 | | - format!( |
100 | | - r#"<option{} value="{}">{}</option>"#, |
101 | | - sel_string, time, name |
102 | | - ) |
| 97 | + option_set.push_str(" value=\""); |
| 98 | + option_set.push_str(opt_val.to_string().as_ref()); |
| 99 | + option_set.push_str("\">"); |
| 100 | + option_set.push_str(opt_name); |
| 101 | + option_set.push_str("</option>\n"); |
103 | 102 | } |
104 | 103 | } |
| 104 | + |
| 105 | + option_set |
105 | 106 | } |
106 | 107 | } |
107 | 108 |
|
|
0 commit comments