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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use proc_macro_hack::proc_macro_hack;
mod dir;
mod file;
pub use crate::dir::Dir;
pub use crate::file::File;
#[proc_macro_hack]
pub use inpm_impl::include_package;
#[cfg(feature = "warp")]
pub mod warp {
use crate::File;
use warpd::{
reject::Rejection,
reply::{self, Reply},
Filter,
};
fn with<T: Clone + Send + Sync>(
source: T,
) -> impl Filter<Extract = (T,), Error = std::convert::Infallible> + Clone {
warpd::any().map(move || source.clone())
}
pub fn embedded(
dir: crate::Dir,
) -> impl Filter<Extract = (warpd::reply::WithHeader<File>,), Error = Rejection> + Clone {
warpd::get()
.and(warpd::path::tail())
.and(with(dir))
.and_then(|tail: warpd::path::Tail, dir: crate::Dir| async move {
dir.get(tail.as_str())
.map(|file| {
let mime = mime_guess::from_path(file.path()).first_or_octet_stream();
warpd::reply::with_header(
file,
warpd::http::header::CONTENT_TYPE,
mime.as_ref(),
)
})
.ok_or(warpd::reject::not_found())
})
}
pub fn spa(
dir: crate::Dir,
entry: &'static str,
) -> impl Filter<Extract = (warpd::reply::WithHeader<File>,), Error = Rejection> + Clone {
warpd::get()
.and(warpd::path::tail())
.and(with(dir))
.and(with(entry))
.and_then(
|tail: warpd::path::Tail, dir: crate::Dir, entry: &'static str| async move {
dir.get(tail.as_str())
.or(dir.get(entry))
.map(|file| {
let mime = mime_guess::from_path(file.path()).first_or_octet_stream();
warpd::reply::with_header(
file,
warpd::http::header::CONTENT_TYPE,
mime.as_ref(),
)
})
.ok_or(warpd::reject::not_found())
},
)
}
impl Reply for File {
fn into_response(self) -> reply::Response {
self.contents().into_owned().into_response()
}
}
}