oci_image_spec/image_digest/
digest.rs

1use serde::{Deserialize, Serialize};
2use std::string::String;
3
4#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
5pub struct Digest {
6    pub name: String,
7    pub digest: String,
8}
9
10impl Digest {
11    pub fn new(alg: super::algorithm::Algorithm, digest: &str) -> Self {
12        let name = alg.name.to_string();
13        let digest = format!("{}:{}", name, digest.to_string());
14        Self { name, digest }
15    }
16
17    pub fn new_from_bytes(alg: super::algorithm::Algorithm, bytes: &[u8]) -> Self {
18        let name = alg.name.to_string();
19        let digest = format!("{}:{}", name, String::from_utf8(bytes.to_vec()).unwrap());
20        Self { name, digest }
21    }
22
23    pub fn string(self: Self) -> String {
24        self.digest.to_string()
25    }
26
27    pub fn algorithm(self: &Self) -> String {
28        self.digest[..self.sep_index()].to_string()
29    }
30
31    pub fn encoded(self: Self) -> String {
32        self.digest[self.sep_index() + 1..].to_string()
33    }
34
35    fn sep_index(&self) -> usize {
36        self.digest.find(':').unwrap()
37    }
38
39    pub fn validate(self: &Self) -> Result<(), std::io::Error> {
40        let alg = self.algorithm();
41        match alg.as_str() {
42            super::algorithm::SHA256 | super::algorithm::SHA384 | super::algorithm::SHA512 => {}
43            _ => {
44                return Err(std::io::Error::new(
45                    std::io::ErrorKind::InvalidData,
46                    "invalid checksum digest algorithm",
47                ));
48            }
49        }
50        let re = regex::Regex::new(r"^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$").unwrap();
51        if re.is_match(&self.digest) {
52            Ok(())
53        } else {
54            Err(std::io::Error::new(
55                std::io::ErrorKind::InvalidData,
56                "invalid checksum digest format",
57            ))
58        }
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65
66    #[test]
67    fn test_validate() {
68        let d = Digest {
69            name: "sha256".to_string(),
70            digest: "sha256:abcdefghijklmnopqrstuvwxyz0123456789".to_string(),
71        };
72        assert!(d.validate().is_ok());
73    }
74}