nix_compat/nixhash/
ca_hash.rs1use crate::nixbase32;
2use crate::nixhash::NixHash;
3use std::borrow::Cow;
4
5#[derive(Clone, Debug, Eq, PartialEq)]
12pub enum CAHash {
13 Flat(NixHash), Nar(NixHash), Text([u8; 32]), }
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub enum HashMode {
21 Flat,
22 Nar,
23 Text,
24}
25
26impl CAHash {
27 pub fn hash(&self) -> Cow<'_, NixHash> {
28 match *self {
29 CAHash::Flat(ref digest) => Cow::Borrowed(digest),
30 CAHash::Nar(ref digest) => Cow::Borrowed(digest),
31 CAHash::Text(digest) => Cow::Owned(NixHash::Sha256(digest)),
32 }
33 }
34
35 pub fn mode(&self) -> HashMode {
36 match self {
37 CAHash::Flat(_) => HashMode::Flat,
38 CAHash::Nar(_) => HashMode::Nar,
39 CAHash::Text(_) => HashMode::Text,
40 }
41 }
42
43 pub fn from_nix_hex_str(s: &str) -> Option<Self> {
51 let (tag, s) = s.split_once(':')?;
52
53 match tag {
54 "text" => {
55 let digest = s.strip_prefix("sha256:")?;
56 let digest = nixbase32::decode_fixed(digest).ok()?;
57 Some(CAHash::Text(digest))
58 }
59 "fixed" => {
60 if let Some(s) = s.strip_prefix("r:") {
61 NixHash::from_nix_nixbase32(s).map(CAHash::Nar)
62 } else {
63 NixHash::from_nix_nixbase32(s).map(CAHash::Flat)
64 }
65 }
66 _ => None,
67 }
68 }
69}
70
71impl std::fmt::Display for CAHash {
74 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75 let (algo, hash) = match self {
76 CAHash::Flat(h) => match h {
77 NixHash::Md5(h) => ("fixed:md5", &h[..]),
78 NixHash::Sha1(h) => ("fixed:sha1", &h[..]),
79 NixHash::Sha256(h) => ("fixed:sha256", &h[..]),
80 NixHash::Sha512(h) => ("fixed:sha512", &h[..]),
81 },
82 CAHash::Nar(h) => match h {
83 NixHash::Md5(h) => ("fixed:r:md5", &h[..]),
84 NixHash::Sha1(h) => ("fixed:r:sha1", &h[..]),
85 NixHash::Sha256(h) => ("fixed:r:sha256", &h[..]),
86 NixHash::Sha512(h) => ("fixed:r:sha512", &h[..]),
87 },
88 CAHash::Text(h) => ("text:sha256", &h[..]),
89 };
90
91 write!(f, "{}:{}", algo, nixbase32::encode(hash))
92 }
93}