feat(nix-compat): Use serde_with for HashAlgo serialization

We already have serde_with in the workspace and using it cuts down
on code lines (very slightly).

This also adds a FromStr implementation for HashAlgo in addition to
the existing TryFrom<&str>.

Change-Id: I1b525d7391f3881d54cef0c74d22198ad394f47d
Reviewed-on: https://cl.snix.dev/c/snix/+/30652
Reviewed-by: Florian Klink <flokli@flokli.de>
Tested-by: besadii
Autosubmit: Brian Olsen <brian@maven-group.org>
This commit is contained in:
Brian Olsen 2025-08-04 23:31:25 +02:00 committed by clbot
parent 6187029077
commit e5177ae930
10 changed files with 36 additions and 33 deletions

View file

@ -4178,7 +4178,7 @@ rec {
"futures" = [ "dep:futures" ];
"nix-compat-derive" = [ "dep:nix-compat-derive" ];
"pin-project-lite" = [ "dep:pin-project-lite" ];
"serde" = [ "dep:serde" "dep:serde_json" ];
"serde" = [ "dep:serde" "dep:serde_json" "dep:serde_with" ];
"tokio" = [ "dep:tokio" ];
"url" = [ "dep:url" ];
"wire" = [ "tokio" "pin-project-lite" "bytes" ];

View file

@ -5611,7 +5611,7 @@ rec {
"futures" = [ "dep:futures" ];
"nix-compat-derive" = [ "dep:nix-compat-derive" ];
"pin-project-lite" = [ "dep:pin-project-lite" ];
"serde" = [ "dep:serde" "dep:serde_json" ];
"serde" = [ "dep:serde" "dep:serde_json" "dep:serde_with" ];
"tokio" = [ "dep:tokio" ];
"url" = [ "dep:url" ];
"wire" = [ "tokio" "pin-project-lite" "bytes" ];

View file

@ -2905,7 +2905,7 @@ rec {
"futures" = [ "dep:futures" ];
"nix-compat-derive" = [ "dep:nix-compat-derive" ];
"pin-project-lite" = [ "dep:pin-project-lite" ];
"serde" = [ "dep:serde" "dep:serde_json" ];
"serde" = [ "dep:serde" "dep:serde_json" "dep:serde_with" ];
"tokio" = [ "dep:tokio" ];
"url" = [ "dep:url" ];
"wire" = [ "tokio" "pin-project-lite" "bytes" ];

View file

@ -2987,7 +2987,7 @@ rec {
"futures" = [ "dep:futures" ];
"nix-compat-derive" = [ "dep:nix-compat-derive" ];
"pin-project-lite" = [ "dep:pin-project-lite" ];
"serde" = [ "dep:serde" "dep:serde_json" ];
"serde" = [ "dep:serde" "dep:serde_json" "dep:serde_with" ];
"tokio" = [ "dep:tokio" ];
"url" = [ "dep:url" ];
"wire" = [ "tokio" "pin-project-lite" "bytes" ];

1
snix/Cargo.lock generated
View file

@ -2613,6 +2613,7 @@ dependencies = [
"rstest",
"serde",
"serde_json",
"serde_with",
"sha2",
"smol_str",
"thiserror 2.0.9",

View file

@ -8300,6 +8300,13 @@ rec {
packageId = "serde_json";
optional = true;
}
{
name = "serde_with";
packageId = "serde_with";
optional = true;
usesDefaultFeatures = false;
features = [ "macros" ];
}
{
name = "sha2";
packageId = "sha2";
@ -8383,7 +8390,7 @@ rec {
"futures" = [ "dep:futures" ];
"nix-compat-derive" = [ "dep:nix-compat-derive" ];
"pin-project-lite" = [ "dep:pin-project-lite" ];
"serde" = [ "dep:serde" "dep:serde_json" ];
"serde" = [ "dep:serde" "dep:serde_json" "dep:serde_with" ];
"tokio" = [ "dep:tokio" ];
"url" = [ "dep:url" ];
"wire" = [ "tokio" "pin-project-lite" "bytes" ];
@ -13770,6 +13777,8 @@ rec {
{
name = "serde_with";
packageId = "serde_with";
usesDefaultFeatures = false;
features = [ "macros" ];
}
{
name = "snix-tracing";
@ -14685,6 +14694,8 @@ rec {
{
name = "serde_with";
packageId = "serde_with";
usesDefaultFeatures = false;
features = [ "macros" ];
}
{
name = "sha1";

View file

@ -117,7 +117,9 @@ serde = "1.0.209"
serde_json = "1.0"
serde_qs = "0.12.0"
serde_tagged = "0.3.0"
serde_with = "3.9.0"
serde_with = { version = "3.9.0", default-features = false, features = [
"macros",
] }
sha1 = "0.10.6"
sha2 = "0.10.8"
smol_str = "0.2.2"

View file

@ -7,10 +7,10 @@ error[E0277]: the trait bound `Test: FromStr` is not satisfied
= help: the following other types implement trait `FromStr`:
ByteString
CString
HashAlgo
IpAddr
Ipv4Addr
Ipv6Addr
NonZero<i128>
NonZero<i16>
NonZero<i32>
and $N others

View file

@ -16,7 +16,7 @@ flakeref = ["url"]
# nix-daemon protocol handling
daemon = ["tokio", "nix-compat-derive", "futures"]
# serde support on types
serde = ["dep:serde", "dep:serde_json"]
serde = ["dep:serde", "dep:serde_json", "dep:serde_with"]
test = []
# Enable all features by default.
@ -36,6 +36,7 @@ nom.workspace = true
num-traits.workspace = true
serde = { workspace = true, features = ["derive"], optional = true }
serde_json = { workspace = true, optional = true }
serde_with = { workspace = true, optional = true }
sha2.workspace = true
thiserror.workspace = true
tracing.workspace = true

View file

@ -1,12 +1,14 @@
use std::fmt::Display;
use std::str::FromStr;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use serde_with::{DeserializeFromStr, SerializeDisplay};
use crate::nixhash::Error;
/// This are the hash algorithms supported by cppnix.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(DeserializeFromStr, SerializeDisplay))]
pub enum HashAlgo {
Md5,
Sha1,
@ -37,37 +39,16 @@ impl Display for HashAlgo {
}
}
#[cfg(feature = "serde")]
impl Serialize for HashAlgo {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.collect_str(&self)
}
}
#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for HashAlgo {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let s: &str = Deserialize::deserialize(deserializer)?;
HashAlgo::try_from(s).map_err(serde::de::Error::custom)
}
}
/// TODO(Raito): this could be automated via macros, I suppose.
/// But this may be more expensive than just doing it by hand
/// and ensuring that is kept in sync.
#[cfg(feature = "serde")]
pub const SUPPORTED_ALGOS: [&str; 4] = ["md5", "sha1", "sha256", "sha512"];
impl TryFrom<&str> for HashAlgo {
type Error = Error;
impl FromStr for HashAlgo {
type Err = Error;
fn try_from(algo_str: &str) -> Result<Self, Self::Error> {
fn from_str(algo_str: &str) -> Result<Self, Self::Err> {
match algo_str {
"md5" => Ok(Self::Md5),
"sha1" => Ok(Self::Sha1),
@ -77,3 +58,10 @@ impl TryFrom<&str> for HashAlgo {
}
}
}
impl TryFrom<&str> for HashAlgo {
type Error = Error;
fn try_from(algo_str: &str) -> Result<Self, Self::Error> {
algo_str.parse()
}
}