From f0312956ce4825c10dae2a049e79e196a6d7511c Mon Sep 17 00:00:00 2001 From: Mikko Lehtonen Date: Wed, 1 Apr 2026 14:29:24 +0300 Subject: [PATCH 1/2] Add optional support for `indexmap` Map/Set types --- Cargo.lock | 9 ++-- Cargo.toml | 1 + daft/Cargo.toml | 2 + daft/src/third_party/indexmap.rs | 72 ++++++++++++++++++++++++++++++++ daft/src/third_party/mod.rs | 2 + 5 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 daft/src/third_party/indexmap.rs diff --git a/Cargo.lock b/Cargo.lock index cd3ce80..2a318e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -152,6 +152,7 @@ name = "daft" version = "0.1.5" dependencies = [ "daft-derive", + "indexmap", "newtype-uuid", "oxnet", "paste", @@ -250,9 +251,9 @@ checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] name = "heck" @@ -262,9 +263,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "indexmap" -version = "2.7.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", "hashbrown", diff --git a/Cargo.toml b/Cargo.toml index e2b9812..635bec4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,3 +33,4 @@ quote = "1.0" syn = "2.0" trybuild = "1.0.103" uuid = "1.12.0" +indexmap = "2.11.4" diff --git a/daft/Cargo.toml b/daft/Cargo.toml index a997cfd..81256ce 100644 --- a/daft/Cargo.toml +++ b/daft/Cargo.toml @@ -15,6 +15,7 @@ workspace = true [dependencies] daft-derive = { workspace = true, optional = true } +indexmap = { workspace = true, optional = true } newtype-uuid = { workspace = true, optional = true } oxnet = { workspace = true, optional = true } paste.workspace = true @@ -28,6 +29,7 @@ derive = ["dep:daft-derive"] newtype-uuid1 = ["dep:newtype-uuid"] oxnet01 = ["dep:oxnet"] uuid1 = ["dep:uuid"] +indexmap = ["dep:indexmap", "alloc"] [package.metadata.docs.rs] all-features = true diff --git a/daft/src/third_party/indexmap.rs b/daft/src/third_party/indexmap.rs new file mode 100644 index 0000000..379963e --- /dev/null +++ b/daft/src/third_party/indexmap.rs @@ -0,0 +1,72 @@ +use crate::Diffable; +use core::hash::Hash; +use indexmap::{IndexMap, IndexSet}; + +map_diff!(IndexMap, Hash); +set_diff!(IndexSet, Hash); + +#[cfg(test)] +mod tests { + use super::*; + use crate::Leaf; + use alloc::vec::Vec; + + #[test] + fn indexmap_set_diff() { + let a: indexmap::IndexSet<_> = [0, 1, 2, 3, 4, 5].into_iter().collect(); + let b: indexmap::IndexSet<_> = [3, 4, 5, 6, 7, 8].into_iter().collect(); + let changes = a.diff(&b); + let expected = IndexSetDiff { + added: [&6, &7, &8].into_iter().collect(), + removed: [&0, &1, &2].into_iter().collect(), + common: [&3, &4, &5].into_iter().collect(), + }; + assert_eq!(expected, changes); + } + + #[test] + fn indexmap_map_diff() { + let a: IndexMap<_, _> = [(0, 1), (1, 1), (2, 1)].into_iter().collect(); + let b: IndexMap<_, _> = [(0, 2), (2, 1), (3, 1)].into_iter().collect(); + + let changes = a.diff(&b); + let expected = IndexMapDiff { + common: [ + (&0, Leaf { before: &1, after: &2 }), + (&2, Leaf { before: &1, after: &1 }), + ] + .into_iter() + .collect(), + added: [(&3, &1)].into_iter().collect(), + removed: [(&1, &1)].into_iter().collect(), + }; + + assert_eq!(changes, expected); + + // Ensure that keys don't need to be Diffable, and values don't need to + // be Eq or Diffable. + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] + struct K(i32); + + #[derive(Debug)] + #[expect(dead_code)] + struct V(f64); + + let floats_a: IndexMap = + [(K(0), V(1.0)), (K(1), V(1.0)), (K(2), V(1.0))] + .into_iter() + .collect(); + let floats_b: IndexMap = + [(K(0), V(2.0)), (K(2), V(1.0)), (K(3), V(1.0))] + .into_iter() + .collect(); + + let diff = floats_a.diff(&floats_b); + assert_eq!(diff.added.keys().copied().collect::>(), [&K(3)]); + assert_eq!(diff.removed.keys().copied().collect::>(), [&K(1)]); + assert_eq!( + diff.common.keys().copied().collect::>(), + [&K(0), &K(2)] + ); + } +} diff --git a/daft/src/third_party/mod.rs b/daft/src/third_party/mod.rs index 45ab987..a109a1d 100644 --- a/daft/src/third_party/mod.rs +++ b/daft/src/third_party/mod.rs @@ -1,5 +1,7 @@ //! Implementations for third-party libraries. +#[cfg(feature = "indexmap")] +mod indexmap; #[cfg(feature = "newtype-uuid1")] mod newtype_uuid_impls; #[cfg(feature = "oxnet01")] From 7f7d2236bd5117992b875b2f69d25a4a3d29d31d Mon Sep 17 00:00:00 2001 From: Rain Date: Thu, 14 May 2026 11:32:58 -0700 Subject: [PATCH 2/2] fix up imports --- daft/src/third_party/indexmap.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/daft/src/third_party/indexmap.rs b/daft/src/third_party/indexmap.rs index 379963e..3955f0a 100644 --- a/daft/src/third_party/indexmap.rs +++ b/daft/src/third_party/indexmap.rs @@ -13,8 +13,8 @@ mod tests { #[test] fn indexmap_set_diff() { - let a: indexmap::IndexSet<_> = [0, 1, 2, 3, 4, 5].into_iter().collect(); - let b: indexmap::IndexSet<_> = [3, 4, 5, 6, 7, 8].into_iter().collect(); + let a: IndexSet<_> = [0, 1, 2, 3, 4, 5].into_iter().collect(); + let b: IndexSet<_> = [3, 4, 5, 6, 7, 8].into_iter().collect(); let changes = a.diff(&b); let expected = IndexSetDiff { added: [&6, &7, &8].into_iter().collect(),