From 3d7f80c0e3c772e7814ace579bddd2e9667033c7 Mon Sep 17 00:00:00 2001 From: Florian Klink Date: Fri, 12 Apr 2024 15:33:57 +0300 Subject: feat(tvix/nix-compat): impl Deserialize, Serialize for Signature Change-Id: I30294079129b0e5b4faa3272e09df982d3ef2178 Reviewed-on: https://cl.tvl.fyi/c/depot/+/11394 Reviewed-by: raitobezarius Tested-by: BuildkiteCI --- tvix/nix-compat/src/narinfo/signature.rs | 48 +++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) (limited to 'tvix/nix-compat/src/narinfo/signature.rs') diff --git a/tvix/nix-compat/src/narinfo/signature.rs b/tvix/nix-compat/src/narinfo/signature.rs index 1f4a90c26c2e..6162ec0e38f8 100644 --- a/tvix/nix-compat/src/narinfo/signature.rs +++ b/tvix/nix-compat/src/narinfo/signature.rs @@ -2,8 +2,9 @@ use std::fmt::{self, Display}; use data_encoding::BASE64; use ed25519_dalek::SIGNATURE_LENGTH; +use serde::{Deserialize, Serialize}; -#[derive(Debug)] +#[derive(Clone, Debug, Eq, PartialEq)] pub struct Signature<'a> { name: &'a str, bytes: [u8; SIGNATURE_LENGTH], @@ -57,6 +58,29 @@ impl<'a> Signature<'a> { } } +impl<'de: 'a, 'a> Deserialize<'de> for Signature<'a> { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let str: &'de str = Deserialize::deserialize(deserializer)?; + Self::parse(str).map_err(|_| { + serde::de::Error::invalid_value(serde::de::Unexpected::Str(str), &"Signature") + }) + } +} + +impl<'a> Serialize for Signature<'a> { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let string: String = self.to_string(); + + string.serialize(serializer) + } +} + #[derive(Debug, thiserror::Error)] pub enum Error { #[error("Invalid name: {0}")] @@ -79,6 +103,7 @@ impl Display for Signature<'_> { mod test { use data_encoding::BASE64; use ed25519_dalek::VerifyingKey; + use hex_literal::hex; use lazy_static::lazy_static; use super::Signature; @@ -129,4 +154,25 @@ mod test { fn parse_fail(input: &'static str) { Signature::parse(input).expect_err("must fail"); } + + #[test] + fn serialize_deserialize() { + let signature_actual = Signature { + name: "cache.nixos.org-1", + bytes: hex!( + r#"4e c4 d3 6f 75 86 4d 92 a9 86 f6 1d 04 75 f0 a3 + ac 1e 54 82 e6 4f 2b 54 8c b0 7e bd c5 fc f5 f3 + a3 8d 18 9c 08 79 8a 03 84 42 3c c5 4b 92 3e 93 + 30 9e 06 31 7d c7 3d 55 91 74 3d 61 91 e2 99 05"# + ), + }; + let signature_str_json = "\"cache.nixos.org-1:TsTTb3WGTZKphvYdBHXwo6weVILmTytUjLB+vcX89fOjjRicCHmKA4RCPMVLkj6TMJ4GMX3HPVWRdD1hkeKZBQ==\""; + + let serialized = serde_json::to_string(&signature_actual).expect("must serialize"); + assert_eq!(signature_str_json, &serialized); + + let deserialized: Signature<'_> = + serde_json::from_str(signature_str_json).expect("must deserialize"); + assert_eq!(&signature_actual, &deserialized); + } } -- cgit 1.4.1