Skip to content

Commit eeaabd4

Browse files
committed
wip!
1 parent 23f2882 commit eeaabd4

File tree

11 files changed

+224
-331
lines changed

11 files changed

+224
-331
lines changed

src/env.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::time::Duration;
1010
pub struct Metadata<'a> {
1111
pub title: String,
1212
pub version: &'a str,
13-
pub highlight: &'a highlight::Data<'a>,
13+
pub highlight: &'a highlight::Data,
1414
}
1515

1616
pub const DEFAULT_HTTP_TIMEOUT: Duration = Duration::from_secs(5);

src/highlight.rs

Lines changed: 2 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
use crate::db::read::Entry;
2-
use crate::env;
32
use crate::errors::Error;
4-
use askama::Template;
53
use sha2::{Digest, Sha256};
64
use std::cmp::Ordering;
7-
use std::io::Cursor;
85
use std::sync::LazyLock;
9-
use syntect::highlighting::{Color, ThemeSet};
10-
use syntect::html::{css_for_theme_with_class_style, line_tokens_to_classed_spans, ClassStyle};
6+
use syntect::html::{line_tokens_to_classed_spans, ClassStyle};
117
use syntect::parsing::{ParseState, ScopeStack, SyntaxReference, SyntaxSet};
128
use syntect::util::LinesWithEndings;
13-
use two_face::theme::EmbeddedThemeName;
149

1510
const HIGHLIGHT_LINE_LENGTH_CUTOFF: usize = 2048;
1611

@@ -25,109 +20,10 @@ pub enum Theme {
2520
Solarized,
2621
}
2722

28-
// #[derive(Template)]
29-
// #[template(path = "style.css", escape = "none")]
30-
// struct StyleCss {
31-
// light_background: Color,
32-
// light_foreground: Color,
33-
// dark_background: Color,
34-
// dark_foreground: Color,
35-
// }
36-
3723
#[derive(Clone)]
3824
pub struct Html(String);
3925

