From 4ad30385173f0be073449c85a0db788d39bf4e73 Mon Sep 17 00:00:00 2001 From: aiongg Date: Sat, 14 Nov 2026 05:42:33 +0000 Subject: [PATCH] DES-10 T4: build linked assets and proxies from the T3 API; pin craft-libs 7df4cc9ab --- Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- crates/format/src/lib.rs | 18 +++++++++++------- crates/format/src/tests.rs | 9 +++++---- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c1807d138..7db579e58 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1093,10 +1093,10 @@ dependencies = [ [[package]] name = "craft-designcraft-format" version = "0.1.0" -source = "git+https://github.com/aiongg/craft-libs?rev=808ec65380fb8fe0d71816aeadb9b2c5dc0142a4#808ec65380fb8fe0d71816aeadb9b2c5dc0142a4" +source = "git+https://github.com/aiongg/craft-libs?rev=7df4cc9ab07152d313a5faa378855235984ab22f#7df4cc9ab07152d313a5faa378855235984ab22f" dependencies = [ "craft-document-bundle", - "craft-eps 0.1.0 (git+https://github.com/aiongg/craft-libs?rev=808ec65380fb8fe0d71816aeadb9b2c5dc0142a4)", + "craft-eps 0.1.0 (git+https://github.com/aiongg/craft-libs?rev=7df4cc9ab07152d313a5faa378855235984ab22f)", "serde", "serde_json", "thiserror 2.0.21", @@ -1123,9 +1123,9 @@ source = "git+https://github.com/storytold/craft-libs?rev=92d392cff132eaf53e13af [[package]] name = "craft-document-bundle" version = "0.1.0" -source = "git+https://github.com/aiongg/craft-libs?rev=808ec65380fb8fe0d71816aeadb9b2c5dc0142a4#808ec65380fb8fe0d71816aeadb9b2c5dc0142a4" +source = "git+https://github.com/aiongg/craft-libs?rev=7df4cc9ab07152d313a5faa378855235984ab22f#7df4cc9ab07152d313a5faa378855235984ab22f" dependencies = [ - "craft-zip 0.1.0 (git+https://github.com/aiongg/craft-libs?rev=808ec65380fb8fe0d71816aeadb9b2c5dc0142a4)", + "craft-zip 0.1.0 (git+https://github.com/aiongg/craft-libs?rev=7df4cc9ab07152d313a5faa378855235984ab22f)", "serde_json", "thiserror 2.0.21", "zip 9.1.1", @@ -1187,7 +1187,7 @@ dependencies = [ [[package]] name = "craft-eps" version = "0.1.0" -source = "git+https://github.com/aiongg/craft-libs?rev=808ec65380fb8fe0d71816aeadb9b2c5dc0142a4#808ec65380fb8fe0d71816aeadb9b2c5dc0142a4" +source = "git+https://github.com/aiongg/craft-libs?rev=7df4cc9ab07152d313a5faa378855235984ab22f#7df4cc9ab07152d313a5faa378855235984ab22f" [[package]] name = "craft-eps" @@ -1771,7 +1771,7 @@ dependencies = [ [[package]] name = "craft-zip" version = "0.1.0" -source = "git+https://github.com/aiongg/craft-libs?rev=808ec65380fb8fe0d71816aeadb9b2c5dc0142a4#808ec65380fb8fe0d71816aeadb9b2c5dc0142a4" +source = "git+https://github.com/aiongg/craft-libs?rev=7df4cc9ab07152d313a5faa378855235984ab22f#7df4cc9ab07152d313a5faa378855235984ab22f" dependencies = [ "flate2", "thiserror 2.0.21", diff --git a/Cargo.toml b/Cargo.toml index df8e31e6e..b1a7b21a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ repository = "https://github.com/storytold/designcraft" # Shared reader and writer; publish the immutable revision before this consumer. craft-pdf = { git = "https://github.com/storytold/craft-libs", rev = "40525913633942f84b06d4837a8d90534a55d63f", version = "=0.1.0", default-features = false } # TODO repin to storytold/craft-libs once #1264 merges -craft-designcraft-format = { git = "https://github.com/aiongg/craft-libs", rev = "808ec65380fb8fe0d71816aeadb9b2c5dc0142a4", version = "=0.1.0" } +craft-designcraft-format = { git = "https://github.com/aiongg/craft-libs", rev = "7df4cc9ab07152d313a5faa378855235984ab22f", version = "=0.1.0" } craft-eps = { git = "https://github.com/storytold/craft-libs", rev = "ba24fe2435adb3c81ad6057faf36365fbba736cf", version = "=0.1.0" } craft-epub = { git = "https://github.com/storytold/craft-libs", rev = "ba24fe2435adb3c81ad6057faf36365fbba736cf", version = "=0.1.0" } craft-idml = { git = "https://github.com/storytold/craft-libs", rev = "1ad5f35bf", version = "=0.1.0" } diff --git a/crates/format/src/lib.rs b/crates/format/src/lib.rs index 62ab14989..d42c3d25f 100644 --- a/crates/format/src/lib.rs +++ b/crates/format/src/lib.rs @@ -6,7 +6,7 @@ use std::collections::HashMap; use std::hash::BuildHasher; use std::sync::Arc; -use designcraft_doc::{AssetData, AssetId, Document, Storage}; +use designcraft_doc::{AssetData, AssetId, Document, LinkedSource, Storage}; #[cfg(test)] use serde_json::Value; #[cfg(test)] @@ -43,8 +43,10 @@ pub fn write(out: &mut W, doc: &Document, pre let mut owned_proxies = Vec::new(); for asset in compact.assets.values() { let id = asset.id.0.to_string(); - if let Some(proxy) = &asset.proxy { - owned_proxies.push((id.clone(), proxy.mime.clone(), proxy.data.clone())); + if let Some(proxy) = &asset.proxy + && let Some(bytes) = proxy.data.embedded_bytes() + { + owned_proxies.push((id.clone(), proxy.mime.clone(), bytes.clone())); } if asset.storage == Storage::Linked { continue; @@ -93,13 +95,15 @@ pub fn load(bytes: &[u8]) -> Result { let Ok(id) = raw_id.parse::() else { continue }; let Some(asset) = doc.assets.get_mut(&AssetId(id)) else { continue }; if asset.proxy.is_some() { - Arc::make_mut(asset).proxy.iter_mut().for_each(|proxy| proxy.data = Arc::new(bytes.clone())); + Arc::make_mut(asset).proxy.iter_mut().for_each(|proxy| proxy.data = AssetData::embedded(bytes.clone())); } } for asset in doc.assets.values_mut() { - if asset.storage == Storage::Linked { - // T3/T7: the loader (and the linked file's length) attach here. - Arc::make_mut(asset).data = AssetData::linked(0); + // The document's own path is unknown here; open re-resolves relative links against it. + if asset.storage == Storage::Linked + && let Some(source) = LinkedSource::of(asset, None) + { + Arc::make_mut(asset).data = AssetData::linked(source); } } doc.merge_duplicate_assets(); diff --git a/crates/format/src/tests.rs b/crates/format/src/tests.rs index dd9cb81ce..fd875a2c2 100644 --- a/crates/format/src/tests.rs +++ b/crates/format/src/tests.rs @@ -899,17 +899,18 @@ fn zip_version(bytes: &[u8]) -> u32 { fn linked_asset_roundtrips_as_record_and_proxy_without_original() { let mut d = Document::new(&NewDocument::default()); let aid = AssetId(d.alloc()); - let asset = Asset { + let mut asset = Asset { id: aid, name: "big.tif".into(), mime: "image/tiff".into(), link: Some("/pics/big.tif".into()), + link_fingerprint: Some(designcraft_doc::Fingerprint { size: 1 << 30, mtime: 0 }), storage: Storage::Linked, - proxy: Some(designcraft_doc::Proxy { mime: "image/png".into(), pixels: (2, 2), data: Arc::new(vec![9, 8, 7]) }), - data: AssetData::linked(1 << 30), + proxy: Some(designcraft_doc::Proxy { mime: "image/png".into(), pixels: (2, 2), data: AssetData::embedded(vec![9, 8, 7]) }), pixels: Some((4000, 3000)), ..Default::default() }; + asset.data = AssetData::linked(designcraft_doc::LinkedSource::of(&asset, None).unwrap()); d.assets.insert(aid, Arc::new(asset)); place(&mut d, aid, 0.0); let bytes = save(&d).unwrap(); @@ -921,7 +922,7 @@ fn linked_asset_roundtrips_as_record_and_proxy_without_original() { assert_eq!(a.link.as_deref(), Some("/pics/big.tif")); assert!(a.data.is_linked()); let proxy = a.proxy.as_ref().unwrap(); - assert_eq!((proxy.mime.as_str(), proxy.pixels, proxy.data.as_slice()), ("image/png", (2, 2), &[9u8, 8, 7][..])); + assert_eq!((proxy.mime.as_str(), proxy.pixels, proxy.data.embedded_bytes().map(|b| b.as_slice())), ("image/png", (2, 2), Some(&[9u8, 8, 7][..]))); } #[test]