bookkeeper_client/digest/
crc32.rs

1use std::marker::PhantomData;
2
3use bytes::BufMut;
4use crc32fast::Hasher;
5
6use super::traits::{Algorithm, Digester};
7
8pub struct Crc32Digester {
9    hasher: Hasher,
10}
11
12#[derive(Clone)]
13pub struct Crc32Algorithm {
14    _marker: PhantomData<()>,
15}
16
17impl Crc32Algorithm {
18    pub fn new() -> Crc32Algorithm {
19        Crc32Algorithm { _marker: PhantomData }
20    }
21}
22
23impl Algorithm for Crc32Algorithm {
24    type Digester = Crc32Digester;
25
26    fn digester(&self) -> Self::Digester {
27        Crc32Digester { hasher: Hasher::new() }
28    }
29
30    fn digest_length(&self) -> usize {
31        8
32    }
33}
34
35impl Digester for Crc32Digester {
36    fn update(&mut self, bytes: &[u8]) {
37        self.hasher.update(bytes);
38    }
39
40    fn digest(self, buf: &mut impl BufMut) {
41        let checksum = self.hasher.finalize() as u64;
42        buf.put_u64(checksum);
43    }
44
45    fn digest_length(&self) -> usize {
46        8
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use bytes::Buf;
53    use pretty_assertions::assert_eq;
54
55    use super::super::traits::{Algorithm, Digester};
56    use super::{Crc32Algorithm, Crc32Digester};
57
58    fn digest(digester: Crc32Digester) -> u64 {
59        let mut vec = Vec::new();
60        digester.digest(&mut vec);
61        assert_eq!(8, vec.len());
62
63        let mut buf = vec.as_slice();
64        buf.get_u64()
65    }
66
67    #[test]
68    fn test_crc32() {
69        let algorithm = Crc32Algorithm::new();
70        let digester = algorithm.digester();
71
72        assert_eq!(8, algorithm.digest_length());
73        assert_eq!(8, digester.digest_length());
74
75        assert_eq!(0, digest(digester));
76
77        let mut digester = algorithm.digester();
78        digester.update(b"abcdefg");
79        assert_eq!(0x312a6aa6, digest(digester));
80
81        let mut digester = algorithm.digester();
82        digester.update(b"abcdefg");
83        digester.update(b"abcdefg");
84        assert_eq!(0x7fd808af, digest(digester));
85    }
86}