40-
pub static LIGHT_THEME: LazyLock<syntect::highlighting::Theme> = LazyLock::new(|| {
41-
let theme_set = two_face::theme::extra();
42-
43-
match *env::THEME {
44-
Theme::Ayu => {
45-
let theme = include_str!("themes/ayu-light.tmTheme");
46-
ThemeSet::load_from_reader(&mut Cursor::new(theme)).expect("loading theme")
47-
}
48-
Theme::Base16Ocean => theme_set.get(EmbeddedThemeName::Base16OceanLight).clone(),
49-
Theme::Coldark => theme_set.get(EmbeddedThemeName::ColdarkCold).clone(),
50-
Theme::Gruvbox => theme_set.get(EmbeddedThemeName::GruvboxLight).clone(),
51-
Theme::Monokai => theme_set
52-
.get(EmbeddedThemeName::MonokaiExtendedLight)
53-
.clone(),
54-
Theme::Onehalf => theme_set.get(EmbeddedThemeName::OneHalfLight).clone(),
55-
Theme::Solarized => theme_set.get(EmbeddedThemeName::SolarizedLight).clone(),
56-
}
57-
});
58-
59-
pub static LIGHT_CSS: LazyLock<String> = LazyLock::new(|| {
60-
css_for_theme_with_class_style(&LIGHT_THEME, ClassStyle::Spaced).expect("generating CSS")
61-
});
62-
63-
pub static DARK_THEME: LazyLock<syntect::highlighting::Theme> = LazyLock::new(|| {
64-
let theme_set = two_face::theme::extra();
65-
66-
match *env::THEME {
67-
Theme::Ayu => {
68-
let theme = include_str!("themes/ayu-dark.tmTheme");
69-
ThemeSet::load_from_reader(&mut Cursor::new(theme)).expect("loading theme")
70-
}
71-
Theme::Base16Ocean => theme_set.get(EmbeddedThemeName::Base16OceanDark).clone(),
72-
Theme::Coldark => theme_set.get(EmbeddedThemeName::ColdarkDark).clone(),
73-
Theme::Gruvbox => theme_set.get(EmbeddedThemeName::GruvboxDark).clone(),
74-
Theme::Monokai => theme_set.get(EmbeddedThemeName::MonokaiExtended).clone(),
75-
Theme::Onehalf => theme_set.get(EmbeddedThemeName::OneHalfDark).clone(),
76-
Theme::Solarized => theme_set.get(EmbeddedThemeName::SolarizedDark).clone(),
77-
}
78-
});
79-
80-
pub static DARK_CSS: LazyLock<String> = LazyLock::new(|| {
81-
css_for_theme_with_class_style(&DARK_THEME, ClassStyle::Spaced).expect("generating CSS")
82-
});
83-
84-
trait ColorExt {
85-
fn new(r: u8, g: u8, b: u8, a: u8) -> Self;
86-
}
87-
88-
impl ColorExt for Color {
89-
fn new(r: u8, g: u8, b: u8, a: u8) -> Self {
90-
Self { r, g, b, a }
91-
}
92-
}
93-
94-
pub static STYLE_CSS: LazyLock<String> = LazyLock::new(|| {
95-
let light_foreground = LIGHT_THEME
96-
.settings
97-
.foreground
98-
.unwrap_or(Color::new(3, 3, 3, 100));
99-
100-
let light_background = LIGHT_THEME
101-
.settings
102-
.background
103-
.unwrap_or(Color::new(250, 250, 250, 100));
104-
105-
let dark_foreground = DARK_THEME
106-
.settings
107-
.foreground
108-
.unwrap_or(Color::new(230, 225, 207, 100));
109-
110-
let dark_background = DARK_THEME
111-
.settings
112-
.background
113-
.unwrap_or(Color::new(15, 20, 25, 100));
114-
115-
String::from("hello")
116-
//
117-
// let style = StyleCss {
118-
// light_background,
119-
// light_foreground,
120-
// dark_background,
121-
// dark_foreground,
122-
// };
123-
//
124-
// style.render().expect("rendering style css")
125-
});
126-
12726
pub static DATA: LazyLock<Data> = LazyLock::new(|| {
128-
let style = Hashed::new("style", "css", &STYLE_CSS);
129-
let index = Hashed::new("index", "js", include_str!("javascript/index.js"));
130-
let paste = Hashed::new("paste", "js", include_str!("javascript/paste.js"));
13127
let syntax_set = two_face::syntax::extra_newlines();
13228
let mut syntaxes = syntax_set.syntaxes().to_vec();
13329
syntaxes.sort_by(|a, b| {
@@ -138,9 +34,6 @@ pub static DATA: LazyLock<Data> = LazyLock::new(|| {
13834
});
13935

14036
Data {
141-
style,
142-
index,
143-
paste,
14437
syntax_set,
14538
syntaxes,
14639
}
@@ -152,10 +45,7 @@ pub struct Hashed<'a> {
15245
pub content: &'a str,
15346
}
15447

155-
pub struct Data<'a> {
156-
pub style: Hashed<'a>,
157-
pub index: Hashed<'a>,
158-
pub paste: Hashed<'a>,
48+
pub struct Data {
15949
pub syntax_set: SyntaxSet,
16050
pub syntaxes: Vec<SyntaxReference>,
16151
}

src/main.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@ use crate::cache::Cache;
33
use crate::db::Database;
44
use crate::errors::Error;
55
use axum::extract::{DefaultBodyLimit, FromRef, Request, State};
6-
use axum::http::{HeaderName, HeaderValue, StatusCode};
6+
use axum::http::{HeaderName, HeaderValue};
77
use axum::middleware::{from_fn, Next};
88
use axum::response::{IntoResponse, Response};
99
use axum::routing::get;
1010
use axum::Router;
1111
use axum_extra::extract::cookie::Key;
12-
use highlight::DARK_CSS;
1312
use http::header::{
1413
CONTENT_SECURITY_POLICY, REFERRER_POLICY, SERVER, X_CONTENT_TYPE_OPTIONS, X_FRAME_OPTIONS,
1514
X_XSS_PROTECTION,
@@ -42,6 +41,8 @@ static PACKAGE_NAME: &str = env!("CARGO_PKG_NAME");
4241
pub struct Assets {
4342
favicon: Asset,
4443
css: assets::CssAssets,
44+
index_js: Asset,
45+
paste_js: Asset,
4546
}
4647

4748
#[derive(Clone)]
@@ -142,6 +143,10 @@ async fn light_css(State(state): State<AppState>) -> impl IntoResponse {
142143
state.assets.css.light.clone()
143144
}
144145

146+
async fn index_js(State(state): State<AppState>) -> impl IntoResponse {
147+
state.assets.index_js.clone()
148+
}
149+
145150
async fn start() -> Result<(), Box<dyn std::error::Error>> {
146151
tracing_subscriber::fmt::init();
147152

@@ -170,14 +175,24 @@ async fn start() -> Result<(), Box<dyn std::error::Error>> {
170175
include_bytes!("../assets/favicon.png").to_vec(),
171176
),
172177
css: CssAssets::new(&env::THEME),
178+
index_js: Asset::new_hashed(
179+
"index",
180+
mime::TEXT_JAVASCRIPT,
181+
include_bytes!("javascript/index.js").to_vec(),
182+
),
183+
paste_js: Asset::new_hashed(
184+
"paste",
185+
mime::TEXT_JAVASCRIPT,
186+
include_bytes!("javascript/paste.js").to_vec(),
187+
),
173188
};
174-
println!("{}", assets.css.style.route());
175189

176190
let app = routes::routes()
177191
.route(assets.favicon.route(), get(favicon))
178192
.route(assets.css.style.route(), get(style_css))
179193
.route(assets.css.dark.route(), get(dark_css))
180194
.route(assets.css.light.route(), get(light_css))
195+
.route(assets.index_js.route(), get(index_js))
181196
.layer(
182197
ServiceBuilder::new()
183198
.layer(DefaultBodyLimit::max(max_body_size))

src/pages.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
use crate::cache::Key as CacheKey;
22
use crate::highlight::Html;
33
use crate::routes::paste::{Format, QueryData};
4-
use crate::Assets;
5-
use crate::{assets, env};
4+
use crate::{env, errors, Assets};
65
use askama::Template;
76
use axum::http::StatusCode;
87
use std::num::NonZero;
@@ -22,6 +21,22 @@ pub struct Error<'a> {
2221
/// Error response carrying a status code and the page itself.
2322
pub type ErrorResponse<'a> = (StatusCode, Error<'a>);
2423

24+
/// Create an error response from `error` consisting of [`StatusCode`] derive from `error` as well
25+
/// as a rendered page with a description.
26+
pub fn make_error(error: errors::Error, assets: Arc<Assets>) -> ErrorResponse<'static> {
27+
let description = error.to_string();
28+
29+
(
30+
error.into(),
31+
Error {
32+
meta: &env::METADATA,
33+
base_path: &env::BASE_PATH,
34+
description,
35+
assets,
36+
},
37+
)
38+
}
39+
2540
impl Error<'_> {
2641
/// Create new [`Error`] from `description`.
2742
pub fn new(description: String, assets: Arc<Assets>) -> Self {

src/routes/assets.rs

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,2 @@
1-
use crate::highlight::{self, DATA};
2-
use crate::{AppState, Router};
3-
use axum::response::IntoResponse;
4-
use axum::routing::get;
5-
use axum_extra::{headers, TypedHeader};
6-
use bytes::Bytes;
7-
use std::time::Duration;
81

9-
/// Asset maximum age of six months.
10-
const MAX_AGE: Duration = Duration::from_secs(60 * 60 * 24 * 30 * 6);
112

12-
fn css_from(content: &'static str) -> impl IntoResponse {
13-
(
14-
(
15-
TypedHeader(headers::ContentType::from(mime::TEXT_CSS)),
16-
TypedHeader(headers::CacheControl::new().with_max_age(MAX_AGE)),
17-
),
18-
content,
19-
)
20-
}
21-
22-
fn js_from(content: &'static str) -> impl IntoResponse {
23-
(
24-
(
25-
TypedHeader(headers::ContentType::from(mime::TEXT_JAVASCRIPT)),
26-
TypedHeader(headers::CacheControl::new().with_max_age(MAX_AGE)),
27-
),
28-
content,
29-
)
30-
}
31-
32-
pub fn routes() -> Router<AppState> {
33-
let style_url = format!("/{}", &DATA.style.name);
34-
let index_url = format!("/{}", &DATA.index.name);
35-
let paste_url = format!("/{}", &DATA.paste.name);
36-
37-
Router::new()
38-
// .route(
39-
// "/favicon.ico",
40-
// get(|| async {
41-
// (
42-
// TypedHeader(headers::ContentType::png()),
43-
// TypedHeader(headers::CacheControl::new().with_max_age(MAX_AGE)),
44-
// Bytes::from_static(include_bytes!("../../assets/favicon.png")),
45-
// )
46-
// }),
47-
// )
48-
// .route(&style_url, get(|| async { css_from(DATA.style.content) }))
49-
// .route(
50-
// "/dark.css",
51-
// get(|| async { css_from(highlight::DARK_CSS.as_str()) }),
52-
// )
53-
// .route(
54-
// "/light.css",
55-
// get(|| async { css_from(highlight::LIGHT_CSS.as_str()) }),
56-
// )
57-
.route(&index_url, get(|| async { js_from(DATA.index.content) }))
58-
.route(&paste_url, get(|| async { js_from(DATA.paste.content) }))
59-
}

0 commit comments

Comments
 (0)