@@ -8,6 +8,9 @@ use core::{
8
8
ops, slice,
9
9
} ;
10
10
11
+ #[ cfg( feature = "zeroize" ) ]
12
+ use zeroize:: Zeroize ;
13
+
11
14
use hash32:: { BuildHasherDefault , FnvHasher } ;
12
15
13
16
use crate :: Vec ;
@@ -66,6 +69,7 @@ use crate::Vec;
66
69
pub type FnvIndexMap < K , V , const N : usize > = IndexMap < K , V , BuildHasherDefault < FnvHasher > , N > ;
67
70
68
71
#[ derive( Clone , Copy , Eq , PartialEq ) ]
72
+ #[ cfg_attr( feature = "zeroize" , derive( Zeroize ) ) ]
69
73
struct HashValue ( u16 ) ;
70
74
71
75
impl HashValue {
@@ -80,6 +84,7 @@ impl HashValue {
80
84
81
85
#[ doc( hidden) ]
82
86
#[ derive( Clone ) ]
87
+ #[ cfg_attr( feature = "zeroize" , derive( Zeroize ) ) ]
83
88
pub struct Bucket < K , V > {
84
89
hash : HashValue ,
85
90
key : K ,
@@ -88,6 +93,7 @@ pub struct Bucket<K, V> {
88
93
89
94
#[ doc( hidden) ]
90
95
#[ derive( Clone , Copy , PartialEq ) ]
96
+ #[ cfg_attr( feature = "zeroize" , derive( Zeroize ) ) ]
91
97
pub struct Pos {
92
98
// compact representation of `{ hash_value: u16, index: u16 }`
93
99
// 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 {
138
144
}
139
145
}
140
146
147
+ #[ cfg_attr(
148
+ feature = "zeroize" ,
149
+ derive( Zeroize ) ,
150
+ zeroize( bound = "K: Zeroize, V: Zeroize" )
151
+ ) ]
141
152
struct CoreMap < K , V , const N : usize > {
142
153
entries : Vec < Bucket < K , V > , N , usize > ,
143
154
indices : [ Option < Pos > ; N ] ,
@@ -722,8 +733,14 @@ where
722
733
/// println!("{}: \"{}\"", book, review);
723
734
/// }
724
735
/// ```
736
+ #[ cfg_attr(
737
+ feature = "zeroize" ,
738
+ derive( Zeroize ) ,
739
+ zeroize( bound = "K: Zeroize, V: Zeroize" )
740
+ ) ]
725
741
pub struct IndexMap < K , V , S , const N : usize > {
726
742
core : CoreMap < K , V , N > ,
743
+ #[ cfg_attr( feature = "zeroize" , zeroize( skip) ) ]
727
744
build_hasher : S ,
728
745
}
729
746
@@ -1988,4 +2005,28 @@ mod tests {
1988
2005
let map: FnvIndexMap < usize , f32 , 4 > = Default :: default ( ) ;
1989
2006
assert_eq ! ( map, map) ;
1990
2007
}
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
+ }
1991
2032
}
0 commit comments