Skip to content

Commit 436fbde

Browse files
committed
added static-file 0.3 impl
1 parent ac66318 commit 436fbde

4 files changed

Lines changed: 90 additions & 21 deletions

File tree

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ jobs:
2929
run: cargo build --no-default-features --features change-detection
3030
- name: Run tests with change detection
3131
run: cargo test --no-default-features --features change-detection
32+
- name: Build with all features
33+
run: cargo build --all-features
3234
publish:
3335
name: Publish
3436
if: startsWith( github.ref, 'refs/tags/v' )

src/builtin_03.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use std::collections::HashMap;
2+
3+
use static_files_03::Resource;
4+
5+
use crate::{ResourceFile, ResourceFilesCollection};
6+
7+
impl ResourceFile for Resource {
8+
fn data(&self) -> &'static [u8] {
9+
self.data
10+
}
11+
12+
fn modified(&self) -> u64 {
13+
self.modified
14+
}
15+
16+
fn mime_type(&self) -> &str {
17+
self.mime_type
18+
}
19+
}
20+
21+
impl ResourceFilesCollection for HashMap<&'static str, Resource> {
22+
type Resource = Resource;
23+
fn get_resource(&self, path: &str) -> Option<&Self::Resource> {
24+
self.get(path)
25+
}
26+
27+
fn contains_key(&self, path: &str) -> bool {
28+
self.contains_key(path)
29+
}
30+
}

src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#![doc = include_str!("../README.md")]
33
pub mod deps;
44
mod resource_files;
5-
pub use resource_files::{ResourceFiles, UriSegmentError};
5+
pub use resource_files::{ResourceFile, ResourceFiles, ResourceFilesCollection, UriSegmentError};
66
#[cfg(feature = "builtin-03")]
77
pub use static_files_03::*;
8+
#[cfg(feature = "builtin-03")]
9+
mod builtin_03;

src/resource_files.rs

Lines changed: 55 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,28 @@ use std::{collections::HashMap, ops::Deref, rc::Rc, sync::Arc};
1818

1919
pub type DefaultResourceFiles = HashMap<&'static str, Resource>;
2020

21-
pub trait ResourceFilesCollection {
22-
fn get_resource(&self, path: &str) -> Option<&Resource>;
23-
fn contains_key(&self, path: &str) -> bool;
21+
/// Resource file with static data and metadata.
22+
pub trait ResourceFile {
23+
fn data(&self) -> &'static [u8];
24+
fn modified(&self) -> u64;
25+
fn mime_type(&self) -> &str;
2426
}
2527

26-
impl ResourceFilesCollection for DefaultResourceFiles {
27-
fn get_resource(&self, path: &str) -> Option<&Resource> {
28-
self.get(path)
29-
}
30-
31-
fn contains_key(&self, path: &str) -> bool {
32-
self.contains_key(path)
33-
}
28+
/// Basic abstraction for a dictionary of resources.
29+
pub trait ResourceFilesCollection {
30+
type Resource: ResourceFile;
31+
/// Get a resource by path
32+
fn get_resource(&self, path: &str) -> Option<&Self::Resource>;
33+
/// Check if a resource exists by path
34+
fn contains_key(&self, path: &str) -> bool;
3435
}
3536

3637
impl<R> ResourceFilesCollection for Rc<R>
3738
where
3839
R: ResourceFilesCollection,
3940
{
40-
fn get_resource(&self, path: &str) -> Option<&Resource> {
41+
type Resource = R::Resource;
42+
fn get_resource(&self, path: &str) -> Option<&Self::Resource> {
4143
let r: &R = self;
4244
r.get_resource(path)
4345
}
@@ -52,7 +54,8 @@ impl<R> ResourceFilesCollection for Arc<R>
5254
where
5355
R: ResourceFilesCollection,
5456
{
55-
fn get_resource(&self, path: &str) -> Option<&Resource> {
57+
type Resource = R::Resource;
58+
fn get_resource(&self, path: &str) -> Option<&Self::Resource> {
5659
let r: &R = self;
5760
r.get_resource(path)
5861
}
@@ -63,6 +66,35 @@ where
6366
}
6467
}
6568

69+
mod legacy_static_files {
70+
use super::*;
71+
72+
impl ResourceFile for Resource {
73+
fn data(&self) -> &'static [u8] {
74+
self.data
75+
}
76+
77+
fn modified(&self) -> u64 {
78+
self.modified
79+
}
80+
81+
fn mime_type(&self) -> &str {
82+
self.mime_type
83+
}
84+
}
85+
86+
impl ResourceFilesCollection for DefaultResourceFiles {
87+
type Resource = Resource;
88+
fn get_resource(&self, path: &str) -> Option<&Self::Resource> {
89+
self.get(path)
90+
}
91+
92+
fn contains_key(&self, path: &str) -> bool {
93+
self.contains_key(path)
94+
}
95+
}
96+
}
97+
6698
/// Static resource files handling
6799
///
68100
/// `ResourceFiles` service must be registered with `App::service` method.
@@ -100,9 +132,12 @@ pub struct ResourceFilesInner<C> {
100132

101133
const INDEX_HTML: &str = "index.html";
102134

103-
impl ResourceFiles {
135+
impl<F> ResourceFiles<F>
136+
where
137+
F: ResourceFilesCollection + 'static,
138+
{
104139
#[must_use]
105-
pub fn new(path: &str, files: HashMap<&'static str, Resource>) -> Self {
140+
pub fn new(path: &str, files: F) -> Self {
106141
let inner = ResourceFilesInner {
107142
path: path.into(),
108143
files,
@@ -328,20 +363,20 @@ where
328363
}
329364
}
330365

331-
fn respond_to(req: &HttpRequest, item: Option<&Resource>) -> HttpResponse {
366+
fn respond_to<Resource: ResourceFile>(req: &HttpRequest, item: Option<&Resource>) -> HttpResponse {
332367
if let Some(file) = item {
333368
let etag = Some(header::EntityTag::new_strong(format!(
334369
"{:x}:{:x}",
335-
file.data.len(),
336-
file.modified
370+
file.data().len(),
371+
file.modified()
337372
)));
338373

339374
let precondition_failed = !any_match(etag.as_ref(), req);
340375

341376
let not_modified = !none_match(etag.as_ref(), req);
342377

343378
let mut resp = HttpResponse::build(StatusCode::OK);
344-
resp.insert_header((header::CONTENT_TYPE, file.mime_type));
379+
resp.insert_header((header::CONTENT_TYPE, file.mime_type()));
345380

346381
if let Some(etag) = etag {
347382
resp.insert_header(header::ETag(etag));
@@ -353,7 +388,7 @@ fn respond_to(req: &HttpRequest, item: Option<&Resource>) -> HttpResponse {
353388
return resp.status(StatusCode::NOT_MODIFIED).finish();
354389
}
355390

356-
resp.body(file.data)
391+
resp.body(file.data())
357392
} else {
358393
HttpResponse::NotFound().body("Not found")
359394
}

0 commit comments

Comments
 (0)