From 9845dfa58174f38917360f874e2f5fbf86ac45cd Mon Sep 17 00:00:00 2001 From: Ruben Arts Date: Fri, 20 Dec 2024 12:13:42 +0100 Subject: [PATCH] feat: Implement serializer for system_requirements --- .../pixi_manifest/src/system_requirements.rs | 100 +++++++++++++++++- 1 file changed, 97 insertions(+), 3 deletions(-) diff --git a/crates/pixi_manifest/src/system_requirements.rs b/crates/pixi_manifest/src/system_requirements.rs index 303ac3a76..ec2a65209 100644 --- a/crates/pixi_manifest/src/system_requirements.rs +++ b/crates/pixi_manifest/src/system_requirements.rs @@ -1,8 +1,10 @@ use miette::Diagnostic; use rattler_conda_types::Version; use rattler_virtual_packages::{Cuda, LibC, Linux, Osx, VirtualPackage}; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; +use serde_value::Value; use serde_with::{serde_as, DisplayFromStr}; +use std::collections::BTreeMap; use std::str::FromStr; use thiserror::Error; @@ -10,7 +12,7 @@ const GLIBC_FAMILY: &str = "glibc"; /// Describes the minimal system requirements to be able to run a certain environment. #[serde_as] -#[derive(Debug, Clone, Deserialize, Default, PartialEq, Eq)] +#[derive(Debug, Clone, Deserialize, Serialize, Default, PartialEq, Eq)] #[serde(deny_unknown_fields)] pub struct SystemRequirements { /// Dictates the minimum version of macOS required. @@ -124,6 +126,15 @@ impl SystemRequirements { archspec, }) } + + /// Returns true if the system requirements are empty, meaning that no requirements were specified. + pub fn is_empty(&self) -> bool { + self.linux.is_none() + && self.cuda.is_none() + && self.macos.is_none() + && self.libc.is_none() + && self.archspec.is_none() + } } #[derive(Debug, Clone, Error, Diagnostic)] @@ -183,8 +194,33 @@ impl LibCSystemRequirement { } } +impl Serialize for LibCSystemRequirement { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + match self { + LibCSystemRequirement::GlibC(version) => serializer.serialize_str(&version.to_string()), + LibCSystemRequirement::OtherFamily(LibCFamilyAndVersion { family, version }) => { + let mut map = BTreeMap::new(); // Initialize the BTreeMap + if let Some(fam) = family { + map.insert( + Value::String("family".to_string()), + Value::String(fam.clone()), + ); + } + map.insert( + Value::String("version".to_string()), + Value::String(version.to_string()), + ); + Value::Map(map).serialize(serializer) // Wrap the map in Value::Map + } + } + } +} + #[serde_as] -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Deserialize, Serialize)] #[serde(deny_unknown_fields)] pub struct LibCFamilyAndVersion { /// The libc family, e.g. glibc @@ -225,6 +261,7 @@ mod tests { use rattler_virtual_packages::{Cuda, LibC, Linux, Osx, VirtualPackage}; use serde::Deserialize; use std::str::FromStr; + use toml_edit::ser::to_string_pretty; #[test] fn system_requirements_works() { @@ -471,4 +508,61 @@ mod tests { assert_matches!(eglibc_2_17.union(&glibc_2_12).unwrap_err(), SystemRequirementsUnionError::DifferentLibcFamilies(fam_a, fam_b) if fam_a == "eglibc" && fam_b == "glibc"); } + + #[test] + fn test_serialization() { + let system_requirements = SystemRequirements { + macos: Some(Version::from_str("10.15").unwrap()), + linux: Some(Version::from_str("5.11").unwrap()), + cuda: Some(Version::from_str("12.2").unwrap()), + libc: Some(LibCSystemRequirement::GlibC( + Version::from_str("2.12").unwrap(), + )), + archspec: Some("x86_64".to_string()), + }; + + let serialized = to_string_pretty(&system_requirements).unwrap(); + + let expected = r#" + macos = "10.15" + linux = "5.11" + cuda = "12.2" + libc = "2.12" + archspec = "x86_64" + "#; + assert_eq!( + serialized.replace("\n", "").replace(" ", ""), + expected.replace("\n", "").replace(" ", "") + ); + } + + #[test] + fn test_serialization_other_family() { + let system_requirements = SystemRequirements { + macos: Some(Version::from_str("10.15").unwrap()), + linux: Some(Version::from_str("5.11").unwrap()), + cuda: Some(Version::from_str("12.2").unwrap()), + libc: Some(LibCSystemRequirement::OtherFamily(LibCFamilyAndVersion { + family: Some("glibc".to_string()), + version: Version::from_str("2.12").unwrap(), + })), + archspec: Some("x86_64".to_string()), + }; + + let serialized = to_string_pretty(&system_requirements).unwrap(); + let expected = r#" + macos = "10.15" + linux = "5.11" + cuda = "12.2" + archspec = "x86_64" + + [libc] + family = "glibc" + version = "2.12" + "#; + assert_eq!( + serialized.replace("\n", "").replace(" ", ""), + expected.replace("\n", "").replace(" ", "") + ); + } }