diff --git a/src/metadata.rs b/src/metadata.rs index 477fa22..f9eac95 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -58,13 +58,15 @@ impl MetadataHandler { let mut metadata = HashMap::new(); // EXIF if let Ok(exif_data) = self.extract_exif_metadata(path) { - metadata.extend(exif_data); + for (k, v) in exif_data { + metadata.entry(k).or_insert(v); + } } // File info if let Ok(file_metadata) = std::fs::metadata(path) { - metadata.insert("File Size".to_string(), format!("{} bytes", file_metadata.len())); + metadata.entry("File Size".to_string()).or_insert(format!("{} bytes", file_metadata.len())); if let Ok(modified) = file_metadata.modified() { - metadata.insert("Modified".to_string(), format!("{:?}", modified)); + metadata.entry("Modified".to_string()).or_insert(format!("{:?}", modified)); } } // Dimensions @@ -72,7 +74,7 @@ impl MetadataHandler { let width = meta.get_pixel_width(); let height = meta.get_pixel_height(); if width > 0 && height > 0 { - metadata.insert("Dimensions".to_string(), format!("{}x{}", width, height)); + metadata.entry("Dimensions".to_string()).or_insert(format!("{}x{}", width, height)); } } Ok(metadata) @@ -119,17 +121,21 @@ impl MetadataHandler { } return Ok(()); } - // Sensitivity classification (updated) + // Sensitivity classification let red_keys = [ "GPSLatitude", "GPSLongitude", "GPSAltitude", "GPSLatitudeRef", "GPSLongitudeRef", "GPSAltitudeRef", - "DateTimeOriginal", "DateTimeDigitized", "DateTime", "OffsetTime", "OffsetTimeOriginal", "Modified", - "ImageUniqueID" + "DateTimeOriginal", "DateTimeDigitized", "DateTime", "OffsetTime", "OffsetTimeOriginal", "OffsetTimeDigitized", + "Modified", "GPSTimeStamp", "GPSSpeedRef","GPSDateStamp", "GPSProcessingMethod", "GPSSpeed", "GPSTrack", "GPSImgDirection", + "ImageUniqueID", "SubSecTime", "SubSecTimeDigitized", "SubSecTimeOriginal", "ExposureIndex", "LensModel", ]; let yellow_keys = [ "Make", "Model", "Software", "SceneCaptureType", "DigitalZoomRatio", "FNumber", "ExposureBiasValue", "ExposureMode", "MeteringMode", "ShutterSpeedValue", "ExposureTime", "WhiteBalance", "ApertureValue", "FocalLength", "FocalLengthIn35mmFilm", "PhotographicSensitivity", "Flash", "ExposureProgram", "ExifVersion", - "MaxApertureValue" + "MaxApertureValue", "SceneType", "BrightnessValue", "SensingMethod", "ComponentsConfiguration", + "LightSource", "FlashpixVersion", "InteroperabilityIndex", "InteroperabilityVersion", + "Tag(Exif, 34953)", "Tag(Exif, 42593)", "Tag(Exif, 34965)", "Tag(Tiff, 39424)", "Tag(Exif, 39321)", + "Tag(Tiff, 34970)", "Tag(Tiff, 34979)", "Tag(Exif, 34974)", "Tag(Exif, 39424)", "Tag(Tiff, 39321)" ]; let green_keys = [ "PixelXDimension", "PixelYDimension", "ImageWidth", "ImageLength", "Dimensions", "Compression", "ColorSpace", @@ -168,14 +174,42 @@ impl MetadataHandler { println!("📋 Image Metadata:"); for (key, value) in metadata { let color = if red_keys.contains(&key.as_str()) { - "\x1b[31m" // Red + "\x1b[31m" } else if yellow_keys.contains(&key.as_str()) { - "\x1b[33m" // Yellow + "\x1b[33m" } else if green_keys.contains(&key.as_str()) { - "\x1b[32m" // Green + "\x1b[32m" } else { - "\x1b[0m" // Default + "\x1b[0m" }; + + // Try to pretty-print JSON objects as sub-tags, even if value is a quoted JSON string + let trimmed = value.trim(); + let try_json = if trimmed.starts_with('"') && trimmed.ends_with('"') && trimmed.len() > 2 { + // Remove surrounding quotes and unescape + let unquoted = &trimmed[1..trimmed.len()-1]; + let unescaped = unquoted.replace("\\\"", "\""); + serde_json::from_str::(&unescaped).ok() + } else if trimmed.starts_with('{') && trimmed.ends_with('}') { + serde_json::from_str::(trimmed).ok() + } else { + None + }; + + if let Some(json) = try_json { + if let Some(obj) = json.as_object() { + println!("{}{}:\x1b[0m", color, key); + for (subkey, subval) in obj { + println!(" {}{}: {}\x1b[0m", color, subkey, subval); + } + continue; + } + // fallback: pretty print the whole JSON + let pretty = serde_json::to_string_pretty(&json).unwrap_or_else(|_| value.clone()); + println!("{}{}: {}\x1b[0m", color, key, pretty); + continue; + } + println!("{}{}: {}\x1b[0m", color, key, value); } println!("{}", "─".repeat(60));