Skip to content

Commit 6cc7399

Browse files
committed
extract mime types into subcrate
1 parent 6973f6b commit 6cc7399

File tree

10 files changed

+88
-70
lines changed

10 files changed

+88
-70
lines changed

Cargo.lock

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ derive_more = { version = "2.0.0", features = ["display", "deref", "from", "into
3030
futures-util = "0.3.5"
3131
http = "1.0.0"
3232
itertools = { version = "0.14.0" }
33+
mime = "0.3.16"
3334
mockito = "1.0.2"
3435
opentelemetry = "0.31.0"
3536
opentelemetry-otlp = { version = "0.31.0", features = ["grpc-tonic", "metrics"] }
@@ -54,6 +55,7 @@ docs_rs_env_vars = { path = "crates/lib/docs_rs_env_vars" }
5455
docs_rs_fastly = { path = "crates/lib/docs_rs_fastly" }
5556
docs_rs_headers = { path = "crates/lib/docs_rs_headers" }
5657
docs_rs_logging = { path = "crates/lib/docs_rs_logging" }
58+
docs_rs_mimes = { path = "crates/lib/docs_rs_mimes" }
5759
docs_rs_opentelemetry = { path = "crates/lib/docs_rs_opentelemetry" }
5860
docs_rs_registry_api = { path = "crates/lib/docs_rs_registry_api" }
5961
docs_rs_repository_stats = { path = "crates/lib/docs_rs_repository_stats" }
@@ -84,7 +86,6 @@ toml = "0.9.2"
8486
opentelemetry = { workspace = true }
8587
opentelemetry_sdk = { workspace = true }
8688
rustwide = { version = "0.21.0", features = ["unstable-toolchain-ci", "unstable"] }
87-
mime_guess = "2"
8889
zstd = "0.13.0"
8990
flate2 = "1.1.1"
9091
hostname = "0.4.0"
@@ -125,7 +126,7 @@ axum = { version = "0.8.1", features = ["macros"] }
125126
axum-extra = { workspace = true }
126127
tower = "0.5.1"
127128
tower-http = { version = "0.6.0", features = ["fs", "trace", "timeout", "catch-panic"] }
128-
mime = "0.3.16"
129+
mime = { workspace = true }
129130

130131
tempfile = "3.1.0"
131132
fn-error-context = "0.2.0"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "docs_rs_mimes"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[dependencies]
7+
mime_guess = "2"
8+
mime = { workspace = true }
9+
10+
[dev-dependencies]
11+
test-case = { workspace = true }
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
use mime::{self, Mime};
2+
use std::{ffi::OsStr, path::Path};
3+
4+
pub fn detect_mime(file_path: impl AsRef<Path>) -> Mime {
5+
let mime = mime_guess::from_path(file_path.as_ref())
6+
.first()
7+
.unwrap_or(mime::TEXT_PLAIN);
8+
9+
match mime.as_ref() {
10+
"text/plain" | "text/troff" | "text/x-markdown" | "text/x-rust" | "text/x-toml" => {
11+
match file_path.as_ref().extension().and_then(OsStr::to_str) {
12+
Some("md") => crate::TEXT_MARKDOWN.clone(),
13+
Some("rs") => crate::TEXT_RUST.clone(),
14+
Some("markdown") => crate::TEXT_MARKDOWN.clone(),
15+
Some("css") => mime::TEXT_CSS,
16+
Some("toml") => crate::TEXT_TOML.clone(),
17+
Some("js") => mime::TEXT_JAVASCRIPT,
18+
Some("json") => mime::APPLICATION_JSON,
19+
Some("gz") => crate::APPLICATION_GZIP.clone(),
20+
Some("zst") => crate::APPLICATION_ZSTD.clone(),
21+
_ => mime,
22+
}
23+
}
24+
"image/svg" => mime::IMAGE_SVG,
25+
26+
_ => mime,
27+
}
28+
}
29+
30+
#[cfg(test)]
31+
mod tests {
32+
use super::*;
33+
use test_case::test_case;
34+
35+
// some standard mime types that mime-guess handles
36+
#[test_case("txt", &mime::TEXT_PLAIN)]
37+
#[test_case("html", &mime::TEXT_HTML)]
38+
// overrides of other mime types and defaults for
39+
// types mime-guess doesn't know about
40+
#[test_case("md", &crate::TEXT_MARKDOWN)]
41+
#[test_case("rs", &crate::TEXT_RUST)]
42+
#[test_case("markdown", &crate::TEXT_MARKDOWN)]
43+
#[test_case("css", &mime::TEXT_CSS)]
44+
#[test_case("toml", &crate::TEXT_TOML)]
45+
#[test_case("js", &mime::TEXT_JAVASCRIPT)]
46+
#[test_case("json", &mime::APPLICATION_JSON)]
47+
#[test_case("zst", &crate::APPLICATION_ZSTD)]
48+
#[test_case("gz", &crate::APPLICATION_GZIP)]
49+
fn test_detect_mime(ext: &str, expected: &Mime) {
50+
assert_eq!(&detect_mime(format!("something.{ext}")), expected);
51+
}
52+
}
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
mod detect;
2+
3+
pub use detect::detect_mime;
4+
15
use mime::Mime;
26
use std::sync::LazyLock;
37

48
macro_rules! mime {
59
($id:ident, $mime:expr) => {
6-
pub(crate) static $id: LazyLock<Mime> = LazyLock::new(|| $mime.parse().unwrap());
10+
pub static $id: LazyLock<Mime> = LazyLock::new(|| $mime.parse().unwrap());
711
};
812
}
913

src/db/file.rs

Lines changed: 2 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,10 @@
88
//! However, postgres is still available for testing and backwards compatibility.
99
1010
use crate::error::Result;
11-
use crate::{
12-
db::mimes,
13-
storage::{AsyncStorage, CompressionAlgorithm},
14-
};
11+
use crate::storage::{AsyncStorage, CompressionAlgorithm};
12+
use docs_rs_mimes::detect_mime;
1513
use mime::Mime;
1614
use serde_json::Value;
17-
use std::ffi::OsStr;
1815
use std::path::{Path, PathBuf};
1916
use tracing::instrument;
2017

@@ -32,32 +29,6 @@ impl FileEntry {
3229
}
3330
}
3431

35-
pub(crate) fn detect_mime(file_path: impl AsRef<Path>) -> Mime {
36-
let mime = mime_guess::from_path(file_path.as_ref())
37-
.first()
38-
.unwrap_or(mime::TEXT_PLAIN);
39-
40-
match mime.as_ref() {
41-
"text/plain" | "text/troff" | "text/x-markdown" | "text/x-rust" | "text/x-toml" => {
42-
match file_path.as_ref().extension().and_then(OsStr::to_str) {
43-
Some("md") => mimes::TEXT_MARKDOWN.clone(),
44-
Some("rs") => mimes::TEXT_RUST.clone(),
45-
Some("markdown") => mimes::TEXT_MARKDOWN.clone(),
46-
Some("css") => mime::TEXT_CSS,
47-
Some("toml") => mimes::TEXT_TOML.clone(),
48-
Some("js") => mime::TEXT_JAVASCRIPT,
49-
Some("json") => mime::APPLICATION_JSON,
50-
Some("gz") => mimes::APPLICATION_GZIP.clone(),
51-
Some("zst") => mimes::APPLICATION_ZSTD.clone(),
52-
_ => mime,
53-
}
54-
}
55-
"image/svg" => mime::IMAGE_SVG,
56-
57-
_ => mime,
58-
}
59-
}
60-
6132
/// Store all files in a directory and return [[mimetype, filename]] as Json
6233
///
6334
/// If there is an S3 Client configured, store files into an S3 bucket;
@@ -101,27 +72,3 @@ pub(crate) fn file_list_to_json(files: impl IntoIterator<Item = FileEntry>) -> V
10172
.collect(),
10273
)
10374
}
104-
105-
#[cfg(test)]
106-
mod tests {
107-
use super::*;
108-
use test_case::test_case;
109-
110-
// some standard mime types that mime-guess handles
111-
#[test_case("txt", &mime::TEXT_PLAIN)]
112-
#[test_case("html", &mime::TEXT_HTML)]
113-
// overrides of other mime types and defaults for
114-
// types mime-guess doesn't know about
115-
#[test_case("md", &mimes::TEXT_MARKDOWN)]
116-
#[test_case("rs", &mimes::TEXT_RUST)]
117-
#[test_case("markdown", &mimes::TEXT_MARKDOWN)]
118-
#[test_case("css", &mime::TEXT_CSS)]
119-
#[test_case("toml", &mimes::TEXT_TOML)]
120-
#[test_case("js", &mime::TEXT_JAVASCRIPT)]
121-
#[test_case("json", &mime::APPLICATION_JSON)]
122-
#[test_case("zst", &mimes::APPLICATION_ZSTD)]
123-
#[test_case("gz", &mimes::APPLICATION_GZIP)]
124-
fn test_detect_mime(ext: &str, expected: &Mime) {
125-
assert_eq!(&detect_mime(format!("something.{ext}")), expected);
126-
}
127-
}

