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 crate::nixbase32;
|
||||||
use data_encoding::{DecodeError, BASE64};
|
use data_encoding::{DecodeError, BASE64};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
fmt,
|
fmt,
|
||||||
path::PathBuf,
|
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.
|
/// Like [StorePath], but without a heap allocation for the name.
|
||||||
/// Used by [StorePath] for parsing.
|
/// 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,
|
/// NAME_CHARS contains `true` for bytes that are valid in store path names,
|
||||||
/// not accounting for '.' being permitted only past the first character.
|
/// not accounting for '.' being permitted only past the first character.
|
||||||
static NAME_CHARS: [bool; 256] = {
|
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(
|
#[test_case(
|
||||||
"/nix/store/00bgd045z0d4icpbc2yyz4gx48ak44la-net-tools-1.60_p20170221182432",
|
"/nix/store/00bgd045z0d4icpbc2yyz4gx48ak44la-net-tools-1.60_p20170221182432",
|
||||||
(StorePath::from_bytes(b"00bgd045z0d4icpbc2yyz4gx48ak44la-net-tools-1.60_p20170221182432").unwrap(), PathBuf::new())
|
(StorePath::from_bytes(b"00bgd045z0d4icpbc2yyz4gx48ak44la-net-tools-1.60_p20170221182432").unwrap(), PathBuf::new())
|
||||||
|
|
Loading…
Reference in a new issue