From 345dbc0d5d36dad806ed2efae5f4585bc5db2079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20M=C3=BCller?= Date: Sat, 19 Sep 2026 17:59:27 +0200 Subject: [PATCH] Add ElementMap::map --- src/maps.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/maps.rs b/src/maps.rs index c96701d..debddc8 100644 --- a/src/maps.rs +++ b/src/maps.rs @@ -52,6 +52,32 @@ impl ElementMap { pub fn reserve(&mut self, additional: usize) { self.data.reserve(additional); } + + /// Returns a new map over the same elements with values transformed by `f`. + /// + /// The default value of the new map is `f` applied to the original default, so reads beyond the + /// current capacity of the new map behave consistently with the transformation. + /// + /// # Examples + /// + /// ``` + /// # use grapherity::maps::ElementMap; + /// let mut map: ElementMap> = ElementMap::new(None, |e| e, 0); + /// map[1] = Some(42); + /// + /// let bools = map.map(|v| v.is_some()); + /// assert_eq!(bools[0], false); + /// assert_eq!(bools[1], true); + /// // Returns mapped default for reads beyond capacity. + /// assert_eq!(bools[9], false); + /// ``` + pub fn map(&self, f: impl Fn(&T) -> U) -> ElementMap { + ElementMap { + data: self.data.iter().map(|v| f(v)).collect(), + default: f(&self.default), + to_index: self.to_index, + } + } } impl Index for ElementMap { @@ -131,4 +157,19 @@ mod tests { assert_eq!(map[1], 7, "unexpected read value after write"); assert_eq!(map[0], 0, "initial read should be default"); } + + #[test] + fn map() { + let mut source: ElementMap> = ElementMap::new(None, |e| e, 0); + source[1] = Some(42); + source[2] = None; + let mapped = source.map(|v| v.is_some()); + assert_eq!(mapped[0], false, "unset entry should map to false"); + assert_eq!(mapped[1], true, "Some entry should map to true"); + assert_eq!(mapped[2], false, "explicit None entry should map to false"); + assert_eq!( + mapped[9], false, + "read beyond capacity should return mapped default" + ); + } }