1#[cfg(feature = "warp")]
2use warp::{
3 http::header::{HeaderValue, CACHE_CONTROL, CONTENT_TYPE},
4 hyper::Body,
5 reply::Response,
6 Filter, Rejection, Reply,
7};
8
9#[cfg(feature = "warp")]
10pub fn route() -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
11 assets().or(fonts()).or(min_assets())
12}
13
14pub static CSS: &str = include_str!("../css/stylus.css");
15pub static MAP: &str = include_str!("../css/stylus.css.map");
16
17#[cfg(feature = "warp")]
18pub fn assets() -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
19 warp::path("assets").and(
20 warp::path("stylus.css")
21 .map(|| Css { body: CSS })
22 .or(warp::path("stylus.css.map").map(|| Map { body: MAP })),
23 )
24}
25
26pub static MIN_CSS: &str = include_str!("../css/stylus.min.css");
27pub static MIN_MAP: &str = include_str!("../css/stylus.min.css.map");
28
29#[cfg(feature = "warp")]
30pub fn min_assets() -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
31 warp::path("assets").and(
32 warp::path("stylus.min.css")
33 .map(|| Css { body: MIN_CSS })
34 .or(warp::path("stylus.min.css.map").map(|| Map { body: MIN_MAP })),
35 )
36}
37
38pub static FONT_REGULAR_TTF: &[u8] = include_bytes!("../fonts/noto-sans-regular.ttf");
39pub static FONT_REGULAR_WOFF: &[u8] = include_bytes!("../fonts/noto-sans-regular.woff");
40pub static FONT_REGULAR_WOFF2: &[u8] = include_bytes!("../fonts/noto-sans-regular.woff2");
41
42pub static FONT_ITALIC_TTF: &[u8] = include_bytes!("../fonts/noto-sans-italic.ttf");
43pub static FONT_ITALIC_WOFF: &[u8] = include_bytes!("../fonts/noto-sans-italic.woff");
44pub static FONT_ITALIC_WOFF2: &[u8] = include_bytes!("../fonts/noto-sans-italic.woff2");
45
46pub static FONT_BOLD_TTF: &[u8] = include_bytes!("../fonts/noto-sans-bold.ttf");
47pub static FONT_BOLD_WOFF: &[u8] = include_bytes!("../fonts/noto-sans-bold.woff");
48pub static FONT_BOLD_WOFF2: &[u8] = include_bytes!("../fonts/noto-sans-bold.woff2");
49
50pub static FONT_BOLD_ITALIC_TTF: &[u8] = include_bytes!("../fonts/noto-sans-bold-italic.ttf");
51pub static FONT_BOLD_ITALIC_WOFF: &[u8] = include_bytes!("../fonts/noto-sans-bold-italic.woff");
52pub static FONT_BOLD_ITALIC_WOFF2: &[u8] = include_bytes!("../fonts/noto-sans-bold-italic.woff2");
53
54#[cfg(feature = "warp")]
55pub fn fonts() -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
56 warp::path("fonts").and(ttf().or(woff()).or(woff2()))
57}
58
59#[cfg(feature = "warp")]
60fn ttf() -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
61 warp::get().and(
62 warp::path("noto-sans-regular.ttf")
63 .map(|| Font {
64 body: FONT_REGULAR_TTF,
65 })
66 .or(warp::path("noto-sans-italic.ttf").map(|| Font {
67 body: FONT_ITALIC_TTF,
68 }))
69 .or(warp::path("noto-sans-bold.ttf").map(|| Font {
70 body: FONT_BOLD_TTF,
71 }))
72 .or(warp::path("noto-sans-bold-italic.ttf").map(|| Font {
73 body: FONT_BOLD_ITALIC_TTF,
74 })),
75 )
76}
77
78#[cfg(feature = "warp")]
79fn woff() -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
80 warp::get().and(
81 warp::path("noto-sans-regular.woff")
82 .map(|| Font {
83 body: FONT_REGULAR_WOFF,
84 })
85 .or(warp::path("noto-sans-italic.woff").map(|| Font {
86 body: FONT_ITALIC_WOFF,
87 }))
88 .or(warp::path("noto-sans-bold.woff").map(|| Font {
89 body: FONT_BOLD_WOFF,
90 }))
91 .or(warp::path("noto-sans-bold-italic.woff").map(|| Font {
92 body: FONT_BOLD_ITALIC_WOFF,
93 })),
94 )
95}
96
97#[cfg(feature = "warp")]
98fn woff2() -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
99 warp::get().and(
100 warp::path("noto-sans-regular.woff2")
101 .map(|| Font {
102 body: FONT_REGULAR_WOFF2,
103 })
104 .or(warp::path("noto-sans-italic.woff2").map(|| Font {
105 body: FONT_ITALIC_WOFF2,
106 }))
107 .or(warp::path("noto-sans-bold.woff2").map(|| Font {
108 body: FONT_BOLD_WOFF2,
109 }))
110 .or(warp::path("noto-sans-bold-italic.woff2").map(|| Font {
111 body: FONT_BOLD_ITALIC_WOFF2,
112 })),
113 )
114}
115
116#[cfg(feature = "warp")]
117struct Css<T> {
118 body: T,
119}
120
121#[cfg(feature = "warp")]
122impl<T> Reply for Css<T>
123where
124 Body: From<T>,
125 T: Send,
126{
127 #[inline]
128 fn into_response(self) -> Response {
129 let mut res = Response::new(Body::from(self.body));
130
131 res.headers_mut().insert(
132 CACHE_CONTROL,
133 HeaderValue::from_static("public, max-age=37260"),
134 );
135
136 res.headers_mut().insert(
137 CONTENT_TYPE,
138 HeaderValue::from_static("text/css; charset=utf-8"),
139 );
140
141 res
142 }
143}
144
145#[cfg(feature = "warp")]
146struct Font<T> {
147 body: T,
148}
149
150#[cfg(feature = "warp")]
151impl<T> Reply for Font<T>
152where
153 Body: From<T>,
154 T: Send,
155{
156 #[inline]
157 fn into_response(self) -> Response {
158 let mut res = Response::new(Body::from(self.body));
159
160 res.headers_mut().insert(
161 CACHE_CONTROL,
162 HeaderValue::from_static("public, max-age=37260"),
163 );
164
165 res.headers_mut().insert(
166 CONTENT_TYPE,
167 HeaderValue::from_static("application/octet-stream"),
168 );
169
170 res
171 }
172}
173
174#[cfg(feature = "warp")]
175struct Map<T> {
176 body: T,
177}
178
179#[cfg(feature = "warp")]
180impl<T> Reply for Map<T>
181where
182 Body: From<T>,
183 T: Send,
184{
185 #[inline]
186 fn into_response(self) -> Response {
187 let mut res = Response::new(Body::from(self.body));
188
189 res.headers_mut().insert(
190 CACHE_CONTROL,
191 HeaderValue::from_static("public, max-age=37260"),
192 );
193
194 res.headers_mut().insert(
195 CONTENT_TYPE,
196 HeaderValue::from_static("application/json; charset=utf-8"),
197 );
198
199 res
200 }
201}