fret_ui_kit/
image_metadata.rs1use fret_core::ImageId;
2use fret_runtime::GlobalsHost;
3use std::collections::HashMap;
4
5#[derive(Debug, Default, Clone)]
14pub struct ImageMetadataStore {
15 by_id: HashMap<ImageId, ImageMetadata>,
16}
17
18#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
19pub struct ImageMetadata {
20 pub intrinsic_size_px: Option<(u32, u32)>,
21}
22
23impl ImageMetadataStore {
24 pub fn set_intrinsic_size_px(&mut self, image: ImageId, size_px: (u32, u32)) {
25 self.by_id.entry(image).or_default().intrinsic_size_px = Some(size_px);
26 }
27
28 pub fn clear_intrinsic_size_px(&mut self, image: ImageId) {
29 if let Some(entry) = self.by_id.get_mut(&image) {
30 entry.intrinsic_size_px = None;
31 if *entry == ImageMetadata::default() {
32 self.by_id.remove(&image);
33 }
34 }
35 }
36
37 pub fn intrinsic_size_px(&self, image: ImageId) -> Option<(u32, u32)> {
38 self.by_id.get(&image)?.intrinsic_size_px
39 }
40
41 pub fn aspect_ratio(&self, image: ImageId) -> Option<f32> {
42 let (w, h) = self.intrinsic_size_px(image)?;
43 if w == 0 || h == 0 {
44 return None;
45 }
46 Some((w as f32) / (h as f32))
47 }
48}
49
50pub fn with_image_metadata_store_mut<H: GlobalsHost, R>(
56 host: &mut H,
57 f: impl FnOnce(&mut ImageMetadataStore) -> R,
58) -> R {
59 host.with_global_mut(ImageMetadataStore::default, |store, _host| f(store))
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn image_metadata_store_reports_aspect_ratio() {
68 let mut store = ImageMetadataStore::default();
69 let img = ImageId::default();
70 store.set_intrinsic_size_px(img, (1920, 1080));
71 assert_eq!(store.aspect_ratio(img), Some(1920.0 / 1080.0));
72 }
73
74 #[test]
75 fn image_metadata_store_ignores_zero_dimensions() {
76 let mut store = ImageMetadataStore::default();
77 let img = ImageId::default();
78 store.set_intrinsic_size_px(img, (0, 1080));
79 assert_eq!(store.aspect_ratio(img), None);
80 store.set_intrinsic_size_px(img, (1920, 0));
81 assert_eq!(store.aspect_ratio(img), None);
82 }
83}