From 2997c1c3047d4a9cd9873a28a3e477bd956f0e23 Mon Sep 17 00:00:00 2001 From: edef Date: Fri, 10 Nov 2023 16:19:02 +0000 Subject: [PATCH] feat(nix-compat/narinfo): turn flags into bitfields Change-Id: I8b95723444013e97bc6ec8d282c7135b1aede114 Reviewed-on: https://cl.tvl.fyi/c/depot/+/9987 Reviewed-by: flokli Tested-by: BuildkiteCI --- tvix/Cargo.lock | 1 + tvix/Cargo.nix | 4 +++ tvix/nix-compat/Cargo.toml | 1 + tvix/nix-compat/src/narinfo.rs | 45 ++++++++++++++++++---------------- 4 files changed, 30 insertions(+), 21 deletions(-) diff --git a/tvix/Cargo.lock b/tvix/Cargo.lock index 7130781ae..c202d4d17 100644 --- a/tvix/Cargo.lock +++ b/tvix/Cargo.lock @@ -1431,6 +1431,7 @@ dependencies = [ name = "nix-compat" version = "0.1.0" dependencies = [ + "bitflags 2.4.1", "bstr", "criterion", "data-encoding", diff --git a/tvix/Cargo.nix b/tvix/Cargo.nix index 1e41b0858..aba8494fe 100644 --- a/tvix/Cargo.nix +++ b/tvix/Cargo.nix @@ -4209,6 +4209,10 @@ rec { then lib.cleanSourceWith { filter = sourceFilter; src = ./nix-compat; } else ./nix-compat; dependencies = [ + { + name = "bitflags"; + packageId = "bitflags 2.4.1"; + } { name = "bstr"; packageId = "bstr"; diff --git a/tvix/nix-compat/Cargo.toml b/tvix/nix-compat/Cargo.toml index 7a51d14e2..db6c77201 100644 --- a/tvix/nix-compat/Cargo.toml +++ b/tvix/nix-compat/Cargo.toml @@ -9,6 +9,7 @@ edition = "2021" async = ["futures-util"] [dependencies] +bitflags = "2.4.1" bstr = { version = "1.6.0", features = ["alloc", "unicode", "serde"] } data-encoding = "2.3.3" futures-util = { version = "0.3.28", features = ["io"], optional = true } diff --git a/tvix/nix-compat/src/narinfo.rs b/tvix/nix-compat/src/narinfo.rs index a6df5592a..dc1c6f181 100644 --- a/tvix/nix-compat/src/narinfo.rs +++ b/tvix/nix-compat/src/narinfo.rs @@ -17,6 +17,7 @@ //! * compression algorithm used for the NAR //! * hash and size of the compressed NAR +use bitflags::bitflags; use data_encoding::{BASE64, HEXLOWER}; use std::{ fmt::{self, Display}, @@ -31,10 +32,7 @@ use crate::{ #[derive(Debug)] pub struct NarInfo<'a> { - pub unknown_fields: bool, - pub compression_default: bool, - pub nar_hash_hex: bool, - pub references_out_of_order: bool, + pub flags: Flags, // core (authenticated, but unverified here) /// Store path described by this [NarInfo] pub store_path: StorePathRef<'a>, @@ -70,13 +68,21 @@ pub struct NarInfo<'a> { pub file_size: Option, } +bitflags! { + /// TODO(edef): be conscious of these when roundtripping + #[derive(Debug, Copy, Clone)] + pub struct Flags: u8 { + const UNKNOWN_FIELD = 1 << 0; + const COMPRESSION_DEFAULT = 1 << 1; + // Format quirks encountered in the cache.nixos.org dataset + const REFERENCES_OUT_OF_ORDER = 1 << 2; + const NAR_HASH_HEX = 1 << 3; + } +} + impl<'a> NarInfo<'a> { pub fn parse(input: &'a str) -> Result { - let mut unknown_fields = false; - let mut compression_default = false; - let mut nar_hash_hex = false; - let mut references_out_of_order = false; - + let mut flags = Flags::empty(); let mut store_path = None; let mut url = None; let mut compression = None; @@ -159,7 +165,7 @@ impl<'a> NarInfo<'a> { let val = if val.len() != HEXLOWER.encode_len(32) { nixbase32::decode_fixed::<32>(val) } else { - nar_hash_hex = true; + flags |= Flags::NAR_HASH_HEX; let val = val.as_bytes(); let mut buf = [0u8; 32]; @@ -193,7 +199,7 @@ impl<'a> NarInfo<'a> { .map(|(i, s)| { // TODO(edef): track *duplicates* if this occurs if mem::replace(&mut prev, s) >= s { - references_out_of_order = true; + flags |= Flags::REFERENCES_OUT_OF_ORDER; } StorePathRef::from_bytes(s.as_bytes()) @@ -244,15 +250,12 @@ impl<'a> NarInfo<'a> { } } _ => { - unknown_fields = true; + flags |= Flags::UNKNOWN_FIELD; } } } Ok(NarInfo { - unknown_fields, - nar_hash_hex, - references_out_of_order, store_path: store_path.ok_or(Error::MissingField("StorePath"))?, nar_hash: nar_hash.ok_or(Error::MissingField("NarHash"))?, nar_size: nar_size.ok_or(Error::MissingField("NarSize"))?, @@ -265,14 +268,14 @@ impl<'a> NarInfo<'a> { compression: match compression { Some("none") => None, None => { - compression_default = true; + flags |= Flags::COMPRESSION_DEFAULT; Some("bzip2") } _ => compression, }, - compression_default, file_hash, file_size, + flags, }) } } @@ -502,7 +505,7 @@ mod test { store_path::StorePathRef, }; - use super::NarInfo; + use super::{Flags, NarInfo}; lazy_static! { static ref CASES: &'static [&'static str] = { @@ -541,7 +544,7 @@ Deriver: 2dzpn70c1hawczwhg9aavqk18zp9zsva-gcc-3.4.6.drv Sig: cache.nixos.org-1:o1DTsjCz0PofLJ216P2RBuSulI8BAb6zHxWE4N+tzlcELk5Uk/GO2SCxWTRN5wJutLZZ+cHTMdWqOHF88KGQDg== "#).expect("should parse"); - assert!(parsed.references_out_of_order); + assert!(parsed.flags.contains(Flags::REFERENCES_OUT_OF_ORDER)); assert_eq!( vec![ "a8922c0h87iilxzzvwn2hmv8x210aqb9-glibc-2.7", @@ -597,7 +600,7 @@ System: i686-linux Sig: cache.nixos.org-1:92fl0i5q7EyegCj5Yf4L0bENkWuVAtgveiRcTEEUH0P6HvCE1xFcPbz/0Pf6Np+K1LPzHK+s5RHOmVoxRsvsDg== "#).expect("should parse"); - assert!(parsed.compression_default); + assert!(parsed.flags.contains(Flags::COMPRESSION_DEFAULT)); assert_eq!(parsed.compression, Some("bzip2")); } @@ -615,7 +618,7 @@ Deriver: fb4ihlq3psnsjq95mvvs49rwpplpc8zj-perl-HTTP-Cookies-6.01.drv Sig: cache.nixos.org-1:HhaiY36Uk3XV1JGe9d9xHnzAapqJXprU1YZZzSzxE97jCuO5RR7vlG2kF7MSC5thwRyxAtdghdSz3AqFi+QSCw== "#).expect("should parse"); - assert!(parsed.nar_hash_hex); + assert!(parsed.flags.contains(Flags::NAR_HASH_HEX)); assert_eq!( hex!("60adfd293a4d81ad7cd7e47263cbb3fc846309ef91b154a08ba672b558f94ff3"), parsed.nar_hash,