From c1a46d036ff1a97880eaf38c8328d356d770f08c Mon Sep 17 00:00:00 2001 From: Andrew Frahn Date: Sat, 10 Oct 2026 11:07:17 +1100 Subject: [PATCH] P1.1: extract dac-engine-library (XMP sidecars, devices, catalog SQLite reader) Co-Authored-By: Claude Opus 5.5 (1M context) --- Cargo.lock | 16 + crates/engine-library/Cargo.toml | 20 + .../{engine => engine-library}/src/devices.rs | 0 crates/engine-library/src/lib.rs | 9 + .../src/lightroom_sqlite.rs | 0 crates/engine-library/src/sidecar.rs | 526 +++++++++++++++++ crates/engine/Cargo.toml | 1 + crates/engine/src/lib.rs | 3 +- crates/engine/src/sidecar.rs | 527 +----------------- 9 files changed, 579 insertions(+), 523 deletions(-) create mode 100644 crates/engine-library/Cargo.toml rename crates/{engine => engine-library}/src/devices.rs (100%) create mode 100644 crates/engine-library/src/lib.rs rename crates/{engine => engine-library}/src/lightroom_sqlite.rs (100%) create mode 100644 crates/engine-library/src/sidecar.rs diff --git a/Cargo.lock b/Cargo.lock index 63c479d892..ff13abeb9d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1329,6 +1329,7 @@ dependencies = [ "dac-develop", "dac-engine-core", "dac-engine-develop", + "dac-engine-library", "dac-faces", "dac-fetch", "dac-geom", @@ -1384,6 +1385,21 @@ dependencies = [ "serde_json", ] +[[package]] +name = "dac-engine-library" +version = "0.4.0" +dependencies = [ + "dac-brand", + "dac-catalog", + "dac-develop", + "dac-engine-core", + "dac-engine-develop", + "dac-meta", + "log", + "serde", + "serde_json", +] + [[package]] name = "dac-faces" version = "0.4.0" diff --git a/crates/engine-library/Cargo.toml b/crates/engine-library/Cargo.toml new file mode 100644 index 0000000000..0d087460bc --- /dev/null +++ b/crates/engine-library/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "dac-engine-library" +version.workspace = true +edition.workspace = true +license.workspace = true +description = "Engine library: XMP sidecars, devices, Lightroom catalog SQLite reader (L4)" + +[lints] +workspace = true + +[dependencies] +dac-brand = { workspace = true } +dac-engine-core = { workspace = true } +dac-engine-develop = { workspace = true } +dac-catalog = { workspace = true } +dac-develop = { workspace = true } +dac-meta = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +log = { workspace = true } diff --git a/crates/engine/src/devices.rs b/crates/engine-library/src/devices.rs similarity index 100% rename from crates/engine/src/devices.rs rename to crates/engine-library/src/devices.rs diff --git a/crates/engine-library/src/lib.rs b/crates/engine-library/src/lib.rs new file mode 100644 index 0000000000..e9e240f606 --- /dev/null +++ b/crates/engine-library/src/lib.rs @@ -0,0 +1,9 @@ +//! Engine library: XMP sidecars (read, write, merge), removable devices and the read-only SQLite +//! reader behind Lightroom Classic catalog import. Re-exported by the `dac-engine` façade, where the +//! library commands (import, folders, collections, keywords, metadata) run against the session. +#![forbid(unsafe_code)] +#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)] + +pub mod devices; +pub mod lightroom_sqlite; +pub mod sidecar; diff --git a/crates/engine/src/lightroom_sqlite.rs b/crates/engine-library/src/lightroom_sqlite.rs similarity index 100% rename from crates/engine/src/lightroom_sqlite.rs rename to crates/engine-library/src/lightroom_sqlite.rs diff --git a/crates/engine-library/src/sidecar.rs b/crates/engine-library/src/sidecar.rs new file mode 100644 index 0000000000..49f967ac19 --- /dev/null +++ b/crates/engine-library/src/sidecar.rs @@ -0,0 +1,526 @@ +//! XMP sidecars: `.xmp` (default) or `.xmp` next to the original. +//! +//! **Write** (`Session::save_sidecar`, `photo.saveMetadataToFile`, or automatically after every +//! change when [`XmpPrefs::auto_write`] is on): rating, colour label, title, caption, copyright, +//! creator, keywords, capture time and GPS in the standard namespaces, plus our complete develop +//! settings (`lc:settings`, JSON), the pick/reject flag (`lc:flag`) and location (`lc:location`). +//! +//! An existing sidecar is never replaced wholesale (issue #92): The app's properties +//! ([`OWNED`], [`OWNED_IF_STATED`]) are merged into it ([`dac_meta::merge_xmp`]) and +//! everything else — another editor's `crs:` develop settings, `xmpMM` history, unknown +//! namespaces — is kept byte for byte. A sidecar that can't be read as XMP is first copied to +//! `.xmp.bak-