diff --git a/.changeset/mime-guess-upload.md b/.changeset/mime-guess-upload.md new file mode 100644 index 00000000..83a3807d --- /dev/null +++ b/.changeset/mime-guess-upload.md @@ -0,0 +1,5 @@ +--- +"@googleworkspace/cli": patch +--- + +Replace hand-rolled MIME type lookup with mime_guess2 crate for upload content-type inference diff --git a/Cargo.lock b/Cargo.lock index 0d55ea8d..5735e416 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -226,9 +226,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.56" +version = "1.2.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" +checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423" dependencies = [ "find-msvc-tools", "shlex", @@ -904,6 +904,7 @@ dependencies = [ "hostname", "iana-time-zone", "keyring", + "mime_guess2", "percent-encoding", "rand 0.8.5", "ratatui", @@ -1477,6 +1478,24 @@ dependencies = [ "autocfg", ] +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess2" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1706dc14a2e140dec0a7a07109d9a3d5890b81e85bd6c60b906b249a77adf0ca" +dependencies = [ + "mime", + "phf 0.11.3", + "phf_shared 0.11.3", + "unicase", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -1723,6 +1742,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.117", + "unicase", ] [[package]] @@ -1732,6 +1752,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" dependencies = [ "siphasher", + "unicase", ] [[package]] @@ -2741,9 +2762,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" dependencies = [ "tinyvec_macros", ] @@ -2954,6 +2975,12 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" +[[package]] +name = "unicase" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" + [[package]] name = "unicode-ident" version = "1.0.24" diff --git a/Cargo.toml b/Cargo.toml index 24bc253b..0e1f0eda 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,6 +56,7 @@ crossterm = "0.29.0" chrono = "0.4.44" chrono-tz = "0.10" iana-time-zone = "0.1" +mime_guess2 = "2.3" async-trait = "0.1.89" serde_yaml = "0.9.34" percent-encoding = "2.3.2" diff --git a/src/executor.rs b/src/executor.rs index 73fd772f..ef7ff6d4 100644 --- a/src/executor.rs +++ b/src/executor.rs @@ -808,7 +808,7 @@ fn resolve_upload_mime( } if let Some(path) = upload_path { - if let Some(detected) = mime_from_extension(path) { + if let Some(detected) = mime_guess2::from_path(path).first() { return detected.to_string(); } } @@ -824,33 +824,6 @@ fn resolve_upload_mime( "application/octet-stream".to_string() } -/// Infers a MIME type from a file path's extension. -fn mime_from_extension(path: &str) -> Option<&'static str> { - let ext = std::path::Path::new(path) - .extension() - .and_then(|e| e.to_str())?; - match ext.to_lowercase().as_str() { - "md" | "markdown" => Some("text/markdown"), - "html" | "htm" => Some("text/html"), - "txt" => Some("text/plain"), - "json" => Some("application/json"), - "csv" => Some("text/csv"), - "xml" => Some("application/xml"), - "pdf" => Some("application/pdf"), - "png" => Some("image/png"), - "jpg" | "jpeg" => Some("image/jpeg"), - "gif" => Some("image/gif"), - "svg" => Some("image/svg+xml"), - "doc" => Some("application/msword"), - "docx" => Some("application/vnd.openxmlformats-officedocument.wordprocessingml.document"), - "xls" => Some("application/vnd.ms-excel"), - "xlsx" => Some("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"), - "ppt" => Some("application/vnd.ms-powerpoint"), - "pptx" => Some("application/vnd.openxmlformats-officedocument.presentationml.presentation"), - _ => None, - } -} - /// Builds a streaming multipart/related body for media upload requests. /// /// Instead of reading the entire file into memory, this streams the file in