tiedcrossing_type/digest/
algorithms.rs1use super::{Algorithm, ContentDigest, Reader, Writer};
5
6use std::collections::BTreeSet;
7use std::ops::{Deref, DerefMut};
8
9use futures::io::{self, copy, sink, AsyncRead};
10use serde::{Deserialize, Serialize};
11
12#[derive(Clone, Debug, Serialize, Deserialize)]
14pub struct Algorithms(BTreeSet<Algorithm>);
15
16impl Default for Algorithms {
17 fn default() -> Self {
18 let mut set = BTreeSet::new();
19 set.insert(Algorithm::Sha224);
20 set.insert(Algorithm::Sha256);
21 set.insert(Algorithm::Sha384);
22 set.insert(Algorithm::Sha512);
23 Self(set)
24 }
25}
26
27impl From<BTreeSet<Algorithm>> for Algorithms {
28 fn from(value: BTreeSet<Algorithm>) -> Self {
29 Self(value)
30 }
31}
32
33impl Deref for Algorithms {
34 type Target = BTreeSet<Algorithm>;
35
36 fn deref(&self) -> &Self::Target {
37 &self.0
38 }
39}
40
41impl DerefMut for Algorithms {
42 fn deref_mut(&mut self) -> &mut Self::Target {
43 &mut self.0
44 }
45}
46
47impl Algorithms {
48 pub fn reader<T>(&self, reader: T) -> Reader<T> {
50 Reader::new(reader, self.iter().cloned())
51 }
52
53 pub fn writer<T>(&self, writer: T) -> Writer<T> {
55 Writer::new(writer, self.iter().cloned())
56 }
57
58 pub async fn read(&self, reader: impl Unpin + AsyncRead) -> io::Result<(u64, ContentDigest)> {
60 let mut r = self.reader(reader);
61 let n = copy(&mut r, &mut sink()).await?;
62 Ok((n, r.digests()))
63 }
64
65 pub fn read_sync(&self, reader: impl std::io::Read) -> io::Result<(u64, ContentDigest)> {
67 let mut r = self.reader(reader);
68 let n = std::io::copy(&mut r, &mut std::io::sink())?;
69 Ok((n, r.digests()))
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76
77 #[async_std::test]
78 async fn digest() {
79 let algorithms = Algorithms::default();
80 let rdr = &b"foo"[..];
81 let content_digest = "sha-224=:CAj2TmDViXn8tnbJbsk4Jw3qQkRa7vzTpOb42w==:,sha-256=:LCa0a2j/xo/5m0U8HTBBNBNCLXBkg7+g+YpeiGJm564=:,sha-384=:mMEf/f3VQGdrGhN8saIrKnA1DJpEFx1rEYDGvly7LuP3nVMsih3Z7y6OCOdSo7q7:,sha-512=:9/u6bgY2+JDlb7vzKD5STG+jIErimDgtYkdB0NxmODJuKCxBvl5CVNiCB3LFUYosWowMf37aGVlKfrU5RT4e1w==:"
82 .parse::<ContentDigest>()
83 .unwrap();
84 assert_eq!(
85 algorithms.read(rdr).await.unwrap(),
86 ("foo".len() as _, content_digest.clone())
87 );
88 assert_eq!(
89 algorithms.read_sync(rdr).unwrap(),
90 ("foo".len() as _, content_digest)
91 );
92 }
93}