diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 31000a2..7b23e9e 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -19,4 +19,4 @@ jobs: - name: Build run: cargo build --verbose - name: Run tests - run: cargo test --verbose + run: cargo test --verbose -- --nocapture diff --git a/Cargo.toml b/Cargo.toml index 84f5fbf..d1d292d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nom-exif" -version = "1.2.6" +version = "1.3.0" edition = "2021" license-file = "LICENSE" description = "Exif/metadata parsing library written in pure Rust, both JPEG/HEIF/HEIC images and MOV/MP4 videos are supported." @@ -18,6 +18,7 @@ thiserror = "1.0" serde = { version = "1.0", features = ["derive"], optional = true } regex = { version = "1.10" } chrono = "0.4" +tracing = { version = "0.1.40" } [features] json_dump = ["serde"] @@ -29,6 +30,7 @@ chrono = "0.4" serde_json = "1.0" regex = { version = "1.10" } clap = { version = "4.4", features = ["derive"] } +tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } [[example]] name = "rexiftool" diff --git a/src/bbox.rs b/src/bbox.rs index 1bbec35..79b3095 100644 --- a/src/bbox.rs +++ b/src/bbox.rs @@ -49,15 +49,16 @@ pub struct BoxHeader { } impl BoxHeader { + #[tracing::instrument(skip_all)] pub fn parse<'a>(input: &'a [u8]) -> IResult<&'a [u8], BoxHeader> { let (remain, size) = number::streaming::be_u32(input)?; let (remain, box_type) = map_res(streaming::take(4_usize), |res: &'a [u8]| { // String::from_utf8 will fail on "©xyz" Ok::(res.iter().map(|b| b.as_char()).collect::()) - // String::from_utf8(res.to_vec()).map_err(|e| { - // eprintln!("{e:?}"); - // e + // String::from_utf8(res.to_vec()).map_err(|error| { + // tracing::error!(?error, ?res, "Failed to construct string"); + // error // }) })(remain)?; @@ -77,20 +78,17 @@ impl BoxHeader { } if box_size > (MAX_BODY_LEN + header_size) as u64 { - eprintln!( - "box size of box '{}' is too big: {}", - box_type - .chars() - .map(|c| { - if c.is_ascii_graphic() { - c.as_char() - } else { - '*' - } - }) - .collect::(), - box_size - ); + let box_type = box_type + .chars() + .map(|c| { + if c.is_ascii_graphic() { + c.as_char() + } else { + '*' + } + }) + .collect::(); + tracing::error!(?box_type, ?box_size, "Box is too big"); return fail(remain); } @@ -156,10 +154,11 @@ pub struct BoxHolder<'a> { } impl<'a> BoxHolder<'a> { + #[tracing::instrument(skip_all)] pub fn parse(input: &'a [u8]) -> IResult<&'a [u8], BoxHolder<'a>> { let (_, header) = BoxHeader::parse(input)?; let (remain, data) = streaming::take(header.box_size)(input)?; - // println!("got {} {}", header.box_type, data.len()); + tracing::debug!(?header.box_type, data_len = ?data.len(), "Got"); Ok((remain, BoxHolder { header, data })) } @@ -339,11 +338,13 @@ mod tests { #[test_case("exif.heic")] fn travel_heic(path: &str) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = read_sample(path).unwrap(); let mut boxes = Vec::new(); let (remain, bbox) = travel_while(&buf, |bbox| { - // println!("got {}", bbox.header.box_type); + tracing::info!(bbox.header.box_type, "Got"); boxes.push((bbox.header.box_type.to_owned(), bbox.to_owned())); bbox.box_type() != "mdat" }) @@ -365,7 +366,7 @@ mod tests { let (remain, bbox) = travel_while( &meta.body_data()[4..], // Safe-slice in test_case |bbox| { - // println!("got {}", bbox.header.box_type); + tracing::info!(bbox.header.box_type, "Got"); boxes.push(bbox.header.box_type.to_owned()); bbox.box_type() != "iloc" }, @@ -384,11 +385,13 @@ mod tests { #[test_case("meta.mov")] fn travel_mov(path: &str) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = read_sample(path).unwrap(); let mut boxes = Vec::new(); let (remain, bbox) = travel_while(&buf, |bbox| { - // println!("got {}", bbox.header.box_type); + tracing::info!(bbox.header.box_type, "Got"); boxes.push((bbox.header.box_type.to_owned(), bbox.to_owned())); bbox.box_type() != "moov" }) @@ -408,7 +411,7 @@ mod tests { let mut boxes = Vec::new(); let (remain, bbox) = travel_while(moov.body_data(), |bbox| { - // println!("got {}", bbox.header.box_type); + tracing::info!(bbox.header.box_type, "Got"); boxes.push(bbox.header.box_type.to_owned()); bbox.box_type() != "meta" }) @@ -424,7 +427,7 @@ mod tests { let meta = bbox; let mut boxes = Vec::new(); let (remain, _) = travel_while(meta.body_data(), |bbox| { - // println!("got {}", bbox.header.box_type); + tracing::info!(bbox.header.box_type, "Got"); boxes.push(bbox.header.box_type.to_owned()); bbox.box_type() != "ilst" }) @@ -437,11 +440,13 @@ mod tests { #[test_case("meta.mp4")] fn travel_mp4(path: &str) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = read_sample(path).unwrap(); let mut boxes = Vec::new(); let (remain, bbox) = travel_while(&buf, |bbox| { - // println!("got {}", bbox.header.box_type); + tracing::info!(bbox.header.box_type, "Got"); boxes.push((bbox.header.box_type.to_owned(), bbox.to_owned())); bbox.box_type() != "moov" }) @@ -461,7 +466,7 @@ mod tests { let mut boxes = Vec::new(); let (remain, bbox) = travel_while(moov.body_data(), |bbox| { - // println!("got {}", bbox.header.box_type); + tracing::info!(bbox.header.box_type, "Got"); boxes.push((bbox.header.box_type.to_owned(), bbox.to_owned())); bbox.box_type() != "udta" }) @@ -482,7 +487,7 @@ mod tests { let meta = bbox; let mut boxes = Vec::new(); let (remain, _) = travel_while(meta.body_data(), |bbox| { - // println!("got {}", bbox.header.box_type); + tracing::info!(bbox.header.box_type, "Got"); boxes.push(bbox.header.box_type.to_owned()); bbox.box_type() != "©xyz" }) @@ -494,7 +499,7 @@ mod tests { let mut boxes = Vec::new(); let (remain, bbox) = travel_while(trak.body_data(), |bbox| { - // println!("got {}", bbox.header.box_type); + tracing::info!(bbox.header.box_type, "Got"); boxes.push(bbox.header.box_type.to_owned()); bbox.box_type() != "mdia" }) @@ -507,7 +512,7 @@ mod tests { let mdia = bbox.unwrap(); let mut boxes = Vec::new(); let (remain, _) = travel_while(mdia.body_data(), |bbox| { - // println!("got {}", bbox.header.box_type); + tracing::info!(bbox.header.box_type, "Got"); boxes.push(bbox.header.box_type.to_owned()); bbox.box_type() != "minf" }) @@ -522,10 +527,12 @@ mod tests { // atom. #[test_case("meta.mp4")] fn find_android_gps_box(path: &str) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = read_sample(path).unwrap(); let (_, bbox) = find_box(&buf, "moov/udta/©xyz").unwrap(); let bbox = bbox.unwrap(); - // println!("bbox: {:?}", bbox.header); + tracing::info!(?bbox.header, "bbox"); // gps info assert_eq!( @@ -536,6 +543,8 @@ mod tests { #[test] fn box_header() { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let data = [ 0x00, 0x00, 0x01, 0xdd, 0x6d, 0x65, 0x74, 0x61, 0x02, 0x04, 0x04, 0x00, ]; diff --git a/src/bbox/iinf.rs b/src/bbox/iinf.rs index afcb51e..9d96f5b 100644 --- a/src/bbox/iinf.rs +++ b/src/bbox/iinf.rs @@ -61,6 +61,7 @@ pub(crate) struct InfeBox { } impl ParseBody for InfeBox { + #[tracing::instrument(skip_all)] fn parse_body<'a>(remain: &'a [u8], header: FullBoxHeader) -> IResult<&'a [u8], InfeBox> { let version = header.version; @@ -79,10 +80,7 @@ impl ParseBody for InfeBox { }), )(remain)?; - // println!( - // "got {} type: {:?} ver: {version}", - // header.box_type, item_type, - // ); + tracing::debug!(?header.box_type, ?item_type, ?version, "Got"); let (remain, item_name) = parse_cstr(remain).map_err(|e| { if e.is_incomplete() { diff --git a/src/bbox/iloc.rs b/src/bbox/iloc.rs index 6191241..1b5db5d 100644 --- a/src/bbox/iloc.rs +++ b/src/bbox/iloc.rs @@ -25,6 +25,7 @@ pub struct IlocBox { const MAX_ILOC_EXTENTS_PER_ITEM: u16 = 32; impl ParseBody for IlocBox { + #[tracing::instrument(skip_all)] fn parse_body(remain: &[u8], header: FullBoxHeader) -> IResult<&[u8], IlocBox> { let version = header.version; @@ -59,7 +60,7 @@ impl ParseBody for IlocBox { let (remain, extent_count) = be_u16(remain)?; if extent_count > MAX_ILOC_EXTENTS_PER_ITEM { - // eprintln!("extent_count: {extent_count}"); + tracing::debug!(?extent_count, "extent_count"); context("extent_count > 32", fail::<_, (), _>)(remain)?; } diff --git a/src/bbox/ilst.rs b/src/bbox/ilst.rs index 95930e4..7f7a3b7 100644 --- a/src/bbox/ilst.rs +++ b/src/bbox/ilst.rs @@ -83,6 +83,7 @@ impl IlstItem { /// Parse ilst item data to value, see [Well-known /// types](https://developer.apple.com/documentation/quicktime-file-format/well-known_types) +#[tracing::instrument(skip(data))] fn parse_value(type_code: u32, data: &[u8]) -> crate::Result { use EntryValue::*; let v = match type_code { @@ -96,9 +97,13 @@ fn parse_value(type_code: u32, data: &[u8]) -> crate::Result { 3 => be_i24(data)?.1.into(), 4 => be_i32(data)?.1.into(), 8 => be_i64(data)?.1.into(), - x => { - let msg = format!("Invalid ilst item data; data type is BE Signed Integer while data len is : {x}"); - // eprintln!("{msg}"); + data_len => { + let data_type = "BE Signed Integer"; + tracing::error!(data_type, data_len, "Invalid ilst item data."); + let msg = format!( + "Invalid ilst item data; \ + data type is {data_type} while data len is : {data_len}", + ); return Err(msg.into()); } }, @@ -108,18 +113,22 @@ fn parse_value(type_code: u32, data: &[u8]) -> crate::Result { 3 => be_u24(data)?.1.into(), 4 => be_u32(data)?.1.into(), 8 => be_u64(data)?.1.into(), - x => { - let msg = format!("Invalid ilst item data; data type is BE Unsigned Integer while data len is : {x}"); - // eprintln!("{msg}"); + data_len => { + let data_type = "BE Unsigned Integer"; + tracing::error!(data_type, data_len, "Invalid ilst item data."); + let msg = format!( + "Invalid ilst item data; \ + data type is {data_type} while data len is : {data_len}", + ); return Err(msg.into()); } }, 23 => be_f32(data)?.1.into(), 24 => be_f64(data)?.1.into(), - o => { - let msg = format!("Unsupported ilst item data type: {o}"); - // eprintln!("{msg}"); - return Err(msg.into()); + data_type => { + let msg = format!("Unsupported ilst item data type"); + tracing::error!(data_type, "{}.", msg); + return Err(format!("{}: {data_type}", msg).into()); } }; Ok(v) @@ -134,6 +143,8 @@ mod tests { #[test_case("meta.mov")] fn ilst_box(path: &str) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = read_sample(path).unwrap(); let (_, bbox) = travel_while(&buf, |b| b.box_type() != "moov").unwrap(); let bbox = bbox.unwrap(); @@ -143,7 +154,7 @@ mod tests { let bbox = bbox.unwrap(); let (rem, ilst) = IlstBox::parse_box(bbox.data).unwrap(); - println!("ilst: {ilst:?}"); + tracing::info!(?ilst, "ilst"); assert_eq!(rem, b""); assert_eq!( @@ -163,6 +174,8 @@ mod tests { #[test_case("embedded-in-heic.mov")] fn heic_mov_ilst(path: &str) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = read_sample(path).unwrap(); let (_, moov) = travel_while(&buf, |b| b.box_type() != "moov").unwrap(); let moov = moov.unwrap(); diff --git a/src/bbox/keys.rs b/src/bbox/keys.rs index 93378da..b74bf39 100644 --- a/src/bbox/keys.rs +++ b/src/bbox/keys.rs @@ -78,6 +78,8 @@ mod tests { #[test_case("meta.mov", 4133, 0x01b9, 0xc9)] fn keys_box(path: &str, moov_size: u64, meta_size: u64, keys_size: u64) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = read_sample(path).unwrap(); let (_, moov) = travel_while(&buf, |b| b.box_type() != "moov").unwrap(); let moov = moov.unwrap(); @@ -127,6 +129,8 @@ mod tests { #[test_case("embedded-in-heic.mov", 0x1790, 0x0372, 0x1ce)] fn heic_mov_keys(path: &str, moov_size: u64, meta_size: u64, keys_size: u64) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = read_sample(path).unwrap(); let (_, moov) = travel_while(&buf, |b| b.box_type() != "moov").unwrap(); let moov = moov.unwrap(); diff --git a/src/bbox/meta.rs b/src/bbox/meta.rs index aeeb7e7..2d93467 100644 --- a/src/bbox/meta.rs +++ b/src/bbox/meta.rs @@ -65,6 +65,7 @@ impl ParseBody for MetaBox { } impl MetaBox { + #[tracing::instrument(skip_all)] pub fn exif_data<'a>(&self, input: &'a [u8]) -> IResult<&'a [u8], Option<&'a [u8]>> { self.iinf .as_ref() @@ -86,10 +87,10 @@ impl MetaBox { } } else if construction_method == 1 { // idat offset - eprintln!("idat offset construction method is not supported yet"); + tracing::debug!("idat offset construction method is not supported yet"); fail(input) } else { - eprintln!("item offset construction method is not supported yet"); + tracing::debug!("item offset construction method is not supported yet"); fail(input) } }) @@ -123,9 +124,11 @@ mod tests { #[test_case("exif.heic", 2618)] fn meta(path: &str, meta_size: usize) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = read_sample(path).unwrap(); let (_, bbox) = travel_while(&buf, |bbox| { - // println!("got {}", bbox.header.box_type); + tracing::info!(bbox.header.box_type, "Got"); bbox.box_type() != "meta" }) .unwrap(); diff --git a/src/bbox/mvhd.rs b/src/bbox/mvhd.rs index 19fc998..2dc13f4 100644 --- a/src/bbox/mvhd.rs +++ b/src/bbox/mvhd.rs @@ -104,6 +104,8 @@ mod tests { 1063 )] fn mvhd_box(path: &str, time_utc: &str, time_east8: &str, milliseconds: u32) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = read_sample(path).unwrap(); let (_, bbox) = travel_while(&buf, |b| b.box_type() != "moov").unwrap(); diff --git a/src/bbox/tkhd.rs b/src/bbox/tkhd.rs index 4fe071a..15dd2c5 100644 --- a/src/bbox/tkhd.rs +++ b/src/bbox/tkhd.rs @@ -150,6 +150,8 @@ mod tests { #[test_case("meta.mov", 720, 1280)] #[test_case("meta.mp4", 1920, 1080)] fn tkhd_box(path: &str, width: u32, height: u32) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = read_sample(path).unwrap(); let (_, bbox) = travel_while(&buf, |b| b.box_type() != "moov").unwrap(); diff --git a/src/exif/gps.rs b/src/exif/gps.rs index aad00ec..5eb8461 100644 --- a/src/exif/gps.rs +++ b/src/exif/gps.rs @@ -128,6 +128,8 @@ mod tests { #[test] fn gps_iso6709() { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let palace = GPSInfo { latitude_ref: 'N', latitude: LatLng(URational(39, 1), URational(55, 1), URational(0, 1)), diff --git a/src/exif/parser.rs b/src/exif/parser.rs index b7cc160..8f2924c 100644 --- a/src/exif/parser.rs +++ b/src/exif/parser.rs @@ -149,10 +149,12 @@ struct Parser<'a> { } impl<'a> Parser<'a> { + #[tracing::instrument(skip(self))] fn parse_ifd(&'a self, pos: usize) -> IResult<&'a [u8], Option> { self.parse_ifd_recursively(pos, 1) } + #[tracing::instrument(skip(self))] fn parse_ifd_recursively( &'a self, pos: usize, @@ -161,7 +163,7 @@ impl<'a> Parser<'a> { // Prevent stack overflow caused by infinite recursion, which will // occur when running fuzzing tests. if depth > MAX_IFD_DEPTH { - eprintln!("too many nested IFDs, parsing aborted at depth {}", depth); + tracing::error!(?depth, "Too many nested IFDs. Parsing aborted."); return fail(&self.data[pos..]); // Safe-slice } @@ -200,6 +202,7 @@ impl<'a> Parser<'a> { Ok((remain, Some(ImageFileDirectory { entries }))) } + #[tracing::instrument(skip(self))] fn parse_ifd_entry(&self, pos: usize, depth: usize) -> IResult<&[u8], Option> { let input = self.data; let endian = self.endian; @@ -218,7 +221,7 @@ impl<'a> Parser<'a> { |(tag, data_format, components_num, value_or_offset)| -> IResult<&[u8], Option> { // get component_size according to data format let Ok(component_size) = entry_component_size(data_format) else { - // eprintln!("parse exif entry failed; {e}"); + // tracing::error!(error = ?e, "Parse Exif entry failed."); // return fail(input); return Ok((remain, None)) }; @@ -339,6 +342,8 @@ mod tests { #[test] fn header() { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = [0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08]; let (_, header) = Header::parse(&buf).unwrap(); @@ -353,8 +358,10 @@ mod tests { #[test_case("exif.jpg")] fn test_parse_exif(path: &str) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = read_sample(path).unwrap(); - // println!("file size: {}", buf.len()); + tracing::info!(bytes = buf.len(), "File size"); // skip first 12 bytes let exif = parse_exif(&buf[12..]).unwrap(); // Safe-slice in test_case @@ -457,6 +464,8 @@ mod tests { altitude_ref: u8, altitude: URational, ) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = read_sample(path).unwrap(); // skip first 12 bytes diff --git a/src/heif.rs b/src/heif.rs index b25a2ba..59a62f2 100644 --- a/src/heif.rs +++ b/src/heif.rs @@ -48,6 +48,7 @@ use crate::{ /// .collect::>() /// ); /// ``` +#[tracing::instrument(skip_all)] pub fn parse_heif_exif(mut reader: R) -> crate::Result> { const INIT_BUF_SIZE: usize = 4096; const GROW_BUF_SIZE: usize = 1024; @@ -75,7 +76,7 @@ pub fn parse_heif_exif(mut reader: R) -> crate::Result Err(e)?, }; - // println!("to_read: {to_read}"); + tracing::debug!(bytes = ?to_read, "to_read"); assert!(to_read > 0); let to_read = cmp::max(GROW_BUF_SIZE, to_read); @@ -127,6 +128,8 @@ mod tests { #[test_case("exif.heic")] fn heif(path: &str) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let reader = open_sample(path).unwrap(); let exif = parse_heif_exif(reader).unwrap().unwrap(); @@ -186,6 +189,8 @@ mod tests { #[test_case("ramdisk.img")] fn invalid_heic(path: &str) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let reader = open_sample(path).unwrap(); parse_heif_exif(reader).expect_err("should be ParseFailed error"); } @@ -193,6 +198,8 @@ mod tests { #[test_case("compatible-brands.heic", Some(FileType::Heif))] #[test_case("compatible-brands-fail.heic", None)] fn heic_compatible_brands(path: &str, ft: Option) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = read_sample(path).unwrap(); let got = check_heif(&buf); if let Some(ft) = ft { @@ -205,6 +212,8 @@ mod tests { #[test_case("no-exif.heic", 0x24-10)] #[test_case("exif.heic", 0xa3a-10)] fn heic_exif_data(path: &str, exif_size: usize) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = read_sample(path).unwrap(); let (_, exif) = extract_exif_data(&buf[..]).unwrap(); diff --git a/src/jpeg.rs b/src/jpeg.rs index eeef524..43a5224 100644 --- a/src/jpeg.rs +++ b/src/jpeg.rs @@ -121,6 +121,7 @@ fn find_exif_segment(input: &[u8]) -> IResult<&[u8], Option>> { } } +#[tracing::instrument(skip_all)] fn travel_until<'a, F>(input: &'a [u8], mut predicate: F) -> IResult<&'a [u8], Segment<'a>> where F: FnMut(&Segment<'a>) -> bool, @@ -133,7 +134,7 @@ where // Sanity check assert!(rem.len() < remain.len()); remain = rem; - // println!("got segment {:x}", segment.marker_code); + tracing::debug!(?segment.marker_code, "Got segment."); if predicate(&segment) { break Ok((remain, segment)); @@ -265,6 +266,8 @@ mod tests { #[test_case("exif.jpg")] fn jpeg(path: &str) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let f = open_sample(path).unwrap(); let exif = parse_jpeg_exif(f).unwrap().unwrap(); @@ -355,6 +358,8 @@ mod tests { #[test_case("no-exif.jpg", 0)] #[test_case("exif.jpg", 0x4569-2)] fn jpeg_find_exif(path: &str, exif_size: usize) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = read_sample(path).unwrap(); let (_, segment) = find_exif_segment(&buf[..]).unwrap(); @@ -368,6 +373,8 @@ mod tests { #[test_case("no-exif.jpg", 0)] #[test_case("exif.jpg", 0x4569-8)] fn jpeg_exif_data(path: &str, exif_size: usize) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = read_sample(path).unwrap(); let (_, exif) = extract_exif_data(&buf[..]).unwrap(); @@ -381,6 +388,8 @@ mod tests { #[test_case("no-exif.jpg", 4089704, 0x000c0301, 0xb3b3e43f)] #[test_case("exif.jpg", 3564768, 0x000c0301, 0x84a297a9)] fn jpeg_image_data(path: &str, len: usize, start: u32, end: u32) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let f = open_sample(path).unwrap(); let data = read_image_data(f).unwrap(); assert_eq!(data.len(), len); @@ -393,6 +402,8 @@ mod tests { #[test] fn broken_jpg() { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let f = open_sample("broken.jpg").unwrap(); parse_jpeg_exif(f).unwrap(); } diff --git a/src/mov.rs b/src/mov.rs index d8f6c1a..8233900 100644 --- a/src/mov.rs +++ b/src/mov.rs @@ -156,6 +156,7 @@ pub fn parse_mov_metadata(reader: R) -> crate::Result(mut reader: R) -> Result<(FileType, Vec), crate::Error> { const INIT_BUF_SIZE: usize = 4096; const GROW_BUF_SIZE: usize = 4096; @@ -180,7 +181,7 @@ fn extract_moov_body(mut reader: R) -> Result<(FileType, Vec Ok(range) => break range.start + offset..range.end + offset, Err(Error::Need(n)) => n, Err(Error::Skip(n)) => { - // println!("skip: {n}"); + tracing::debug!(?n, "skip"); reader.seek(std::io::SeekFrom::Current(n as i64))?; offset = buf.len(); GROW_BUF_SIZE @@ -188,7 +189,7 @@ fn extract_moov_body(mut reader: R) -> Result<(FileType, Vec Err(Error::ParseFailed(e)) => return Err(e), }; - // println!("to_read: {to_read}"); + tracing::debug!(?to_read, "to_read"); assert!(to_read > 0); let to_read = cmp::max(GROW_BUF_SIZE, to_read); @@ -258,6 +259,7 @@ pub enum Error { /// moov atom it may contain. /// /// Regarding error handling, please refer to [Error] for more information. +#[tracing::instrument(skip_all)] fn extract_moov_body_from_buf(input: &[u8]) -> Result, Error> { // parse metadata from moov/meta/keys & moov/meta/ilst let remain = input; @@ -274,7 +276,7 @@ fn extract_moov_body_from_buf(input: &[u8]) -> Result, Error> { let mut to_skip = 0; let mut skipped = 0; let (remain, header) = travel_header(remain, |h, remain| { - // println!("got: {} {}", h.box_type, h.box_size); + tracing::debug!(?h.box_type, ?h.box_size, "Got"); if h.box_type == "moov" { // stop travelling skipped += h.header_size; @@ -367,6 +369,8 @@ mod tests { #[test_case("meta.mov")] fn mov_parse(path: &str) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let reader = open_sample(path).unwrap(); let entries = parse_metadata(reader).unwrap(); assert_eq!( @@ -388,8 +392,10 @@ mod tests { #[test_case("meta.mov")] fn mov_extract_mov(path: &str) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = read_sample(path).unwrap(); - println!("file size: {}", buf.len()); + tracing::info!(bytes = buf.len(), "File size."); let range = extract_moov_body_from_buf(&buf).unwrap(); let (_, entries) = parse_moov_body(&buf[range]).unwrap(); assert_eq!( @@ -409,21 +415,27 @@ mod tests { #[test_case("compatible-brands.mov")] fn mov_compatible_brands(path: &str) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = read_sample(path).unwrap(); - println!("file size: {}", buf.len()); + tracing::info!(bytes = buf.len(), "File size."); let ft = check_qt_mp4(&buf).unwrap(); assert_eq!(ft, FileType::QuickTime); } #[test_case("compatible-brands-fail.mov")] fn mov_compatible_brands_fail(path: &str) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let buf = read_sample(path).unwrap(); - println!("file size: {}", buf.len()); + tracing::info!(bytes = buf.len(), "File size."); check_qt_mp4(&buf).unwrap_err(); } #[test_case("meta.mp4")] fn parse_mp4(path: &str) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let entries = parse_metadata(open_sample(path).unwrap()).unwrap(); assert_eq!( entries @@ -441,6 +453,8 @@ mod tests { #[test_case("embedded-in-heic.mov")] fn parse_embedded_mov(path: &str) { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let entries = parse_mov_metadata(open_sample(path).unwrap()).unwrap(); assert_eq!( entries @@ -466,6 +480,8 @@ mod tests { #[test] fn test_iso_8601_tz_to_rfc3339() { + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); + let s = "2023-11-02T19:58:34+08".to_string(); assert_eq!(tz_iso_8601_to_rfc3339(s), "2023-11-02T19:58:34+08:00");