winget_types/shared/
sha_256.rs1use std::{
2 io,
3 io::{Error, ErrorKind, Read},
4 str::FromStr,
5};
6
7use derive_more::Display;
8use heapless::String;
9use serde::{Deserialize, Serialize};
10use sha2::{Digest, Sha256};
11
12const SHA256_DIGEST_LEN: usize = 256 / 0xFu8.count_ones() as usize;
14
15#[derive(Clone, Debug, Display, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
16pub struct Sha256String(String<SHA256_DIGEST_LEN>);
17
18impl Sha256String {
19 pub fn from_hasher(data: &[u8]) -> Result<Self, base16ct::Error> {
20 let mut encode_buf = [0; SHA256_DIGEST_LEN];
21 let sha_256 = base16ct::upper::encode_str(data, &mut encode_buf)?;
22 Ok(Self(
23 String::<SHA256_DIGEST_LEN>::from_str(sha_256).unwrap_or_else(|()| unreachable!()),
24 ))
25 }
26
27 pub fn from_reader<R: Read>(mut reader: R) -> io::Result<Self> {
28 let mut hasher = Sha256::new();
29 let mut buffer = [0; 1 << 12];
30
31 loop {
32 let count = reader.read(&mut buffer)?;
33 if count == 0 {
34 break;
35 }
36 hasher.update(&buffer[..count]);
37 }
38
39 Self::from_hasher(&hasher.finalize()).map_err(|err| Error::new(ErrorKind::Other, err))
40 }
41}
42
43impl Default for Sha256String {
44 fn default() -> Self {
45 Self(std::iter::repeat_n('0', SHA256_DIGEST_LEN).collect::<_>())
46 }
47}