Skip to content

Commit ee35cfd

Browse files
JSKittyclaude
andcommitted
refactor: deduplicate util.rs MIME tables and pure functions into vector-core
Delete ~330 lines of duplicate MIME HashMaps (EXT_TO_MIME, MIME_TO_EXT) and superseded functions from src-tauri/util.rs — re-exported from vector-core. Moved to vector-core crypto module: - format_bytes, is_image_mime, mime_from_extension_safe, mime_from_magic_bytes Delegated to vector-core: - calculate_file_hash → vector_core::crypto::sha256_hex - mime_from_extension_static → vector_core::crypto::mime_from_extension Kept in src-tauri (Tauri/SIMD deps): - data_uri (base64_simd), extract_https_urls (simd::url) - thumbhash generation/decoding (image crate + simd downsampling) - get_file_type_description (UI display strings) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 978114e commit ee35cfd

2 files changed

Lines changed: 66 additions & 349 deletions

File tree

crates/vector-core/src/crypto/mod.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,57 @@ pub fn sanitize_filename(name: &str) -> String {
427427
sanitized.to_string()
428428
}
429429

430+
/// Format bytes into human-readable format (KB, MB, GB).
431+
pub fn format_bytes(bytes: u64) -> String {
432+
const KB: f64 = 1024.0;
433+
const MB: f64 = KB * 1024.0;
434+
const GB: f64 = MB * 1024.0;
435+
436+
if bytes < KB as u64 {
437+
format!("{} B", bytes)
438+
} else if bytes < MB as u64 {
439+
format!("{:.1} KB", bytes as f64 / KB)
440+
} else if bytes < GB as u64 {
441+
format!("{:.1} MB", bytes as f64 / MB)
442+
} else {
443+
format!("{:.1} GB", bytes as f64 / GB)
444+
}
445+
}
446+
447+
/// Returns true if the provided MIME type is an image/*.
448+
pub fn is_image_mime(mime: &str) -> bool {
449+
mime.trim().starts_with("image/")
450+
}
451+
452+
/// Convert a file extension to a MIME type, with an optional restriction to image/* types.
453+
pub fn mime_from_extension_safe(extension: &str, image_only: bool) -> Result<String, String> {
454+
let mime = mime_from_extension(extension).to_string();
455+
if image_only && !is_image_mime(&mime) {
456+
return Err(mime);
457+
}
458+
Ok(mime)
459+
}
460+
461+
/// Detect MIME type from file magic bytes.
462+
/// Supports PNG, JPEG, GIF, WebP, TIFF, ICO, and SVG.
463+
/// Returns "application/octet-stream" for unrecognized formats.
464+
pub fn mime_from_magic_bytes(bytes: &[u8]) -> &'static str {
465+
if bytes.len() < 4 {
466+
return "application/octet-stream";
467+
}
468+
match bytes[0] {
469+
0x89 if bytes[1..4] == [0x50, 0x4E, 0x47] => "image/png",
470+
0xFF if bytes[1..3] == [0xD8, 0xFF] => "image/jpeg",
471+
b'G' if bytes.len() >= 6 && (bytes[..6] == *b"GIF87a" || bytes[..6] == *b"GIF89a") => "image/gif",
472+
b'R' if bytes.len() > 12 && bytes[..4] == *b"RIFF" && bytes[8..12] == *b"WEBP" => "image/webp",
473+
0x49 if bytes[1..4] == [0x49, 0x2A, 0x00] => "image/tiff",
474+
0x4D if bytes[1..4] == [0x4D, 0x00, 0x2A] => "image/tiff",
475+
0x00 if bytes[1..4] == [0x00, 0x01, 0x00] => "image/x-icon",
476+
b'<' if bytes.starts_with(b"<?xml") || bytes.starts_with(b"<svg") => "image/svg+xml",
477+
_ => "application/octet-stream",
478+
}
479+
}
480+
430481
#[cfg(test)]
431482
mod tests {
432483
use super::*;

0 commit comments

Comments
 (0)