nix_compat/nixhash/
serde.rs

1use super::NixHash;
2use crate::nixbase32;
3use serde::{Deserialize, Serialize};
4
5impl<'de> Deserialize<'de> for NixHash {
6    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
7    where
8        D: serde::Deserializer<'de>,
9    {
10        let str: &'de str = Deserialize::deserialize(deserializer)?;
11        NixHash::from_str(str, None).map_err(|_| {
12            serde::de::Error::invalid_value(serde::de::Unexpected::Str(str), &"NixHash")
13        })
14    }
15}
16
17impl Serialize for NixHash {
18    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
19    where
20        S: serde::Serializer,
21    {
22        let sri = self.to_sri_string();
23        sri.serialize(serializer)
24    }
25}
26
27/// The length of a sha256 digest, nixbase32-encoded.
28const NIXBASE32_SHA256_ENCODE_LEN: usize = nixbase32::encode_len(32);
29
30pub fn from_nix_nixbase32_or_sri<'de, D>(deserializer: D) -> Result<[u8; 32], D::Error>
31where
32    D: serde::Deserializer<'de>,
33{
34    let str: &'de str = Deserialize::deserialize(deserializer)?;
35    if let Some(digest_str) = str.strip_prefix("sha256:") {
36        return from_nix_nixbase32::<D>(digest_str);
37    }
38    if let Some(digest_str) = str.strip_prefix("sha256-") {
39        return from_sri::<D>(digest_str);
40    }
41    Err(serde::de::Error::invalid_value(
42        serde::de::Unexpected::Str(str),
43        &"extected a valid nixbase32 or sri narHash",
44    ))
45}
46
47pub fn from_sri<'de, D>(str: &str) -> Result<[u8; 32], D::Error>
48where
49    D: serde::Deserializer<'de>,
50{
51    let digest: [u8; 32] = data_encoding::BASE64
52        .decode(str.as_bytes())
53        .map_err(|_| {
54            serde::de::Error::invalid_value(
55                serde::de::Unexpected::Str(str),
56                &"valid base64 encoded string",
57            )
58        })?
59        .try_into()
60        .map_err(|_| {
61            serde::de::Error::invalid_value(serde::de::Unexpected::Str(str), &"valid digest len")
62        })?;
63
64    Ok(digest)
65}
66
67pub fn from_nix_nixbase32<'de, D>(str: &str) -> Result<[u8; 32], D::Error>
68where
69    D: serde::Deserializer<'de>,
70{
71    let digest_str: [u8; NIXBASE32_SHA256_ENCODE_LEN] =
72        str.as_bytes().try_into().map_err(|_| {
73            serde::de::Error::invalid_value(serde::de::Unexpected::Str(str), &"valid digest len")
74        })?;
75
76    let digest: [u8; 32] = nixbase32::decode_fixed(digest_str).map_err(|_| {
77        serde::de::Error::invalid_value(serde::de::Unexpected::Str(str), &"valid nixbase32")
78    })?;
79
80    Ok(digest)
81}
82
83pub fn to_nix_nixbase32<S>(v: &[u8; 32], serializer: S) -> Result<S::Ok, S::Error>
84where
85    S: serde::Serializer,
86{
87    let string = NixHash::Sha256(*v).to_nix_nixbase32();
88    string.serialize(serializer)
89}