refactor(nix-compat/nixhash): move serde into serde module
Especially the various specific format serializers/deserializers with used in path_info.rs shouldn't be living there, but in NixHash, so they can be used by other consumers of the library wanting to restrict to a certain format. Change-Id: Id43ba96e3f6ec68999f028854b625d5335d71554 Reviewed-on: https://cl.snix.dev/c/snix/+/30556 Reviewed-by: Ilan Joselevich <personal@ilanjoselevich.com> Tested-by: besadii Autosubmit: Florian Klink <flokli@flokli.de>
This commit is contained in:
parent
87d80eb1cc
commit
6c1bfd778e
3 changed files with 93 additions and 91 deletions
|
|
@ -1,14 +1,13 @@
|
||||||
use crate::nixbase32;
|
use crate::nixbase32;
|
||||||
use bstr::ByteSlice;
|
use bstr::ByteSlice;
|
||||||
use data_encoding::{BASE64, BASE64_NOPAD, HEXLOWER};
|
use data_encoding::{BASE64, BASE64_NOPAD, HEXLOWER};
|
||||||
use serde::Deserialize;
|
|
||||||
use serde::Serialize;
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use thiserror;
|
use thiserror;
|
||||||
|
|
||||||
mod algos;
|
mod algos;
|
||||||
mod ca_hash;
|
mod ca_hash;
|
||||||
|
pub mod serde;
|
||||||
|
|
||||||
pub use algos::HashAlgo;
|
pub use algos::HashAlgo;
|
||||||
pub use ca_hash::CAHash;
|
pub use ca_hash::CAHash;
|
||||||
|
|
@ -129,28 +128,6 @@ impl NixHash {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for NixHash {
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
||||||
where
|
|
||||||
D: serde::Deserializer<'de>,
|
|
||||||
{
|
|
||||||
let str: &'de str = Deserialize::deserialize(deserializer)?;
|
|
||||||
from_str(str, None).map_err(|_| {
|
|
||||||
serde::de::Error::invalid_value(serde::de::Unexpected::Str(str), &"NixHash")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Serialize for NixHash {
|
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: serde::Serializer,
|
|
||||||
{
|
|
||||||
let sri = self.to_sri_string();
|
|
||||||
sri.serialize(serializer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Constructs a new [NixHash] by specifying [HashAlgo] and digest.
|
/// Constructs a new [NixHash] by specifying [HashAlgo] and digest.
|
||||||
/// It can fail if the passed digest length doesn't match what's expected for
|
/// It can fail if the passed digest length doesn't match what's expected for
|
||||||
/// the passed algo.
|
/// the passed algo.
|
||||||
|
|
|
||||||
89
snix/nix-compat/src/nixhash/serde.rs
Normal file
89
snix/nix-compat/src/nixhash/serde.rs
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
use super::NixHash;
|
||||||
|
use crate::nixbase32;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for NixHash {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let str: &'de str = Deserialize::deserialize(deserializer)?;
|
||||||
|
super::from_str(str, None).map_err(|_| {
|
||||||
|
serde::de::Error::invalid_value(serde::de::Unexpected::Str(str), &"NixHash")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for NixHash {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
let sri = self.to_sri_string();
|
||||||
|
sri.serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The length of a sha256 digest, nixbase32-encoded.
|
||||||
|
const NIXBASE32_SHA256_ENCODE_LEN: usize = nixbase32::encode_len(32);
|
||||||
|
|
||||||
|
pub fn from_nix_hash_string<'de, D>(deserializer: D) -> Result<[u8; 32], D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let str: &'de str = Deserialize::deserialize(deserializer)?;
|
||||||
|
if let Some(digest_str) = str.strip_prefix("sha256:") {
|
||||||
|
return from_nix_nixbase32_string::<D>(digest_str);
|
||||||
|
}
|
||||||
|
if let Some(digest_str) = str.strip_prefix("sha256-") {
|
||||||
|
return from_sri_string::<D>(digest_str);
|
||||||
|
}
|
||||||
|
Err(serde::de::Error::invalid_value(
|
||||||
|
serde::de::Unexpected::Str(str),
|
||||||
|
&"extected a valid nixbase32 or sri narHash",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_sri_string<'de, D>(str: &str) -> Result<[u8; 32], D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let digest: [u8; 32] = data_encoding::BASE64
|
||||||
|
.decode(str.as_bytes())
|
||||||
|
.map_err(|_| {
|
||||||
|
serde::de::Error::invalid_value(
|
||||||
|
serde::de::Unexpected::Str(str),
|
||||||
|
&"valid base64 encoded string",
|
||||||
|
)
|
||||||
|
})?
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| {
|
||||||
|
serde::de::Error::invalid_value(serde::de::Unexpected::Str(str), &"valid digest len")
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(digest)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_nix_nixbase32_string<'de, D>(str: &str) -> Result<[u8; 32], D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let digest_str: [u8; NIXBASE32_SHA256_ENCODE_LEN] =
|
||||||
|
str.as_bytes().try_into().map_err(|_| {
|
||||||
|
serde::de::Error::invalid_value(serde::de::Unexpected::Str(str), &"valid digest len")
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let digest: [u8; 32] = nixbase32::decode_fixed(digest_str).map_err(|_| {
|
||||||
|
serde::de::Error::invalid_value(serde::de::Unexpected::Str(str), &"valid nixbase32")
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(digest)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_nix_nixbase32_string<S>(v: &[u8; 32], serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
let string = NixHash::Sha256(*v).to_nix_nixbase32_string();
|
||||||
|
string.serialize(serializer)
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{narinfo::SignatureRef, nixbase32, nixhash::NixHash, store_path::StorePathRef};
|
use crate::{narinfo::SignatureRef, nixhash, store_path::StorePathRef};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
|
|
@ -14,8 +14,8 @@ pub struct ExportedPathInfo<'a> {
|
||||||
|
|
||||||
#[serde(
|
#[serde(
|
||||||
rename = "narHash",
|
rename = "narHash",
|
||||||
serialize_with = "to_nix_nixbase32_string",
|
serialize_with = "nixhash::serde::to_nix_nixbase32_string",
|
||||||
deserialize_with = "from_nix_hash_string"
|
deserialize_with = "nixhash::serde::from_nix_hash_string"
|
||||||
)]
|
)]
|
||||||
pub nar_sha256: [u8; 32],
|
pub nar_sha256: [u8; 32],
|
||||||
|
|
||||||
|
|
@ -51,70 +51,6 @@ impl PartialOrd for ExportedPathInfo<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_nix_nixbase32_string<S>(v: &[u8; 32], serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: serde::Serializer,
|
|
||||||
{
|
|
||||||
let string = NixHash::Sha256(*v).to_nix_nixbase32_string();
|
|
||||||
string.serialize(serializer)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The length of a sha256 digest, nixbase32-encoded.
|
|
||||||
const NIXBASE32_SHA256_ENCODE_LEN: usize = nixbase32::encode_len(32);
|
|
||||||
|
|
||||||
fn from_nix_hash_string<'de, D>(deserializer: D) -> Result<[u8; 32], D::Error>
|
|
||||||
where
|
|
||||||
D: serde::Deserializer<'de>,
|
|
||||||
{
|
|
||||||
let str: &'de str = Deserialize::deserialize(deserializer)?;
|
|
||||||
if let Some(digest_str) = str.strip_prefix("sha256:") {
|
|
||||||
return from_nix_nixbase32_string::<D>(digest_str);
|
|
||||||
}
|
|
||||||
if let Some(digest_str) = str.strip_prefix("sha256-") {
|
|
||||||
return from_sri_string::<D>(digest_str);
|
|
||||||
}
|
|
||||||
Err(serde::de::Error::invalid_value(
|
|
||||||
serde::de::Unexpected::Str(str),
|
|
||||||
&"extected a valid nixbase32 or sri narHash",
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_sri_string<'de, D>(str: &str) -> Result<[u8; 32], D::Error>
|
|
||||||
where
|
|
||||||
D: serde::Deserializer<'de>,
|
|
||||||
{
|
|
||||||
let digest: [u8; 32] = data_encoding::BASE64
|
|
||||||
.decode(str.as_bytes())
|
|
||||||
.map_err(|_| {
|
|
||||||
serde::de::Error::invalid_value(
|
|
||||||
serde::de::Unexpected::Str(str),
|
|
||||||
&"valid base64 encoded string",
|
|
||||||
)
|
|
||||||
})?
|
|
||||||
.try_into()
|
|
||||||
.map_err(|_| {
|
|
||||||
serde::de::Error::invalid_value(serde::de::Unexpected::Str(str), &"valid digest len")
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(digest)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_nix_nixbase32_string<'de, D>(str: &str) -> Result<[u8; 32], D::Error>
|
|
||||||
where
|
|
||||||
D: serde::Deserializer<'de>,
|
|
||||||
{
|
|
||||||
let digest_str: [u8; NIXBASE32_SHA256_ENCODE_LEN] =
|
|
||||||
str.as_bytes().try_into().map_err(|_| {
|
|
||||||
serde::de::Error::invalid_value(serde::de::Unexpected::Str(str), &"valid digest len")
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let digest: [u8; 32] = nixbase32::decode_fixed(digest_str).map_err(|_| {
|
|
||||||
serde::de::Error::invalid_value(serde::de::Unexpected::Str(str), &"valid nixbase32")
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(digest)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use hex_literal::hex;
|
use hex_literal::hex;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue