use std::env;
use anyhow::{anyhow, Context, Result};
use xmp_toolkit::{xmp_ns, OpenFileOptions, XmpFile, XmpMeta};
fn read_xmp_from_file() -> Result<()> {
let args: Vec<String> = env::args().collect();
let path = match args.len() {
2 => Ok(&args[1]),
n => Err(anyhow!(
"expected 1 argument (file name), got {} arguments",
n - 1
)),
}?;
let mut f = XmpFile::new()?;
f.open_file(
path,
OpenFileOptions::default().only_xmp().use_smart_handler(),
)
.or_else(|_err| {
eprintln!(
"No smart handler available for file {}. Trying packet scanning.",
path
);
f.open_file(path, OpenFileOptions::default().use_packet_scanning())
})
.with_context(|| format!("could not find XMP in file {}", path))?;
let xmp = f
.xmp()
.ok_or_else(|| anyhow!("unable to process XMP in file {}", path))?;
if let Some(creator_tool) = xmp.property(xmp_ns::XMP, "CreatorTool") {
println!("CreatorTool = {}", creator_tool.value);
}
if let Some(first_creator) = xmp.property_array(xmp_ns::DC, "creator").next() {
println!("dc:creator = {}", first_creator.value);
} else {
println!("No creator found");
}
for (index, v) in xmp.property_array(xmp_ns::DC, "subject").enumerate() {
println!("dc::subject[{}] = {}", index, v.value);
}
if let Some((value, _actual_lang)) =
xmp.localized_text(xmp_ns::DC, "title", Some("en"), "en-US")
{
println!("dc:title in English = {}", value.value);
}
if let Some((value, _actual_lang)) =
xmp.localized_text(xmp_ns::DC, "title", Some("fr"), "fr-FR")
{
println!("dc:title in French = {}", value.value);
}
if let Some(value) = xmp.property_date(xmp_ns::XMP, "MetadataDate") {
println!("meta:MetadataDate = {}", value.value);
}
if xmp.contains_struct_field(xmp_ns::EXIF, "Flash", xmp_ns::EXIF, "Fired") {
let path = XmpMeta::compose_struct_field_path(xmp_ns::EXIF, "Flash", xmp_ns::EXIF, "Fired")
.unwrap();
if let Some(value) = xmp.property_bool(xmp_ns::EXIF, &path) {
println!("Flash Used = {}", value.value);
}
}
Ok(())
}
fn main() {
if let Err(err) = read_xmp_from_file().context("could not read XMP from file") {
eprintln!("Error: {:?}", err);
std::process::exit(1);
}
}