src/db/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ mod add_package;
1818
pub mod blacklist;
1919
pub mod delete;
2020
pub(crate) mod file;
21-
pub(crate) mod mimes;
2221
mod overrides;
2322

2423
static MIGRATOR: Migrator = sqlx::migrate!();

src/storage/mod.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,12 @@ use self::{
1010
database::DatabaseBackend,
1111
s3::S3Backend,
1212
};
13-
use crate::{
14-
Config,
15-
db::{
16-
file::{FileEntry, detect_mime},
17-
mimes,
18-
},
19-
error::Result,
20-
};
13+
use crate::{Config, db::file::FileEntry, error::Result};
2114
use axum_extra::headers;
2215
use chrono::{DateTime, Utc};
2316
use dashmap::DashMap;
2417
use docs_rs_database::Pool;
18+
use docs_rs_mimes::{self as mimes, detect_mime};
2519
use docs_rs_opentelemetry::AnyMeterProvider;
2620
use docs_rs_types::{BuildId, Version};
2721
use docs_rs_utils::spawn_blocking;

src/web/sitemap.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::{
22
Config,
3-
db::mimes,
43
docbuilder::Limits,
54
impl_axum_webpage,
65
utils::{ConfigName, get_config, report_error},
@@ -22,6 +21,7 @@ use axum::{
2221
};
2322
use axum_extra::{TypedHeader, headers::ContentType};
2423
use chrono::{TimeZone, Utc};
24+
use docs_rs_mimes as mimes;
2525
use futures_util::{StreamExt as _, pin_mut};
2626
use std::sync::Arc;
2727
use tracing::{Span, error};

src/web/statics.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::{cache::CachePolicy, metrics::request_recorder, routes::get_static};
2-
use crate::{db::mimes::APPLICATION_OPENSEARCH_XML, web::cache::STATIC_ASSET_CACHE_POLICY};
2+
use crate::web::cache::STATIC_ASSET_CACHE_POLICY;
33
use axum::{
44
Router as AxumRouter,
55
extract::{Extension, Request},
@@ -12,6 +12,7 @@ use axum_extra::{
1212
typed_header::TypedHeader,
1313
};
1414
use docs_rs_headers::IfNoneMatch;
15+
use docs_rs_mimes::APPLICATION_OPENSEARCH_XML;
1516
use http::{StatusCode, Uri};
1617
use tower_http::services::ServeDir;
1718

0 commit comments

Comments
 (0)