From 77b814fae49f7fc9c18cf0f97c5d6f582a3a1c38 Mon Sep 17 00:00:00 2001 From: Eguzki Astiz Lezaun Date: Tue, 1 Oct 2024 23:39:19 +0200 Subject: [PATCH] handle partial parsing errors (#3) Signed-off-by: Eguzki Astiz Lezaun --- Cargo.lock | 19 +++--- Cargo.toml | 3 +- src/datetime_tag_parser.rs | 116 ++++++++++++++++++------------------- 3 files changed, 68 insertions(+), 70 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 853202d..211a78f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -212,8 +212,8 @@ dependencies = [ "clap", "clap-verbosity-flag", "env_logger", + "exif", "filetime", - "kamadak-exif", "lazy_static", "little_exif", "log", @@ -252,6 +252,14 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "exif" +version = "0.5.5" +source = "git+https://github.com/kamadak/exif-rs.git?rev=8523b0f06f6fe4f8eb6022d6ae0922f5c1b3477c#8523b0f06f6fe4f8eb6022d6ae0922f5c1b3477c" +dependencies = [ + "mutate_once", +] + [[package]] name = "filetime" version = "0.2.23" @@ -330,15 +338,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "kamadak-exif" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4fc70d0ab7e5b6bafa30216a6b48705ea964cdfc29c050f2412295eba58077" -dependencies = [ - "mutate_once", -] - [[package]] name = "lazy_static" version = "1.5.0" diff --git a/Cargo.toml b/Cargo.toml index 40c299f..8d60b0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,8 @@ serde_yaml = "0.9" regex = "1.10" chrono = "0.4.34" filetime = "0.2" -kamadak-exif = "0.5.5" +# kamadak-exif = "0.5.5" +exif = { git = "https://github.com/kamadak/exif-rs.git", rev = "8523b0f06f6fe4f8eb6022d6ae0922f5c1b3477c" } little_exif = "0.4.0" lazy_static = "1.5.0" clap-verbosity-flag = "2.2.1" diff --git a/src/datetime_tag_parser.rs b/src/datetime_tag_parser.rs index e7a4ba0..c07e534 100644 --- a/src/datetime_tag_parser.rs +++ b/src/datetime_tag_parser.rs @@ -1,69 +1,67 @@ use chrono::NaiveDate; -use exif::{DateTime, Error, In, Tag, Value}; +use exif::{DateTime, In, Tag, Value}; use std::fs::File; use std::path::Path; -pub fn captures(path: &Path) -> Result>, String> { - let file = match File::open(path) { - Ok(f) => f, - Err(e) => return Err(e.to_string()), - }; +pub fn captures(path: &Path) -> Result>, exif::Error> { + let file = File::open(path)?; let mut bufreader = std::io::BufReader::new(&file); - let exifreader = exif::Reader::new(); - match exifreader.read_from_container(&mut bufreader) { - Ok(exif) => { - //for f in exif.fields() { - // println!( - // " {}/{}: {}", - // f.ifd_num.index(), - // f.tag, - // f.display_value().with_unit(&exif) - // ); - // println!(" {:?}", f.value); - //} - match exif.get_field(Tag::DateTimeOriginal, In::PRIMARY) { - Some(field) => match field.value { - Value::Ascii(ref vec) if !vec.is_empty() => { - match DateTime::from_ascii(&vec[0]) { - Ok(datetime) => Ok(Some( - NaiveDate::from_ymd_opt( - i32::from(datetime.year), - u32::from(datetime.month), - u32::from(datetime.day), - ) - .unwrap() - .and_hms_milli_opt( - u32::from(datetime.hour), - u32::from(datetime.minute), - u32::from(datetime.second), - 0, - ) - .unwrap() - .and_utc(), - )), - Err(e) => Err(e.to_string()), - } - } - _ => Ok(None), - }, - None => Ok(None), - } + let result = exif::Reader::new() + .continue_on_error(true) + .read_from_container(&mut bufreader); + + let exif = if let Err(exif::Error::PartialResult(partial)) = result { + let (exif, _) = partial.into_inner(); + exif + } else { + result? + }; - //if let Some(field) = exif.get_field(Tag::DateTime, In::PRIMARY) { - // match field.value { - // Value::Ascii(ref vec) if !vec.is_empty() => { - // if let Ok(datetime) = DateTime::from_ascii(&vec[0]) { - // println!("Year of DateTime is {}.", datetime.year); - // } - // } - // _ => {} - // } - //} - } - Err(e) => match e { - Error::NotFound(_) => Ok(None), - _ => Err(e.to_string()), + //for f in exif.fields() { + // println!( + // " {}/{}: {}", + // f.ifd_num.index(), + // f.tag, + // f.display_value().with_unit(&exif) + // ); + // println!(" {:?}", f.value); + //} + + match exif.get_field(Tag::DateTimeOriginal, In::PRIMARY) { + Some(field) => match field.value { + Value::Ascii(ref vec) if !vec.is_empty() => { + let datetime = DateTime::from_ascii(&vec[0])?; + Ok(Some( + NaiveDate::from_ymd_opt( + i32::from(datetime.year), + u32::from(datetime.month), + u32::from(datetime.day), + ) + .unwrap() + .and_hms_milli_opt( + u32::from(datetime.hour), + u32::from(datetime.minute), + u32::from(datetime.second), + 0, + ) + .unwrap() + .and_utc(), + )) + } + _ => Ok(None), }, + None => Ok(None), } + + //if let Some(field) = exif.get_field(Tag::DateTime, In::PRIMARY) { + // match field.value { + // Value::Ascii(ref vec) if !vec.is_empty() => { + // if let Ok(datetime) = DateTime::from_ascii(&vec[0]) { + // println!("Year of DateTime is {}.", datetime.year); + // } + // } + // _ => {} + // } + //} }