@@ -8,6 +8,9 @@ use core::{
88 ops, slice,
99} ;
1010
11+ #[ cfg( feature = "zeroize" ) ]
12+ use zeroize:: Zeroize ;
13+
1114use hash32:: { BuildHasherDefault , FnvHasher } ;
1215
1316use crate :: Vec ;
@@ -66,6 +69,7 @@ use crate::Vec;
6669pub type FnvIndexMap < K , V , const N : usize > = IndexMap < K , V , BuildHasherDefault < FnvHasher > , N > ;
6770
6871#[ derive( Clone , Copy , Eq , PartialEq ) ]
72+ #[ cfg_attr( feature = "zeroize" , derive( Zeroize ) ) ]
6973struct HashValue ( u16 ) ;
7074
7175impl HashValue {
@@ -80,6 +84,7 @@ impl HashValue {
8084
8185#[ doc( hidden) ]
8286#[ derive( Clone ) ]
87+ #[ cfg_attr( feature = "zeroize" , derive( Zeroize ) ) ]
8388pub struct Bucket < K , V > {
8489 hash : HashValue ,
8590 key : K ,
@@ -88,6 +93,7 @@ pub struct Bucket<K, V> {
8893
8994#[ doc( hidden) ]
9095#[ derive( Clone , Copy , PartialEq ) ]
96+ #[ cfg_attr( feature = "zeroize" , derive( Zeroize ) ) ]
9197pub struct Pos {
9298 // compact representation of `{ hash_value: u16, index: u16 }`
9399 // To get the most from `NonZero` we store the *value minus 1*. This way `None::Option<Pos>`
@@ -138,6 +144,11 @@ macro_rules! probe_loop {
138144 }
139145}
140146
147+ #[ cfg_attr(
148+ feature = "zeroize" ,
149+ derive( Zeroize ) ,
150+ zeroize( bound = "K: Zeroize, V: Zeroize" )
151+ ) ]
141152struct CoreMap < K , V , const N : usize > {
142153 entries : Vec < Bucket < K , V > , N , usize > ,
143154 indices : [ Option < Pos > ; N ] ,
@@ -722,8 +733,14 @@ where
722733/// println!("{}: \"{}\"", book, review);
723734/// }
724735/// ```
736+ #[ cfg_attr(
737+ feature = "zeroize" ,
738+ derive( Zeroize ) ,
739+ zeroize( bound = "K: Zeroize, V: Zeroize" )
740+ ) ]
725741pub struct IndexMap < K , V , S , const N : usize > {
726742 core : CoreMap < K , V , N > ,
743+ #[ cfg_attr( feature = "zeroize" , zeroize( skip) ) ]
727744 build_hasher : S ,
728745}
729746
@@ -1988,4 +2005,28 @@ mod tests {
19882005 let map: FnvIndexMap < usize , f32 , 4 > = Default :: default ( ) ;
19892006 assert_eq ! ( map, map) ;
19902007 }
2008+
2009+ #[ test]
2010+ #[ cfg( feature = "zeroize" ) ]
2011+ fn test_index_map_zeroize ( ) {
2012+ use zeroize:: Zeroize ;
2013+
2014+ let mut map: FnvIndexMap < u8 , u8 , 8 > = FnvIndexMap :: new ( ) ;
2015+ for i in 1 ..=8 {
2016+ map. insert ( i, i * 10 ) . unwrap ( ) ;
2017+ }
2018+
2019+ assert_eq ! ( map. len( ) , 8 ) ;
2020+ assert ! ( !map. is_empty( ) ) ;
2021+
2022+ // zeroized using Vec's implementation
2023+ map. zeroize ( ) ;
2024+
2025+ assert_eq ! ( map. len( ) , 0 ) ;
2026+ assert ! ( map. is_empty( ) ) ;
2027+
2028+ map. insert ( 1 , 10 ) . unwrap ( ) ;
2029+ assert_eq ! ( map. len( ) , 1 ) ;
2030+ assert_eq ! ( map. get( & 1 ) , Some ( & 10 ) ) ;
2031+ }
19912032}
0 commit comments