feat(nix-compat): Add serde feature flag
This makes serde features optional behind a flag that is not enabled by default. So Deserialize and Serialize implementations and anything that deals with JSON. Change-Id: I04830aa3883da13ea99a4a51b28981e8a5ecd426 Reviewed-on: https://cl.snix.dev/c/snix/+/30660 Autosubmit: Brian Olsen <brian@maven-group.org> Reviewed-by: Florian Klink <flokli@flokli.de> Tested-by: besadii
This commit is contained in:
parent
2a29b90c7f
commit
6187029077
22 changed files with 176 additions and 121 deletions
2
contrib/crunch-v2/Cargo.lock
generated
2
contrib/crunch-v2/Cargo.lock
generated
|
|
@ -1427,8 +1427,6 @@ dependencies = [
|
|||
"num-traits",
|
||||
"num_enum",
|
||||
"pin-project-lite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.8",
|
||||
"thiserror 2.0.11",
|
||||
"tokio",
|
||||
|
|
|
|||
|
|
@ -4140,15 +4140,6 @@ rec {
|
|||
packageId = "pin-project-lite";
|
||||
optional = true;
|
||||
}
|
||||
{
|
||||
name = "serde";
|
||||
packageId = "serde";
|
||||
features = [ "derive" ];
|
||||
}
|
||||
{
|
||||
name = "serde_json";
|
||||
packageId = "serde_json";
|
||||
}
|
||||
{
|
||||
name = "sha2";
|
||||
packageId = "sha2 0.10.8";
|
||||
|
|
@ -4187,6 +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" ];
|
||||
"tokio" = [ "dep:tokio" ];
|
||||
"url" = [ "dep:url" ];
|
||||
"wire" = [ "tokio" "pin-project-lite" "bytes" ];
|
||||
|
|
|
|||
2
contrib/fetchroots/Cargo.lock
generated
2
contrib/fetchroots/Cargo.lock
generated
|
|
@ -1708,8 +1708,6 @@ dependencies = [
|
|||
"num-traits",
|
||||
"num_enum",
|
||||
"pin-project-lite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"thiserror 2.0.11",
|
||||
"tokio",
|
||||
|
|
|
|||
|
|
@ -5573,15 +5573,6 @@ rec {
|
|||
packageId = "pin-project-lite";
|
||||
optional = true;
|
||||
}
|
||||
{
|
||||
name = "serde";
|
||||
packageId = "serde";
|
||||
features = [ "derive" ];
|
||||
}
|
||||
{
|
||||
name = "serde_json";
|
||||
packageId = "serde_json";
|
||||
}
|
||||
{
|
||||
name = "sha2";
|
||||
packageId = "sha2";
|
||||
|
|
@ -5620,6 +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" ];
|
||||
"tokio" = [ "dep:tokio" ];
|
||||
"url" = [ "dep:url" ];
|
||||
"wire" = [ "tokio" "pin-project-lite" "bytes" ];
|
||||
|
|
|
|||
2
contrib/narinfo2parquet/Cargo.lock
generated
2
contrib/narinfo2parquet/Cargo.lock
generated
|
|
@ -971,8 +971,6 @@ dependencies = [
|
|||
"num-traits",
|
||||
"num_enum",
|
||||
"pin-project-lite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"thiserror 2.0.11",
|
||||
"tokio",
|
||||
|
|
|
|||
|
|
@ -2867,15 +2867,6 @@ rec {
|
|||
packageId = "pin-project-lite";
|
||||
optional = true;
|
||||
}
|
||||
{
|
||||
name = "serde";
|
||||
packageId = "serde";
|
||||
features = [ "derive" ];
|
||||
}
|
||||
{
|
||||
name = "serde_json";
|
||||
packageId = "serde_json";
|
||||
}
|
||||
{
|
||||
name = "sha2";
|
||||
packageId = "sha2";
|
||||
|
|
@ -2914,6 +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" ];
|
||||
"tokio" = [ "dep:tokio" ];
|
||||
"url" = [ "dep:url" ];
|
||||
"wire" = [ "tokio" "pin-project-lite" "bytes" ];
|
||||
|
|
|
|||
2
contrib/weave/Cargo.lock
generated
2
contrib/weave/Cargo.lock
generated
|
|
@ -1010,8 +1010,6 @@ dependencies = [
|
|||
"num-traits",
|
||||
"num_enum",
|
||||
"pin-project-lite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"thiserror 2.0.11",
|
||||
"tokio",
|
||||
|
|
|
|||
|
|
@ -2949,15 +2949,6 @@ rec {
|
|||
packageId = "pin-project-lite";
|
||||
optional = true;
|
||||
}
|
||||
{
|
||||
name = "serde";
|
||||
packageId = "serde";
|
||||
features = [ "derive" ];
|
||||
}
|
||||
{
|
||||
name = "serde_json";
|
||||
packageId = "serde_json";
|
||||
}
|
||||
{
|
||||
name = "sha2";
|
||||
packageId = "sha2";
|
||||
|
|
@ -2996,6 +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" ];
|
||||
"tokio" = [ "dep:tokio" ];
|
||||
"url" = [ "dep:url" ];
|
||||
"wire" = [ "tokio" "pin-project-lite" "bytes" ];
|
||||
|
|
|
|||
|
|
@ -8218,7 +8218,7 @@ rec {
|
|||
{
|
||||
name = "drvfmt";
|
||||
path = "src/bin/drvfmt.rs";
|
||||
requiredFeatures = [ ];
|
||||
requiredFeatures = [ "serde" ];
|
||||
}
|
||||
];
|
||||
src = lib.cleanSourceWith { filter = sourceFilter; src = ./nix-compat; };
|
||||
|
|
@ -8292,11 +8292,13 @@ rec {
|
|||
{
|
||||
name = "serde";
|
||||
packageId = "serde";
|
||||
optional = true;
|
||||
features = [ "derive" ];
|
||||
}
|
||||
{
|
||||
name = "serde_json";
|
||||
packageId = "serde_json";
|
||||
optional = true;
|
||||
}
|
||||
{
|
||||
name = "sha2";
|
||||
|
|
@ -8381,11 +8383,12 @@ rec {
|
|||
"futures" = [ "dep:futures" ];
|
||||
"nix-compat-derive" = [ "dep:nix-compat-derive" ];
|
||||
"pin-project-lite" = [ "dep:pin-project-lite" ];
|
||||
"serde" = [ "dep:serde" "dep:serde_json" ];
|
||||
"tokio" = [ "dep:tokio" ];
|
||||
"url" = [ "dep:url" ];
|
||||
"wire" = [ "tokio" "pin-project-lite" "bytes" ];
|
||||
};
|
||||
resolvedDefaultFeatures = [ "async" "bytes" "daemon" "default" "flakeref" "futures" "nix-compat-derive" "pin-project-lite" "test" "tokio" "url" "wire" ];
|
||||
resolvedDefaultFeatures = [ "async" "bytes" "daemon" "default" "flakeref" "futures" "nix-compat-derive" "pin-project-lite" "serde" "test" "tokio" "url" "wire" ];
|
||||
};
|
||||
"nix-compat-derive" = rec {
|
||||
crateName = "nix-compat-derive";
|
||||
|
|
@ -14636,7 +14639,7 @@ rec {
|
|||
{
|
||||
name = "nix-compat";
|
||||
packageId = "nix-compat";
|
||||
features = [ "async" ];
|
||||
features = [ "async" "serde" ];
|
||||
}
|
||||
{
|
||||
name = "parking_lot";
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@ name = "nix-compat"
|
|||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[[bin]]
|
||||
name = "drvfmt"
|
||||
required-features = ["serde"]
|
||||
|
||||
[features]
|
||||
# async NAR writer. Also needs the `wire` feature.
|
||||
async = ["tokio"]
|
||||
|
|
@ -11,6 +15,8 @@ wire = ["tokio", "pin-project-lite", "bytes"]
|
|||
flakeref = ["url"]
|
||||
# nix-daemon protocol handling
|
||||
daemon = ["tokio", "nix-compat-derive", "futures"]
|
||||
# serde support on types
|
||||
serde = ["dep:serde", "dep:serde_json"]
|
||||
test = []
|
||||
|
||||
# Enable all features by default.
|
||||
|
|
@ -28,8 +34,8 @@ glob.workspace = true
|
|||
mimalloc.workspace = true
|
||||
nom.workspace = true
|
||||
num-traits.workspace = true
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json.workspace = true
|
||||
serde = { workspace = true, features = ["derive"], optional = true }
|
||||
serde_json = { workspace = true, optional = true }
|
||||
sha2.workspace = true
|
||||
thiserror.workspace = true
|
||||
tracing.workspace = true
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use crate::store_path::{
|
|||
self, StorePath, StorePathRef, build_ca_path, build_output_path, build_text_path,
|
||||
};
|
||||
use bstr::BString;
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
|
@ -26,22 +27,23 @@ pub use validate::validate_output_name;
|
|||
|
||||
use self::write::AtermWriteable;
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct Derivation {
|
||||
#[serde(rename = "args")]
|
||||
#[cfg_attr(feature = "serde", serde(rename = "args"))]
|
||||
pub arguments: Vec<String>,
|
||||
|
||||
pub builder: String,
|
||||
|
||||
#[serde(rename = "env")]
|
||||
#[cfg_attr(feature = "serde", serde(rename = "env"))]
|
||||
pub environment: BTreeMap<String, BString>,
|
||||
|
||||
/// Map from drv path to output names used from this derivation.
|
||||
#[serde(rename = "inputDrvs")]
|
||||
#[cfg_attr(feature = "serde", serde(rename = "inputDrvs"))]
|
||||
pub input_derivations: BTreeMap<StorePath<String>, BTreeSet<String>>,
|
||||
|
||||
/// Plain store paths of additional inputs.
|
||||
#[serde(rename = "inputSrcs")]
|
||||
#[cfg_attr(feature = "serde", serde(rename = "inputSrcs"))]
|
||||
pub input_sources: BTreeSet<StorePath<String>>,
|
||||
|
||||
/// Maps output names to Output.
|
||||
|
|
|
|||
|
|
@ -1,20 +1,25 @@
|
|||
use crate::nixhash::CAHash;
|
||||
use crate::{derivation::OutputError, store_path::StorePath};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::de::Unexpected;
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde_json::Map;
|
||||
use std::borrow::Cow;
|
||||
|
||||
/// References the derivation output.
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)]
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize))]
|
||||
pub struct Output {
|
||||
/// Store path of build result.
|
||||
pub path: Option<StorePath<String>>,
|
||||
|
||||
#[serde(flatten)]
|
||||
#[cfg_attr(feature = "serde", serde(flatten))]
|
||||
pub ca_hash: Option<CAHash>, // we can only represent a subset here.
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de> Deserialize<'de> for Output {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
|
|
@ -73,6 +78,7 @@ impl Output {
|
|||
|
||||
/// This ensures that a potentially valid input addressed
|
||||
/// output is deserialized as a non-fixed output.
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn deserialize_valid_input_addressed_output() {
|
||||
let json_bytes = r#"
|
||||
|
|
@ -86,6 +92,7 @@ fn deserialize_valid_input_addressed_output() {
|
|||
|
||||
/// This ensures that a potentially valid fixed output
|
||||
/// output deserializes fine as a fixed output.
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn deserialize_valid_fixed_output() {
|
||||
let json_bytes = r#"
|
||||
|
|
@ -101,6 +108,7 @@ fn deserialize_valid_fixed_output() {
|
|||
|
||||
/// This ensures that parsing an input with the invalid hash encoding
|
||||
/// will result in a parsing failure.
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn deserialize_with_error_invalid_hash_encoding_fixed_output() {
|
||||
let json_bytes = r#"
|
||||
|
|
@ -116,6 +124,7 @@ fn deserialize_with_error_invalid_hash_encoding_fixed_output() {
|
|||
|
||||
/// This ensures that parsing an input with the wrong hash algo
|
||||
/// will result in a parsing failure.
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn deserialize_with_error_invalid_hash_algo_fixed_output() {
|
||||
let json_bytes = r#"
|
||||
|
|
@ -131,6 +140,7 @@ fn deserialize_with_error_invalid_hash_algo_fixed_output() {
|
|||
|
||||
/// This ensures that parsing an input with the missing hash algo but present hash will result in a
|
||||
/// parsing failure.
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn deserialize_with_error_missing_hash_algo_fixed_output() {
|
||||
let json_bytes = r#"
|
||||
|
|
@ -145,6 +155,7 @@ fn deserialize_with_error_missing_hash_algo_fixed_output() {
|
|||
|
||||
/// This ensures that parsing an input with the missing hash but present hash algo will result in a
|
||||
/// parsing failure.
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn deserialize_with_error_missing_hash_fixed_output() {
|
||||
let json_bytes = r#"
|
||||
|
|
@ -157,6 +168,7 @@ fn deserialize_with_error_missing_hash_fixed_output() {
|
|||
assert!(output.is_err());
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn serialize_deserialize() {
|
||||
let json_bytes = r#"
|
||||
|
|
@ -171,6 +183,7 @@ fn serialize_deserialize() {
|
|||
assert_eq!(output, output2);
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn serialize_deserialize_fixed() {
|
||||
let json_bytes = r#"
|
||||
|
|
|
|||
|
|
@ -1,19 +1,28 @@
|
|||
use super::parse_error::ErrorKind;
|
||||
use crate::derivation::Derivation;
|
||||
#[cfg(feature = "serde")]
|
||||
use crate::derivation::output::Output;
|
||||
use crate::derivation::parse_error::NomError;
|
||||
use crate::derivation::parser::Error;
|
||||
#[cfg(feature = "serde")]
|
||||
use crate::store_path::StorePath;
|
||||
#[cfg(feature = "serde")]
|
||||
use bstr::{BStr, BString};
|
||||
#[cfg(feature = "serde")]
|
||||
use hex_literal::hex;
|
||||
#[cfg(feature = "serde")]
|
||||
use rstest::rstest;
|
||||
#[cfg(feature = "serde")]
|
||||
use std::collections::BTreeSet;
|
||||
use std::fs;
|
||||
#[cfg(feature = "serde")]
|
||||
use std::path::{Path, PathBuf};
|
||||
#[cfg(feature = "serde")]
|
||||
use std::str::FromStr;
|
||||
|
||||
const RESOURCES_PATHS: &str = "src/derivation/tests/derivation_tests";
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[rstest]
|
||||
fn check_serialization(
|
||||
#[files("src/derivation/tests/derivation_tests/ok/*.drv")]
|
||||
|
|
@ -33,6 +42,7 @@ fn check_serialization(
|
|||
assert_eq!(expected, BStr::new(&serialized_derivation));
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[rstest]
|
||||
fn validate(
|
||||
#[files("src/derivation/tests/derivation_tests/ok/*.drv")]
|
||||
|
|
@ -49,6 +59,7 @@ fn validate(
|
|||
.expect("derivation failed to validate")
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[rstest]
|
||||
fn check_to_aterm_bytes(
|
||||
#[files("src/derivation/tests/derivation_tests/ok/*.drv")]
|
||||
|
|
@ -68,6 +79,7 @@ fn check_to_aterm_bytes(
|
|||
/// Reads in derivations in ATerm representation, parses with that parser,
|
||||
/// then compares the structs with the ones obtained by parsing the JSON
|
||||
/// representations.
|
||||
#[cfg(feature = "serde")]
|
||||
#[rstest]
|
||||
fn from_aterm_bytes(
|
||||
#[files("src/derivation/tests/derivation_tests/ok/*.drv")] path_to_drv_file: PathBuf,
|
||||
|
|
@ -139,6 +151,7 @@ fn from_aterm_bytes_trailer() {
|
|||
Derivation::from_aterm_bytes(&buf).expect_err("must fail");
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[rstest]
|
||||
#[case::fixed_sha256("bar", "0hm2f1psjpcwg8fijsmr4wwxrx59s092-bar.drv")]
|
||||
#[case::simple_sha256("foo", "4wvvbi4jwn0prsdxb7vs673qa5h9gr7x-foo.drv")]
|
||||
|
|
@ -164,6 +177,7 @@ fn derivation_path(#[case] name: &str, #[case] expected_path: &str) {
|
|||
|
||||
/// This trims all output paths from a Derivation struct,
|
||||
/// by setting outputs[$outputName].path and environment[$outputName] to the empty string.
|
||||
#[cfg(feature = "serde")]
|
||||
fn derivation_without_output_paths(derivation: &Derivation) -> Derivation {
|
||||
let mut trimmed_env = derivation.environment.clone();
|
||||
let mut trimmed_outputs = derivation.outputs.clone();
|
||||
|
|
@ -188,6 +202,7 @@ fn derivation_without_output_paths(derivation: &Derivation) -> Derivation {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[rstest]
|
||||
#[case::fixed_sha256("0hm2f1psjpcwg8fijsmr4wwxrx59s092-bar.drv", hex!("724f3e3634fce4cbbbd3483287b8798588e80280660b9a63fd13a1bc90485b33"))]
|
||||
#[case::fixed_sha1("ss2p4wmxijn652haqyd7dckxwl4c7hxx-bar.drv", hex!("c79aebd0ce3269393d4a1fde2cbd1d975d879b40f0bf40a48f550edc107fd5df"))]
|
||||
|
|
@ -204,6 +219,7 @@ fn hash_derivation_modulo_fixed(#[case] drv_path: &str, #[case] expected_digest:
|
|||
/// This reads a Derivation (in A-Term), trims out all fields containing
|
||||
/// calculated output paths, then triggers the output path calculation and
|
||||
/// compares the struct to match what was originally read in.
|
||||
#[cfg(feature = "serde")]
|
||||
#[rstest]
|
||||
#[case::fixed_sha256("bar", "0hm2f1psjpcwg8fijsmr4wwxrx59s092-bar.drv")]
|
||||
#[case::simple_sha256("foo", "4wvvbi4jwn0prsdxb7vs673qa5h9gr7x-foo.drv")]
|
||||
|
|
@ -298,6 +314,7 @@ fn output_paths(#[case] name: &str, #[case] drv_path_str: &str) {
|
|||
/// it, then continues with the foo derivation.
|
||||
///
|
||||
/// The code ensures the resulting Derivations match our fixtures.
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn output_path_construction() {
|
||||
// create the bar derivation
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
//! Contains types Nix uses for its logging, visible in the "internal-json" log
|
||||
//! messages as well as in nix-daemon communication.
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
#[cfg(feature = "serde")]
|
||||
use tracing::warn;
|
||||
|
||||
/// Every "internal-json" log line emitted by Nix has this prefix.
|
||||
|
|
@ -9,17 +11,13 @@ pub const AT_NIX_PREFIX: &str = "@nix ";
|
|||
|
||||
/// The different verbosity levels Nix distinguishes.
|
||||
#[derive(
|
||||
Clone,
|
||||
Debug,
|
||||
Eq,
|
||||
PartialEq,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
num_enum::TryFromPrimitive,
|
||||
num_enum::IntoPrimitive,
|
||||
Default,
|
||||
Clone, Debug, Eq, PartialEq, num_enum::TryFromPrimitive, num_enum::IntoPrimitive, Default,
|
||||
)]
|
||||
#[cfg_attr(
|
||||
feature = "serde",
|
||||
derive(Serialize, Deserialize),
|
||||
serde(try_from = "u64", into = "u64")
|
||||
)]
|
||||
#[serde(try_from = "u64", into = "u64")]
|
||||
#[cfg_attr(
|
||||
feature = "daemon",
|
||||
derive(nix_compat_derive::NixDeserialize, nix_compat_derive::NixSerialize),
|
||||
|
|
@ -59,13 +57,14 @@ impl std::fmt::Display for VerbosityLevel {
|
|||
|
||||
/// The different types of log messages Nix' `internal-json` format can
|
||||
/// represent.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(tag = "action" /*, deny_unknown_fields */)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde",
|
||||
derive(Serialize, Deserialize),
|
||||
serde(tag = "action", rename_all = "camelCase" /*, deny_unknown_fields */))]
|
||||
// TODO: deny_unknown_fields doesn't seem to work in the testcases below
|
||||
pub enum LogMessage<'a> {
|
||||
#[serde(rename = "start")]
|
||||
Start {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
|
||||
fields: Option<Vec<Field<'a>>>,
|
||||
id: u64,
|
||||
level: VerbosityLevel,
|
||||
|
|
@ -74,10 +73,10 @@ pub enum LogMessage<'a> {
|
|||
r#type: ActivityType,
|
||||
},
|
||||
|
||||
#[serde(rename = "stop")]
|
||||
Stop { id: u64 },
|
||||
Stop {
|
||||
id: u64,
|
||||
},
|
||||
|
||||
#[serde(rename = "result")]
|
||||
Result {
|
||||
fields: Vec<Field<'a>>,
|
||||
id: u64,
|
||||
|
|
@ -86,7 +85,6 @@ pub enum LogMessage<'a> {
|
|||
|
||||
// FUTUREWORK: there sometimes seems to be column/file/line fields set to null, and a raw_msg field,
|
||||
// see msg_with_raw_msg testcase. These should be represented.
|
||||
#[serde(rename = "msg")]
|
||||
Msg {
|
||||
level: VerbosityLevel,
|
||||
msg: std::borrow::Cow<'a, str>,
|
||||
|
|
@ -94,10 +92,12 @@ pub enum LogMessage<'a> {
|
|||
|
||||
// Log lines like these are sent by nixpkgs stdenv, present in `nix log` outputs of individual builds.
|
||||
// They are also interpreted by Nix to re-emit [Self::Result]-style messages.
|
||||
#[serde(rename = "setPhase")]
|
||||
SetPhase { phase: &'a str },
|
||||
SetPhase {
|
||||
phase: &'a str,
|
||||
},
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
fn serialize_bytes_as_string<S>(b: &[u8], serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
|
|
@ -113,24 +113,22 @@ where
|
|||
|
||||
/// Fields in a log message can be either ints or strings.
|
||||
/// Sometimes, Nix also uses invalid UTF-8 in here, so we use BStr.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
|
||||
#[serde(untagged)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(untagged))]
|
||||
pub enum Field<'a> {
|
||||
Int(u64),
|
||||
String(#[serde(serialize_with = "serialize_bytes_as_string")] std::borrow::Cow<'a, [u8]>),
|
||||
String(
|
||||
#[cfg_attr(feature = "serde", serde(serialize_with = "serialize_bytes_as_string"))]
|
||||
std::borrow::Cow<'a, [u8]>,
|
||||
),
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Clone,
|
||||
Debug,
|
||||
Eq,
|
||||
PartialEq,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
num_enum::TryFromPrimitive,
|
||||
num_enum::IntoPrimitive,
|
||||
#[derive(Clone, Debug, Eq, PartialEq, num_enum::TryFromPrimitive, num_enum::IntoPrimitive)]
|
||||
#[cfg_attr(
|
||||
feature = "serde",
|
||||
derive(Serialize, Deserialize),
|
||||
serde(try_from = "u8", into = "u8")
|
||||
)]
|
||||
#[serde(try_from = "u8", into = "u8")]
|
||||
#[repr(u8)]
|
||||
pub enum ActivityType {
|
||||
Unknown = 0,
|
||||
|
|
@ -174,17 +172,12 @@ impl std::fmt::Display for ActivityType {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Clone,
|
||||
Debug,
|
||||
Eq,
|
||||
PartialEq,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
num_enum::TryFromPrimitive,
|
||||
num_enum::IntoPrimitive,
|
||||
#[derive(Clone, Debug, Eq, PartialEq, num_enum::TryFromPrimitive, num_enum::IntoPrimitive)]
|
||||
#[cfg_attr(
|
||||
feature = "serde",
|
||||
derive(Serialize, Deserialize),
|
||||
serde(try_from = "u8", into = "u8")
|
||||
)]
|
||||
#[serde(try_from = "u8", into = "u8")]
|
||||
#[repr(u8)]
|
||||
pub enum ResultType {
|
||||
FileLinked = 100,
|
||||
|
|
@ -200,6 +193,7 @@ pub enum ResultType {
|
|||
|
||||
impl<'a> LogMessage<'a> {
|
||||
/// Parses a given log message string into a [LogMessage].
|
||||
#[cfg(feature = "serde")]
|
||||
pub fn from_json_str(s: &'a str) -> Result<Self, Error> {
|
||||
let s = s.strip_prefix(AT_NIX_PREFIX).ok_or(Error::MissingPrefix)?;
|
||||
|
||||
|
|
@ -207,6 +201,7 @@ impl<'a> LogMessage<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl std::fmt::Display for LogMessage<'_> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
|
|
@ -217,6 +212,7 @@ impl std::fmt::Display for LogMessage<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error("Missing @nix prefix")]
|
||||
|
|
@ -231,7 +227,10 @@ pub enum Error {
|
|||
// while it *is* compared.
|
||||
#[allow(unused_variables)]
|
||||
mod test {
|
||||
use super::{ActivityType, Field, LogMessage, ResultType, VerbosityLevel};
|
||||
use super::VerbosityLevel;
|
||||
#[cfg(feature = "serde")]
|
||||
use super::{ActivityType, Field, LogMessage, ResultType};
|
||||
#[cfg(feature = "serde")]
|
||||
use rstest::rstest;
|
||||
|
||||
#[test]
|
||||
|
|
@ -247,6 +246,7 @@ mod test {
|
|||
VerbosityLevel::try_from(42).expect_err("must fail parsing");
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[rstest]
|
||||
#[case::start(
|
||||
r#"@nix {"action":"start","id":1264799149195466,"level":5,"parent":0,"text":"copying '/nix/store/rfqxfljma55x8ybmyg07crnarvqx62sr-nixpkgs-src/pkgs/development/compilers/llvm/18/llvm/lit-shell-script-runner-set-dyld-library-path.patch' to the store","type":0}"#,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
pub(crate) mod wire;
|
||||
|
||||
mod copy;
|
||||
#[cfg(feature = "serde")]
|
||||
pub mod listing;
|
||||
pub mod reader;
|
||||
pub mod writer;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use std::{
|
|||
};
|
||||
|
||||
use data_encoding::BASE64;
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
const SIGNATURE_LENGTH: usize = std::mem::size_of::<ed25519::SignatureBytes>();
|
||||
|
|
@ -100,6 +101,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'a, 'de, S> Deserialize<'de> for Signature<S>
|
||||
where
|
||||
S: Deref<Target = str> + From<&'a str>,
|
||||
|
|
@ -116,6 +118,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<S: Display> Serialize for Signature<S>
|
||||
where
|
||||
S: Deref<Target = str>,
|
||||
|
|
@ -165,6 +168,7 @@ pub enum Error {
|
|||
mod test {
|
||||
use data_encoding::BASE64;
|
||||
use ed25519_dalek::VerifyingKey;
|
||||
#[cfg(feature = "serde")]
|
||||
use hex_literal::hex;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
|
|
@ -221,6 +225,7 @@ mod test {
|
|||
Signature::<&str>::parse(input).expect_err("must fail");
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn serialize_deserialize() {
|
||||
let signature_actual = Signature {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::fmt::Display;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::nixhash::Error;
|
||||
|
|
@ -36,6 +37,7 @@ impl Display for HashAlgo {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl Serialize for HashAlgo {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
|
|
@ -45,6 +47,7 @@ impl Serialize for HashAlgo {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de> Deserialize<'de> for HashAlgo {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
|
|
@ -58,6 +61,7 @@ impl<'de> Deserialize<'de> for HashAlgo {
|
|||
/// 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 {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
use crate::nixbase32;
|
||||
use crate::nixhash::{HashAlgo, NixHash};
|
||||
use serde::de::Unexpected;
|
||||
use serde::ser::SerializeMap;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use crate::nixhash::NixHash;
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Unexpected, ser::SerializeMap};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde_json::{Map, Value};
|
||||
use std::borrow::Cow;
|
||||
|
||||
use super::algos::SUPPORTED_ALGOS;
|
||||
use super::decode_digest;
|
||||
|
||||
/// A Nix CAHash describes a content-addressed hash of a path.
|
||||
///
|
||||
/// The way Nix prints it as a string is a bit confusing, but there's essentially
|
||||
|
|
@ -119,10 +116,15 @@ impl CAHash {
|
|||
///
|
||||
/// This is to match how `nix show-derivation` command shows them in JSON
|
||||
/// representation.
|
||||
#[cfg(feature = "serde")]
|
||||
pub(crate) fn from_map<'de, D>(map: &Map<String, Value>) -> Result<Option<Self>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
use super::algos::SUPPORTED_ALGOS;
|
||||
use super::decode_digest;
|
||||
use crate::nixhash::HashAlgo;
|
||||
|
||||
// If we don't have hash neither hashAlgo, let's just return None.
|
||||
if !map.contains_key("hash") && !map.contains_key("hashAlgo") {
|
||||
return Ok(None);
|
||||
|
|
@ -166,6 +168,7 @@ impl CAHash {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl Serialize for CAHash {
|
||||
/// map a CAHash into the serde data model.
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
|
|
@ -194,6 +197,7 @@ impl Serialize for CAHash {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de> Deserialize<'de> for CAHash {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
|
|
@ -210,13 +214,16 @@ impl<'de> Deserialize<'de> for CAHash {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[cfg(feature = "serde")]
|
||||
use hex_literal::hex;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use crate::{
|
||||
derivation::CAHash,
|
||||
nixhash::{HashAlgo, NixHash},
|
||||
};
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn serialize_flat() {
|
||||
let json_bytes = r#"{
|
||||
|
|
@ -234,6 +241,7 @@ mod tests {
|
|||
assert_eq!(serialized, json_bytes);
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn serialize_nar() {
|
||||
let json_bytes = r#"{
|
||||
|
|
@ -251,6 +259,7 @@ mod tests {
|
|||
assert_eq!(serialized, json_bytes);
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn deserialize_flat() {
|
||||
let json_bytes = r#"
|
||||
|
|
@ -272,6 +281,7 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn deserialize_hex() {
|
||||
let json_bytes = r#"
|
||||
|
|
@ -293,6 +303,7 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn deserialize_nixbase32() {
|
||||
let json_bytes = r#"
|
||||
|
|
@ -314,6 +325,7 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn deserialize_base64() {
|
||||
let json_bytes = r#"
|
||||
|
|
@ -335,6 +347,7 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn serialize_deserialize_nar() {
|
||||
let json_bytes = r#"
|
||||
|
|
@ -350,6 +363,7 @@ mod tests {
|
|||
assert_eq!(hash, hash2);
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn serialize_deserialize_flat() {
|
||||
let json_bytes = r#"
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use thiserror;
|
|||
|
||||
mod algos;
|
||||
mod ca_hash;
|
||||
#[cfg(feature = "serde")]
|
||||
pub mod serde;
|
||||
|
||||
pub use algos::HashAlgo;
|
||||
|
|
@ -537,6 +538,7 @@ mod tests {
|
|||
NixHash::from_str(weird_base64, Some(HashAlgo::Sha256)).expect_err("must fail");
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn serialize_deserialize() {
|
||||
let nixhash_actual = NixHash::Sha256(hex!(
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
use crate::{narinfo::SignatureRef, nixhash, store_path::StorePathRef};
|
||||
#[cfg(feature = "serde")]
|
||||
use crate::nixhash;
|
||||
use crate::{narinfo::SignatureRef, store_path::StorePathRef};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
|
|
@ -7,26 +10,34 @@ use std::collections::BTreeSet;
|
|||
/// This is not to be confused with the format Nix uses in its `nix path-info` command.
|
||||
/// It includes some more fields, like `registrationTime`, `signatures` and `ultimate`,
|
||||
/// does not include the `closureSize` and encodes `narHash` as SRI.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(
|
||||
feature = "serde",
|
||||
derive(Serialize, Deserialize),
|
||||
serde(rename_all = "camelCase")
|
||||
)]
|
||||
pub struct ExportedPathInfo<'a> {
|
||||
#[serde(rename = "closureSize")]
|
||||
pub closure_size: u64,
|
||||
|
||||
#[serde(
|
||||
rename = "narHash",
|
||||
serialize_with = "nixhash::serde::to_nix_nixbase32",
|
||||
deserialize_with = "nixhash::serde::from_nix_nixbase32_or_sri"
|
||||
#[cfg_attr(
|
||||
feature = "serde",
|
||||
serde(
|
||||
rename = "narHash",
|
||||
serialize_with = "nixhash::serde::to_nix_nixbase32",
|
||||
deserialize_with = "nixhash::serde::from_nix_nixbase32_or_sri"
|
||||
)
|
||||
)]
|
||||
pub nar_sha256: [u8; 32],
|
||||
|
||||
#[serde(rename = "narSize")]
|
||||
pub nar_size: u64,
|
||||
|
||||
#[serde(borrow)]
|
||||
#[cfg_attr(feature = "serde", serde(borrow))]
|
||||
pub path: StorePathRef<'a>,
|
||||
|
||||
#[serde(borrow)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[cfg_attr(
|
||||
feature = "serde",
|
||||
serde(borrow, skip_serializing_if = "Option::is_none")
|
||||
)]
|
||||
pub deriver: Option<StorePathRef<'a>>,
|
||||
|
||||
/// The list of other Store Paths this Store Path refers to.
|
||||
|
|
@ -34,7 +45,10 @@ pub struct ExportedPathInfo<'a> {
|
|||
pub references: BTreeSet<StorePathRef<'a>>,
|
||||
// more recent versions of Nix also have a `valid: true` field here, Nix 2.3 doesn't,
|
||||
// and nothing seems to use it.
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
#[cfg_attr(
|
||||
feature = "serde",
|
||||
serde(default, skip_serializing_if = "Vec::is_empty")
|
||||
)]
|
||||
pub signatures: Vec<SignatureRef<'a>>,
|
||||
}
|
||||
|
||||
|
|
@ -53,11 +67,14 @@ impl PartialOrd for ExportedPathInfo<'_> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[cfg(feature = "serde")]
|
||||
use hex_literal::hex;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use super::*;
|
||||
|
||||
/// Ensure we can create the same JSON as the exportReferencesGraph feature
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn serialize_deserialize() {
|
||||
// JSON extracted from a build of
|
||||
|
|
@ -95,6 +112,7 @@ mod tests {
|
|||
}
|
||||
|
||||
/// Ensure we can parse output from `nix path-info --json``
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn serialize_deserialize_from_path_info() {
|
||||
// JSON extracted from
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use crate::nixbase32;
|
||||
use data_encoding::{BASE64, DecodeError};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
fmt,
|
||||
|
|
@ -236,6 +237,7 @@ impl FromStr for StorePath<String> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'a, 'de: 'a, S> Deserialize<'de> for StorePath<S>
|
||||
where
|
||||
S: AsRef<str> + From<&'a str>,
|
||||
|
|
@ -258,6 +260,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<S> Serialize for StorePath<S>
|
||||
where
|
||||
S: AsRef<str>,
|
||||
|
|
@ -345,11 +348,13 @@ mod tests {
|
|||
use hex_literal::hex;
|
||||
use pretty_assertions::assert_eq;
|
||||
use rstest::rstest;
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
/// An example struct, holding a StorePathRef.
|
||||
/// Used to test deserializing StorePathRef.
|
||||
#[cfg(feature = "serde")]
|
||||
#[derive(Deserialize)]
|
||||
struct Container<'a> {
|
||||
#[serde(borrow)]
|
||||
store_path: StorePathRef<'a>,
|
||||
|
|
@ -492,6 +497,7 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn serialize_ref() {
|
||||
let nixpath_actual = StorePathRef::from_bytes(
|
||||
|
|
@ -507,6 +513,7 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn serialize_owned() {
|
||||
let nixpath_actual = StorePathRef::from_bytes(
|
||||
|
|
@ -522,6 +529,7 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn deserialize_ref() {
|
||||
let store_path_str_json =
|
||||
|
|
@ -536,6 +544,7 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn deserialize_ref_container() {
|
||||
let str_json = "{\"store_path\":\"/nix/store/00bgd045z0d4icpbc2yyz4gx48ak44la-net-tools-1.60_p20170221182432\"}";
|
||||
|
|
@ -548,6 +557,7 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn deserialize_owned() {
|
||||
let store_path_str_json =
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ data-encoding.workspace = true
|
|||
ed25519.workspace = true
|
||||
ed25519-dalek.workspace = true
|
||||
futures.workspace = true
|
||||
nix-compat = { path = "../nix-compat", features = ["async"] }
|
||||
nix-compat = { path = "../nix-compat", features = ["async", "serde"] }
|
||||
pin-project-lite.workspace = true
|
||||
prost.workspace = true
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue