1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*!
# Digestible
A more dynamic [Hash](core::hash::Hash) and [Hasher](core::hash::Hasher) trait for Rust
---
## Key Difference over The Rust Hash and Hasher Traits
- ByteOrder is built in. So you can digest number types in any byte order. [ByteOrder](byteorder)
- Output is a Generic Associated Type.
So you can Digest into a ByteArray,
String with [Base64](to_base64)
or any type the Digester uses.
- Skip Fields with `#[digestible(skip)]`
- 'digest_with' and 'with' to override the default digest behavior.
[digest_with](https://docs.rs/digestible/0.2.0/digestible/digest_with/index.html)
- Support for all Hashing Algorithms that implement [digest::Digest] such as SHA2, md-5, and many more.
- Writing Type Headers to prevent collisions with similar types. (This is optional and can be disabled with `#[digestible(type_header = none)]`)
---
## Features
- `no_std` Support
- Digest to implement Digester for all types that implement [digest::Digest](https://docs.rs/digest/latest/digest/)
- Float and Atomic Support using `digest_with`
#### [Digestible](digestible::Digestible)
A trait that allows you to digest data into a [Digester](digester::Digester)
Equivalent to [Hash](core::hash::Hash) but with more control over the digesting process
#### [Digester]
A trait that allows you to digest data into a Target type
Equivalent to [Hasher](core::hash::Hasher) but with more control over the digesting process
#### [DigestWriter](DigestWriter)
A trait that allows you to write data to a writer.
This is used internally by [Digester] this is what is passed into [Digestible] to digest data
#### [Digestible Macro](digestible_macros::Digestible)
A macro that allows you to automatically implement [Digestible] for your types
Similar to [derive(Hash)](core::hash::Hash) but with more control over the digesting process
## Type Headers
Type Header is a way to identify complex type when being digested.
Preventing collisions between similar types.
This is generated by the macro by putting the [type_name](core::any::type_name)
of the type in the digest.
### Enums
The Type Header for Enum is written as [type_name](core::any::type_name)::`variant_name`
*/
extern crate alloc;
pub use crateDigestible;
pub use Digester;
pub use byteorder;
/// Provides some sometimes useful digest_with implementations
/// Provides inter-compatibility with [Hasher](core::hash::Hasher)/[Hash](core::hash::Hash) and [Digester](crate::Digester)/[Digestible](crate::Digestible)
pub use DigestWriter;
///# Digestible Macro
///
/// Implement the [Digestible] trait for the given struct or enum.
///
/// This will push all data one after another into the [DigestWriter].
///
/// No padding or spaces are added. Similar to how [Hash](core::hash::Hash) works.
///
///
/// ## Container Attributes
/// ### type_header
/// Sets how the type header is written [TypeHeader](https:///docs.rs/digestible/latest/digestible/index.html#type-headers)
/// Options:
/// - none: No type header is written `#[digestible(type_header = none)]`
/// - HashName: The name of the hash is written as the type header (Default) `#[digestible(type_header = HashName)]`
/// ### impl_hash
/// The macro will also implement [Hash](core::hash::Hash) for the given struct or enum using [DigesterUsingHasher](hash_digester::DigesterUsingHasher).
/// This will put the same data the Digestible trait would into the hasher. Allowing you to use `digest_with` and including type headers.
/// This will not be useful if you are using this type in a HashMap or HashSet. As this will provide more data than the Hash trait would. and can be slower.
/// By default this uses NativeEndian.
/// You can change this by using
/// - `#[digestible(impl_hash = LittleEndian)]`
/// - `#[digestible(impl_hash = BigEndian)]`
/// - `#[digestible(impl_hash = NetworkEndian)]`
/// - `#[digestible(impl_hash = NativeEndian)]`
/// #### Output
///```rust
/// use digestible_macros::Digestible;
/// #[derive(Digestible)]
/// // Add this #[digestible(impl_hash = LittleEndian)]
/// pub struct MyStruct {
/// pub id: u32,
/// }
/// // This will be generated
/// impl core::hash::Hash for MyStruct {
/// fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
/// let mut digester = digestible::hash_digester::DigesterUsingHasher(state);
/// <Self as digestible::Digestible>::digest::<byteorder::LittleEndian, _>(
/// self,
/// &mut digester,
/// );
/// }
/// }
/// ```
/// ## Field Attributes
/// ### skip: Skips the field when digesting
/// ### with: Path to a digest fn
/// Required Fn Signature: `fn digest<B: ByteOrder, W: DigestWriter>(digest: Type, writer: &mut W);`
///
/// ```rust, no_run
/// use core::time::Duration;
/// use digestible::byteorder::ByteOrder;
/// use digestible::hash_digester::HashableHack;
/// use digestible::{DigestWriter, Digestible};
///
/// fn duration_digest_with<B: ByteOrder, W: DigestWriter>(digest: &Duration, writer: &mut W) {
/// writer.write_u64::<B>(digest.as_secs());
/// }
/// ```
/// ### digest_with
/// Function provided in the [digest_with](crate::digest_with) module Example: `#[digestible(digest_with = digest_with_hash)]`
/// ### as_ref
/// Will call as_ref on the field before digesting it. Example: `#[digestible(as_ref = TargetType)]`
pub use Digestible;
pub use ;