@@ -127,53 +127,63 @@ pub fn detect_mime_type(bytes: &[u8]) -> &'static str {
127127 return "application/octet-stream" ;
128128 }
129129
130- if bytes. starts_with ( & [ 0x89 , 0x50 , 0x4E , 0x47 , 0x0D , 0x0A , 0x1A , 0x0A ] ) {
130+ // PNG: 89 50 4E 47 0D 0A 1A 0A
131+ if bytes. starts_with ( b"\x89 PNG\r \n \x1a \n " ) {
131132 return "image/png" ;
132133 }
133- if bytes. starts_with ( & [ 0xFF , 0xD8 ] ) {
134+ // JPEG: FF D8
135+ if bytes. starts_with ( b"\xFF \xD8 " ) {
134136 return "image/jpeg" ;
135137 }
136- if bytes . starts_with ( & [ 0x47 , 0x49 , 0x46 , 0x38 , 0x37 , 0x61 ] ) ||
137- bytes. starts_with ( & [ 0x47 , 0x49 , 0x46 , 0x38 , 0x39 , 0x61 ] ) {
138+ // GIF87a/89a: GIF87a or GIF89a
139+ if bytes. starts_with ( b"GIF87a" ) || bytes . starts_with ( b"GIF89a" ) {
138140 return "image/gif" ;
139141 }
140- if bytes. starts_with ( & [ 0x42 , 0x4D ] ) {
142+ // BMP: 42 4D
143+ if bytes. starts_with ( b"BM" ) {
141144 return "image/bmp" ;
142145 }
143- if bytes . starts_with ( & [ 0x52 , 0x49 , 0x46 , 0x46 ] ) && bytes . len ( ) >= 12 &&
144- & bytes[ 8 ..12 ] == & [ 0x57 , 0x45 , 0x42 , 0x50 ] {
146+ // WebP: RIFF....WEBP
147+ if bytes . starts_with ( b"RIFF" ) && bytes . len ( ) >= 12 && & bytes[ 8 ..12 ] == b"WEBP" {
145148 return "image/webp" ;
146149 }
147- if bytes. starts_with ( & [ 0x25 , 0x50 , 0x44 , 0x46 ] ) {
150+ // PDF: %PDF
151+ if bytes. starts_with ( b"%PDF" ) {
148152 return "application/pdf" ;
149153 }
150- if bytes. starts_with ( & [ 0x50 , 0x4B , 0x03 , 0x04 ] ) {
154+ // ZIP: 50 4B 03 04
155+ if bytes. starts_with ( b"PK\x03 \x04 " ) {
156+ // Check for Office document types in ZIP central directory
151157 if bytes. len ( ) >= 50 {
152- let content = String :: from_utf8_lossy ( & bytes[ 30 ..50 ] ) ;
153- if content . contains ( "word/" ) {
158+ let central_dir = & bytes[ 30 ..bytes . len ( ) . min ( 50 ) ] ;
159+ if central_dir . windows ( 6 ) . any ( |w| w == b "word/") {
154160 return "application/vnd.openxmlformats-officedocument.wordprocessingml.document" ;
155161 }
156- if content . contains ( "xl/" ) {
162+ if central_dir . windows ( 3 ) . any ( |w| w == b "xl/") {
157163 return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ;
158164 }
159- if content . contains ( "ppt/" ) {
165+ if central_dir . windows ( 4 ) . any ( |w| w == b "ppt/") {
160166 return "application/vnd.openxmlformats-officedocument.presentationml.presentation" ;
161167 }
162168 }
163169 return "application/zip" ;
164170 }
165171
166- let start = String :: from_utf8_lossy ( & bytes[ ..bytes. len ( ) . min ( 100 ) ] ) ;
167- let trimmed = start. trim_start ( ) ;
168-
169- if trimmed. starts_with ( "<svg" ) {
170- return "image/svg+xml" ;
171- }
172- if trimmed. starts_with ( "<?xml" ) || trimmed. starts_with ( '<' ) {
173- return "application/xml" ;
174- }
175- if trimmed. starts_with ( '{' ) || trimmed. starts_with ( '[' ) {
176- return "application/json" ;
172+ // Text-based formats - check first few bytes for ASCII patterns
173+ if bytes. len ( ) >= 1 {
174+ match bytes[ 0 ] {
175+ b'<' => {
176+ if bytes. len ( ) >= 4 && bytes. starts_with ( b"<svg" ) {
177+ return "image/svg+xml" ;
178+ }
179+ if bytes. len ( ) >= 5 && bytes. starts_with ( b"<?xml" ) {
180+ return "application/xml" ;
181+ }
182+ return "application/xml" ;
183+ }
184+ b'{' | b'[' => return "application/json" ,
185+ _ => { }
186+ }
177187 }
178188
179189 "application/octet-stream"
@@ -559,65 +569,51 @@ mod tests {
559569 assert_eq ! ( detect_mime_type( & [ ] ) , "application/octet-stream" ) ;
560570
561571 // Test PNG
562- let png_data = [ 0x89 , 0x50 , 0x4E , 0x47 , 0x0D , 0x0A , 0x1A , 0x0A ] ;
563- assert_eq ! ( detect_mime_type( & png_data) , "image/png" ) ;
572+ assert_eq ! ( detect_mime_type( b"\x89 PNG\r \n \x1a \n " ) , "image/png" ) ;
564573
565574 // Test JPEG
566- let jpeg_data = [ 0xFF , 0xD8 , 0xFF , 0xE0 ] ;
567- assert_eq ! ( detect_mime_type( & jpeg_data) , "image/jpeg" ) ;
575+ assert_eq ! ( detect_mime_type( b"\xFF \xD8 \xFF \xE0 " ) , "image/jpeg" ) ;
568576
569577 // Test GIF87a
570- let gif87a_data = [ 0x47 , 0x49 , 0x46 , 0x38 , 0x37 , 0x61 ] ;
571- assert_eq ! ( detect_mime_type( & gif87a_data) , "image/gif" ) ;
578+ assert_eq ! ( detect_mime_type( b"GIF87a" ) , "image/gif" ) ;
572579
573580 // Test GIF89a
574- let gif89a_data = [ 0x47 , 0x49 , 0x46 , 0x38 , 0x39 , 0x61 ] ;
575- assert_eq ! ( detect_mime_type( & gif89a_data) , "image/gif" ) ;
581+ assert_eq ! ( detect_mime_type( b"GIF89a" ) , "image/gif" ) ;
576582
577583 // Test BMP
578- let bmp_data = [ 0x42 , 0x4D , 0x00 , 0x00 ] ;
579- assert_eq ! ( detect_mime_type( & bmp_data) , "image/bmp" ) ;
584+ assert_eq ! ( detect_mime_type( b"BM\x00 \x00 " ) , "image/bmp" ) ;
580585
581586 // Test PDF
582- let pdf_data = [ 0x25 , 0x50 , 0x44 , 0x46 , 0x2D ] ;
583- assert_eq ! ( detect_mime_type( & pdf_data) , "application/pdf" ) ;
587+ assert_eq ! ( detect_mime_type( b"%PDF-" ) , "application/pdf" ) ;
584588
585589 // Test SVG
586- let svg_data = b"<svg xmlns=\" http://www.w3.org/2000/svg\" >" ;
587- assert_eq ! ( detect_mime_type( svg_data) , "image/svg+xml" ) ;
590+ assert_eq ! ( detect_mime_type( b"<svg xmlns=\" http://www.w3.org/2000/svg\" >" ) , "image/svg+xml" ) ;
588591
589592 // Test XML (non-SVG)
590- let xml_data = b"<?xml version=\" 1.0\" ?><root><data>test</data></root>" ;
591- assert_eq ! ( detect_mime_type( xml_data) , "application/xml" ) ;
593+ assert_eq ! ( detect_mime_type( b"<?xml version=\" 1.0\" ?><root><data>test</data></root>" ) , "application/xml" ) ;
592594
593595 // Test JSON
594- let json_data = b"{\" key\" : \" value\" }" ;
595- assert_eq ! ( detect_mime_type( json_data) , "application/json" ) ;
596+ assert_eq ! ( detect_mime_type( b"{\" key\" : \" value\" }" ) , "application/json" ) ;
596597
597598 // Test ZIP
598- let zip_data = [ 0x50 , 0x4B , 0x03 , 0x04 ] ;
599- assert_eq ! ( detect_mime_type( & zip_data) , "application/zip" ) ;
599+ assert_eq ! ( detect_mime_type( b"PK\x03 \x04 " ) , "application/zip" ) ;
600600
601601 // Test unknown data
602- let unknown_data = [ 0x00 , 0x01 , 0x02 , 0x03 ] ;
603- assert_eq ! ( detect_mime_type( & unknown_data) , "application/octet-stream" ) ;
602+ assert_eq ! ( detect_mime_type( & [ 0x00 , 0x01 , 0x02 , 0x03 ] ) , "application/octet-stream" ) ;
604603 }
605604
606605 #[ test]
607606 fn test_vec_to_data_uri_with_auto_detection ( ) {
608607 // Test PNG auto-detection
609- let png_data = [ 0x89 , 0x50 , 0x4E , 0x47 , 0x0D , 0x0A , 0x1A , 0x0A , 0x00 ] ;
610- let result = vec_to_data_uri ( & png_data) ;
608+ let result = vec_to_data_uri ( b"\x89 PNG\r \n \x1a \n \x00 " ) ;
611609 assert ! ( result. starts_with( "data:image/png;base64," ) ) ;
612610
613611 // Test JPEG auto-detection
614- let jpeg_data = [ 0xFF , 0xD8 , 0xFF , 0xE0 , 0x00 ] ;
615- let result = vec_to_data_uri ( & jpeg_data) ;
612+ let result = vec_to_data_uri ( b"\xFF \xD8 \xFF \xE0 \x00 " ) ;
616613 assert ! ( result. starts_with( "data:image/jpeg;base64," ) ) ;
617614
618615 // Test PDF auto-detection
619- let pdf_data = [ 0x25 , 0x50 , 0x44 , 0x46 , 0x2D , 0x00 ] ;
620- let result = vec_to_data_uri ( & pdf_data) ;
616+ let result = vec_to_data_uri ( b"%PDF-\x00 " ) ;
621617 assert ! ( result. starts_with( "data:application/pdf;base64," ) ) ;
622618 }
623619
0 commit comments