gosh_dl/protocol/
checksum.rs

1//! Checksum types for download verification
2//!
3//! Supports MD5 and SHA256 hash verification.
4
5use serde::{Deserialize, Serialize};
6
7/// Supported checksum algorithms
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
9#[serde(rename_all = "lowercase")]
10pub enum ChecksumAlgorithm {
11    /// MD5 hash (128-bit, fast but less secure)
12    Md5,
13    /// SHA-256 hash (256-bit, more secure)
14    Sha256,
15}
16
17impl std::fmt::Display for ChecksumAlgorithm {
18    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19        match self {
20            ChecksumAlgorithm::Md5 => write!(f, "MD5"),
21            ChecksumAlgorithm::Sha256 => write!(f, "SHA256"),
22        }
23    }
24}
25
26/// Expected checksum for verification
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct ExpectedChecksum {
29    /// The hash algorithm to use
30    pub algorithm: ChecksumAlgorithm,
31    /// The expected hash value (hex-encoded, lowercase)
32    pub value: String,
33}
34
35impl ExpectedChecksum {
36    /// Create an MD5 checksum expectation
37    pub fn md5(hex_value: impl Into<String>) -> Self {
38        Self {
39            algorithm: ChecksumAlgorithm::Md5,
40            value: hex_value.into().to_lowercase(),
41        }
42    }
43
44    /// Create a SHA-256 checksum expectation
45    pub fn sha256(hex_value: impl Into<String>) -> Self {
46        Self {
47            algorithm: ChecksumAlgorithm::Sha256,
48            value: hex_value.into().to_lowercase(),
49        }
50    }
51
52    /// Parse from a string like "md5:abc123" or "sha256:def456"
53    pub fn parse(s: &str) -> Option<Self> {
54        let (algo, hash) = s.split_once(':')?;
55        let algorithm = match algo.to_lowercase().as_str() {
56            "md5" => ChecksumAlgorithm::Md5,
57            "sha256" | "sha-256" => ChecksumAlgorithm::Sha256,
58            _ => return None,
59        };
60        Some(Self {
61            algorithm,
62            value: hash.to_lowercase(),
63        })
64    }
65}