1
- #![ cfg( feature = "alloc" ) ]
2
1
use alloc:: boxed:: Box ;
2
+ use core:: fmt;
3
3
4
4
use super :: { FixedOutput , Reset , Update } ;
5
- use generic_array:: typenum:: Unsigned ;
5
+ use generic_array:: { typenum:: Unsigned , GenericArray } ;
6
6
7
7
/// The `DynDigest` trait is a modification of `Digest` trait suitable
8
8
/// for trait objects.
@@ -19,6 +19,16 @@ pub trait DynDigest {
19
19
/// Retrieve result and consume boxed hasher instance
20
20
fn finalize ( self : Box < Self > ) -> Box < [ u8 ] > ;
21
21
22
+ /// Write result into provided array and consume the hasher instance.
23
+ ///
24
+ /// Returns error if buffer length is not equal to `output_size`.
25
+ fn finalize_into ( self , buf : & mut [ u8 ] ) -> Result < ( ) , InvalidBufferLength > ;
26
+
27
+ /// Write result into provided array and reset the hasher instance.
28
+ ///
29
+ /// Returns error if buffer length is not equal to `output_size`.
30
+ fn finalize_into_reset ( & mut self , out : & mut [ u8 ] ) -> Result < ( ) , InvalidBufferLength > ;
31
+
22
32
/// Reset hasher instance to its initial state.
23
33
fn reset ( & mut self ) ;
24
34
@@ -42,6 +52,24 @@ impl<D: Update + FixedOutput + Reset + Clone + 'static> DynDigest for D {
42
52
self . finalize_fixed ( ) . to_vec ( ) . into_boxed_slice ( )
43
53
}
44
54
55
+ fn finalize_into ( self , buf : & mut [ u8 ] ) -> Result < ( ) , InvalidBufferLength > {
56
+ if buf. len ( ) == self . output_size ( ) {
57
+ self . finalize_into ( GenericArray :: from_mut_slice ( buf) ) ;
58
+ Ok ( ( ) )
59
+ } else {
60
+ Err ( InvalidBufferLength )
61
+ }
62
+ }
63
+
64
+ fn finalize_into_reset ( & mut self , buf : & mut [ u8 ] ) -> Result < ( ) , InvalidBufferLength > {
65
+ if buf. len ( ) == self . output_size ( ) {
66
+ self . finalize_into_reset ( GenericArray :: from_mut_slice ( buf) ) ;
67
+ Ok ( ( ) )
68
+ } else {
69
+ Err ( InvalidBufferLength )
70
+ }
71
+ }
72
+
45
73
fn reset ( & mut self ) {
46
74
Reset :: reset ( self ) ;
47
75
}
@@ -60,3 +88,16 @@ impl Clone for Box<dyn DynDigest> {
60
88
self . box_clone ( )
61
89
}
62
90
}
91
+
92
+ #[ cfg_attr( docsrs, doc( cfg( feature = "alloc" ) ) ) ]
93
+ #[ derive( Default , Debug , Copy , Clone , Eq , PartialEq ) ]
94
+ pub struct InvalidBufferLength ;
95
+
96
+ impl fmt:: Display for InvalidBufferLength {
97
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
98
+ f. write_str ( "invalid buffer length" )
99
+ }
100
+ }
101
+
102
+ #[ cfg( feature = "std" ) ]
103
+ impl std:: error:: Error for InvalidBufferLength { }
0 commit comments