apub_core/
digest.rs

1//! Traits around message digest
2
3use std::{rc::Rc, sync::Arc};
4
5/// Describes computing message digests for arbitrary bytes
6///
7/// This trait has notable implementations such as apub-openssl's OpenSslDigest, and
8/// apub-rustcrypto's Sha256Digest
9pub trait Digest {
10    /// This NAME should correspond with an HTTP Digest algorithm name
11    const NAME: &'static str;
12
13    /// Produce a message digest from the given bytes
14    fn digest(&mut self, input: &[u8]) -> String;
15
16    /// Update the Digest with the given bytes
17    fn update(&mut self, input: &[u8]);
18
19    /// Verify an encoded string with the current digest
20    fn verify(&mut self, encoded: &str) -> bool;
21}
22
23/// Describes creating a new Digest type
24pub trait DigestBuilder: Digest {
25    /// Create the Digest
26    fn build() -> Self;
27}
28
29/// Allows associating a given Digest type with any arbitrary type
30///
31/// Some downstreams have dependencies on types that implement DigestFactory in order to generate
32/// the desired type for computing digests
33pub trait DigestFactory {
34    /// The Digest type associated
35    type Digest: DigestBuilder + Digest + Send + 'static;
36}
37
38impl<'a, T> DigestFactory for &'a T
39where
40    T: DigestFactory,
41{
42    type Digest = T::Digest;
43}
44
45impl<'a, T> DigestFactory for &'a mut T
46where
47    T: DigestFactory,
48{
49    type Digest = T::Digest;
50}
51
52impl<T> DigestFactory for Box<T>
53where
54    T: DigestFactory,
55{
56    type Digest = T::Digest;
57}
58
59impl<T> DigestFactory for Rc<T>
60where
61    T: DigestFactory,
62{
63    type Digest = T::Digest;
64}
65
66impl<T> DigestFactory for Arc<T>
67where
68    T: DigestFactory,
69{
70    type Digest = T::Digest;
71}
72
73impl<'a, T> Digest for &'a mut T
74where
75    T: Digest,
76{
77    const NAME: &'static str = T::NAME;
78
79    fn digest(&mut self, input: &[u8]) -> String {
80        T::digest(self, input)
81    }
82
83    fn update(&mut self, input: &[u8]) {
84        T::update(self, input)
85    }
86
87    fn verify(&mut self, encoded: &str) -> bool {
88        T::verify(self, encoded)
89    }
90}
91
92impl<T> Digest for Box<T>
93where
94    T: Digest,
95{
96    const NAME: &'static str = T::NAME;
97
98    fn digest(&mut self, input: &[u8]) -> String {
99        T::digest(self, input)
100    }
101
102    fn update(&mut self, input: &[u8]) {
103        T::update(self, input)
104    }
105
106    fn verify(&mut self, encoded: &str) -> bool {
107        T::verify(self, encoded)
108    }
109}