Skip to content

Commit 645964b

Browse files
committed
review: copilot review on the PR
1 parent d0cbb64 commit 645964b

File tree

1 file changed

+45
-46
lines changed

1 file changed

+45
-46
lines changed

crates/nix_rs/src/info.rs

Lines changed: 45 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
//! Information about the user's Nix installation
22
use serde::{Deserialize, Serialize};
3-
use std::fmt;
3+
use std::{fmt, sync::OnceLock};
44
use tokio::sync::OnceCell;
55

66
use crate::{command::NixCmd, config::NixConfig, env::NixEnv, version::NixVersion};
77
use regex::Regex;
88

9+
static INSTALLATION_TYPE_PATTERNS: OnceLock<Vec<(Regex, NixInstallationType)>> = OnceLock::new();
10+
911
/// Type of Nix installation
10-
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
12+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1113
pub enum NixInstallationType {
1214
/// Official Nix installation
1315
Official,
@@ -25,6 +27,44 @@ impl fmt::Display for NixInstallationType {
2527
}
2628

2729
impl NixInstallationType {
30+
/// Get or initialize the compiled regex patterns
31+
fn get_patterns() -> &'static Vec<(Regex, NixInstallationType)> {
32+
INSTALLATION_TYPE_PATTERNS.get_or_init(|| {
33+
let pattern_strings = [
34+
(
35+
r"^nix \(Determinate Nix [\d.]+\) (\d+)\.(\d+)\.(\d+)$",
36+
NixInstallationType::DeterminateSystems,
37+
),
38+
(
39+
r"^nix \(Nix\) (\d+)\.(\d+)\.(\d+)$",
40+
NixInstallationType::Official,
41+
),
42+
(r"^(\d+)\.(\d+)\.(\d+)$", NixInstallationType::Official),
43+
];
44+
45+
let mut compiled_patterns = Vec::new();
46+
for (pattern_str, installation_type) in pattern_strings {
47+
// If regex compilation fails, we'll panic at startup which is acceptable
48+
let regex = Regex::new(pattern_str).expect("Invalid regex pattern");
49+
compiled_patterns.push((regex, installation_type));
50+
}
51+
compiled_patterns
52+
})
53+
}
54+
55+
/// Detect installation type from a version string
56+
fn from_version_str(version_str: &str) -> Self {
57+
let patterns = Self::get_patterns();
58+
for (regex, installation_type) in patterns {
59+
if regex.is_match(version_str) {
60+
return *installation_type;
61+
}
62+
}
63+
64+
// Default to Official if no pattern matches
65+
NixInstallationType::Official
66+
}
67+
2868
/// Detect the installation type by examining `nix --version` output
2969
async fn detect() -> Result<Self, NixInfoError> {
3070
let cmd = NixCmd::default();
@@ -33,31 +73,10 @@ impl NixInstallationType {
3373
cmd.arg("--version");
3474
})
3575
.await
36-
.map_err(|e| NixInfoError::NixCmdError(crate::command::NixCmdError::CmdError(e)))?;
76+
.map_err(|_| NixInfoError::InstallationTypeDetectionError)?;
3777
let version_str = String::from_utf8_lossy(&output).trim().to_string();
3878

39-
let patterns = [
40-
(
41-
r"^nix \(Determinate Nix [\d.]+\) (\d+)\.(\d+)\.(\d+)$",
42-
NixInstallationType::DeterminateSystems,
43-
),
44-
(
45-
r"^nix \(Nix\) (\d+)\.(\d+)\.(\d+)$",
46-
NixInstallationType::Official,
47-
),
48-
(r"^(\d+)\.(\d+)\.(\d+)$", NixInstallationType::Official),
49-
];
50-
51-
for (pattern, installation_type) in patterns {
52-
let re =
53-
Regex::new(pattern).map_err(|_| NixInfoError::InstallationTypeDetectionError)?;
54-
if re.is_match(&version_str) {
55-
return Ok(installation_type);
56-
}
57-
}
58-
59-
// Default to Official if no pattern matches
60-
Ok(NixInstallationType::Official)
79+
Ok(Self::from_version_str(&version_str))
6180
}
6281
}
6382

@@ -77,27 +96,7 @@ mod tests {
7796
];
7897

7998
for (version_str, expected_type) in test_cases {
80-
let patterns = [
81-
(
82-
r"^nix \(Determinate Nix [\d.]+\) (\d+)\.(\d+)\.(\d+)$",
83-
NixInstallationType::DeterminateSystems,
84-
),
85-
(
86-
r"^nix \(Nix\) (\d+)\.(\d+)\.(\d+)$",
87-
NixInstallationType::Official,
88-
),
89-
(r"^(\d+)\.(\d+)\.(\d+)$", NixInstallationType::Official),
90-
];
91-
92-
let mut detected_type = NixInstallationType::Official; // default
93-
for (pattern, installation_type) in patterns {
94-
let re = Regex::new(pattern).unwrap();
95-
if re.is_match(version_str) {
96-
detected_type = installation_type;
97-
break;
98-
}
99-
}
100-
99+
let detected_type = NixInstallationType::from_version_str(version_str);
101100
assert_eq!(
102101
detected_type, expected_type,
103102
"Failed for version string: '{}'",

0 commit comments

Comments
 (0)