feat(tvix/nix-compat): serde for StorePath[Ref]s
Necessary, if we want to use it inside of `Derivation` etc. Change-Id: I8888060417b2ee83ac52d7ec3e7b27c393271d8b Reviewed-on: https://cl.tvl.fyi/c/depot/+/10947 Reviewed-by: tazjin <tazjin@tvl.su> Autosubmit: Peter Kolloch <info@eigenvalue.net> Tested-by: BuildkiteCI Reviewed-by: flokli <flokli@flokli.de>
This commit is contained in:
parent
d293304667
commit
e87f2a2b3a
1 changed files with 94 additions and 0 deletions
|
@ -1,5 +1,6 @@
|
|||
use crate::nixbase32;
|
||||
use data_encoding::{DecodeError, BASE64};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
fmt,
|
||||
path::PathBuf,
|
||||
|
@ -135,6 +136,26 @@ impl StorePath {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for StorePath {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let r = <StorePathRef<'de> as Deserialize<'de>>::deserialize(deserializer)?;
|
||||
Ok(r.to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for StorePath {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
let r: StorePathRef = self.into();
|
||||
r.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
/// Like [StorePath], but without a heap allocation for the name.
|
||||
/// Used by [StorePath] for parsing.
|
||||
///
|
||||
|
@ -220,6 +241,35 @@ impl<'a> StorePathRef<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for StorePathRef<'de> {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let string: &'de str = Deserialize::deserialize(deserializer)?;
|
||||
let stripped: Option<&str> = string.strip_prefix(STORE_DIR_WITH_SLASH);
|
||||
let stripped: &str = stripped.ok_or_else(|| {
|
||||
serde::de::Error::invalid_value(
|
||||
serde::de::Unexpected::Str(string),
|
||||
&"store path prefix",
|
||||
)
|
||||
})?;
|
||||
StorePathRef::from_bytes(stripped.as_bytes()).map_err(|_| {
|
||||
serde::de::Error::invalid_value(serde::de::Unexpected::Str(string), &"StorePath")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for StorePathRef<'_> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
let string: String = self.to_absolute_path();
|
||||
string.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
/// NAME_CHARS contains `true` for bytes that are valid in store path names,
|
||||
/// not accounting for '.' being permitted only past the first character.
|
||||
static NAME_CHARS: [bool; 256] = {
|
||||
|
@ -388,6 +438,50 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_ref() {
|
||||
let store_path_str =
|
||||
"/nix/store/00bgd045z0d4icpbc2yyz4gx48ak44la-net-tools-1.60_p20170221182432";
|
||||
let nixpath_actual =
|
||||
StorePathRef::from_absolute_path(store_path_str.as_bytes()).expect("can parse");
|
||||
|
||||
let serialized = serde_json::to_string(&nixpath_actual).expect("can serialize");
|
||||
|
||||
assert_eq!(
|
||||
"\"/nix/store/00bgd045z0d4icpbc2yyz4gx48ak44la-net-tools-1.60_p20170221182432\"",
|
||||
&serialized
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_owned() {
|
||||
let store_path_str =
|
||||
"/nix/store/00bgd045z0d4icpbc2yyz4gx48ak44la-net-tools-1.60_p20170221182432";
|
||||
let nixpath_actual = StorePathRef::from_absolute_path(store_path_str.as_bytes())
|
||||
.expect("can parse")
|
||||
.to_owned();
|
||||
|
||||
let serialized = serde_json::to_string(&nixpath_actual).expect("can serialize");
|
||||
|
||||
assert_eq!(
|
||||
"\"/nix/store/00bgd045z0d4icpbc2yyz4gx48ak44la-net-tools-1.60_p20170221182432\"",
|
||||
&serialized
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialize_ref() {
|
||||
let store_path_str_json =
|
||||
"\"/nix/store/00bgd045z0d4icpbc2yyz4gx48ak44la-net-tools-1.60_p20170221182432\"";
|
||||
|
||||
let store_path: StorePath = serde_json::from_str(store_path_str_json).expect("valid json");
|
||||
|
||||
assert_eq!(
|
||||
"/nix/store/00bgd045z0d4icpbc2yyz4gx48ak44la-net-tools-1.60_p20170221182432",
|
||||
store_path.to_absolute_path()
|
||||
);
|
||||
}
|
||||
|
||||
#[test_case(
|
||||
"/nix/store/00bgd045z0d4icpbc2yyz4gx48ak44la-net-tools-1.60_p20170221182432",
|
||||
(StorePath::from_bytes(b"00bgd045z0d4icpbc2yyz4gx48ak44la-net-tools-1.60_p20170221182432").unwrap(), PathBuf::new())
|
||||
|
|
Loading…
Reference in a new issue