exif_oxide/lib.rs
1//! exif-oxide: High-performance Rust implementation of ExifTool
2//!
3//! This library provides metadata extraction from image files with ExifTool compatibility.
4//! The architecture uses runtime registries for PrintConv/ValueConv implementations to avoid
5//! code generation bloat while maintaining flexible extensibility.
6//!
7//! ## Testing
8//!
9//! This crate includes both unit tests and integration tests:
10//!
11//! - **Unit tests**: Always available, test individual components in isolation
12//! - **Integration tests**: Require the `integration-tests` feature flag and external test assets
13//!
14//! To run all tests including integration tests:
15//! ```bash
16//! cargo test --features integration-tests
17//! ```
18//!
19//! Integration tests compare our output against ExifTool reference data and require
20//! test images and the ExifTool submodule to be available. They are automatically
21//! excluded from published crates to keep package size manageable.
22
23pub mod composite_tags;
24pub mod conditions;
25pub mod examples;
26pub mod exif;
27pub mod file_detection;
28pub mod file_types;
29pub mod formats;
30pub mod generated;
31
32pub mod implementations;
33pub mod processor_registry;
34pub mod raw;
35pub mod registry;
36pub mod tiff_types;
37pub mod tiff_utils;
38pub mod types;
39pub mod value_extraction;
40pub mod xmp;
41
42pub use file_detection::{FileDetectionError, FileTypeDetectionResult, FileTypeDetector};
43pub use generated::*;
44pub use registry::Registry;
45pub use types::{ExifData, ExifError, TagValue};
46
47pub use generated::COMPOSITE_TAG_LOOKUP as COMPOSITE_TAG_BY_NAME;
48
49// Initialize all conversion implementations when library is loaded
50use std::sync::LazyLock;
51static _INIT: LazyLock<()> = LazyLock::new(|| {
52 implementations::register_all_conversions();
53});
54
55/// Ensure conversions are registered (call this before using the library)
56pub fn init() {
57 LazyLock::force(&_INIT);
58}
59
60use serde_json::Value;
61use std::path::Path;
62
63/// Extract metadata from a file and return it as JSON (matching CLI output format)
64///
65/// This is a high-level convenience function that matches the CLI output format,
66/// making it easy to compare with ExifTool output in tests.
67pub fn extract_metadata_json(file_path: &str) -> Result<Value, ExifError> {
68 // Ensure conversions are registered
69 init();
70
71 // Use the existing extract_metadata function from formats module
72 let path = Path::new(file_path);
73 let mut exif_data = formats::extract_metadata(path, false)?;
74
75 // Prepare for serialization (converts TagEntry to legacy format with PrintConv)
76 exif_data.prepare_for_serialization(None);
77
78 // Convert ExifData to JSON
79 let json = serde_json::to_value(&exif_data)
80 .map_err(|e| ExifError::ParseError(format!("Failed to serialize to JSON: {e}")))?;
81
82 Ok(json)
83}