diff --git a/Cargo.toml b/Cargo.toml index 4925a3a..9f421bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ name = "wire" [workspace.lints.clippy] pedantic = { level = "deny", priority = -1 } +nursery = { level = "deny", priority = -1 } missing_const_for_fn = "deny" disallowed_types = "warn" diff --git a/crates/cli/src/apply.rs b/crates/cli/src/apply.rs index 043f747..4591ecc 100644 --- a/crates/cli/src/apply.rs +++ b/crates/cli/src/apply.rs @@ -38,8 +38,10 @@ struct NodeErrors(#[related] Vec); // returns Names and Tags fn read_apply_targets_from_stdin() -> Result<(Vec, Vec)> { let mut buf = String::new(); - let mut stdin = std::io::stdin().lock(); - stdin.read_to_string(&mut buf).into_diagnostic()?; + std::io::stdin() + .lock() + .read_to_string(&mut buf) + .into_diagnostic()?; Ok(buf .split_whitespace() @@ -107,7 +109,7 @@ pub async fn apply( cache: Arc>, ) -> Result<()> where - F: Fn(&Name, &Node) -> Goal, + F: Fn(&Name, &Node) -> Goal + Send + Sync, { let location = Arc::new(location); @@ -229,7 +231,7 @@ where return Err(NodeErrors( errors .into_iter() - .map(|(name, error)| NodeError(name.clone(), error)) + .map(|(name, error)| NodeError(name, error)) .collect(), ) .into()); diff --git a/crates/cli/src/cli.rs b/crates/cli/src/cli.rs index 223c47e..31a2516 100644 --- a/crates/cli/src/cli.rs +++ b/crates/cli/src/cli.rs @@ -85,23 +85,22 @@ pub enum ApplyTarget { impl From for ApplyTarget { fn from(value: String) -> Self { if value == "-" { - return ApplyTarget::Stdin; + return Self::Stdin; } - if let Some(stripped) = value.strip_prefix("@") { - ApplyTarget::Tag(stripped.to_string()) - } else { - ApplyTarget::Node(Name(Arc::from(value.as_str()))) - } + value.strip_prefix("@").map_or_else( + || Self::Node(Name(Arc::from(value.as_str()))), + |stripped| Self::Tag(stripped.to_string()), + ) } } impl Display for ApplyTarget { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { - ApplyTarget::Node(name) => name.fmt(f), - ApplyTarget::Tag(tag) => write!(f, "@{tag}"), - ApplyTarget::Stdin => write!(f, "#stdin"), + Self::Node(name) => name.fmt(f), + Self::Tag(tag) => write!(f, "@{tag}"), + Self::Stdin => write!(f, "#stdin"), } } } @@ -313,21 +312,17 @@ impl TryFrom for HiveGoal { fn try_from(value: Goal) -> Result { match value { - Goal::Build => Ok(HiveGoal::Build), - Goal::Push => Ok(HiveGoal::Push), - Goal::Boot => Ok(HiveGoal::SwitchToConfiguration( - SwitchToConfigurationGoal::Boot, - )), - Goal::Switch => Ok(HiveGoal::SwitchToConfiguration( + Goal::Build => Ok(Self::Build), + Goal::Push => Ok(Self::Push), + Goal::Boot => Ok(Self::SwitchToConfiguration(SwitchToConfigurationGoal::Boot)), + Goal::Switch => Ok(Self::SwitchToConfiguration( SwitchToConfigurationGoal::Switch, )), - Goal::Test => Ok(HiveGoal::SwitchToConfiguration( - SwitchToConfigurationGoal::Test, - )), - Goal::DryActivate => Ok(HiveGoal::SwitchToConfiguration( + Goal::Test => Ok(Self::SwitchToConfiguration(SwitchToConfigurationGoal::Test)), + Goal::DryActivate => Ok(Self::SwitchToConfiguration( SwitchToConfigurationGoal::DryActivate, )), - Goal::Keys => Ok(HiveGoal::Keys), + Goal::Keys => Ok(Self::Keys), } } } diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 35fa38a..c6efd23 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -170,15 +170,14 @@ fn check_nix_available() -> bool { { Ok(_) => true, Err(e) => { - if let std::io::ErrorKind::NotFound = e.kind() { - false - } else { + if e.kind() != std::io::ErrorKind::NotFound { error!( "Something weird happened checking for nix availability, {}", e ); - false } + + false } } } diff --git a/crates/cli/src/sigint.rs b/crates/cli/src/sigint.rs index a67a7fb..25a7afb 100644 --- a/crates/cli/src/sigint.rs +++ b/crates/cli/src/sigint.rs @@ -9,11 +9,9 @@ use signal_hook_tokio::Signals; use futures::stream::StreamExt; use tracing::info; -pub(crate) async fn handle_signals(mut signals: Signals, should_shutdown: Arc) { +pub async fn handle_signals(mut signals: Signals, should_shutdown: Arc) { while let Some(signal) = signals.next().await { - if let SIGINT = signal - && !should_shutdown.load(std::sync::atomic::Ordering::Relaxed) - { + if signal == SIGINT && !should_shutdown.load(std::sync::atomic::Ordering::Relaxed) { info!("Received SIGINT, attempting to shut down executor tasks."); should_shutdown.store(true, std::sync::atomic::Ordering::Relaxed); } diff --git a/crates/cli/src/tracing_setup.rs b/crates/cli/src/tracing_setup.rs index b8bcd2a..e9144fa 100644 --- a/crates/cli/src/tracing_setup.rs +++ b/crates/cli/src/tracing_setup.rs @@ -26,7 +26,7 @@ struct NonClobberingWriter; impl NonClobberingWriter { const fn new() -> Self { - NonClobberingWriter + Self } } @@ -196,6 +196,7 @@ where .unwrap(); write!(writer, "{node_name}")?; + drop(parent_ext); // write the step name if let Some(step) = ctx.event_scope().unwrap().from_root().nth(1) { diff --git a/crates/core/src/cache/mod.rs b/crates/core/src/cache/mod.rs index 8c98344..4641295 100644 --- a/crates/core/src/cache/mod.rs +++ b/crates/core/src/cache/mod.rs @@ -43,8 +43,7 @@ async fn get_cache_directory() -> Option { let cache_home = env::var("XDG_CACHE_HOME") .inspect_err(|_| debug!("XDG_CACHE_HOME not found")) .ok() - .map(PathBuf::from) - .unwrap_or(home.join(".cache")); + .map_or_else(|| home.join(".cache"), PathBuf::from); let cache_directory = cache_home.join("wire"); @@ -529,23 +528,23 @@ where // delete invalid evaluation_cache entries for path in &evaluation_paths { - let mut is_invalid = false; - - if let Ok(p) = SafeStorePath::::from_name_and_digest( + // is invalid if either the output or the flake path are not in + // the valid set + let is_invalid = if let Ok(p) = SafeStorePath::::from_name_and_digest( &path.flake_path_name, &path.flake_path_digest, ) && !valid_set.contains(&p) { - is_invalid = true; - } - - if let Ok(p) = SafeStorePath::::from_name_and_digest( + true + } else if let Ok(p) = SafeStorePath::::from_name_and_digest( &path.output_path_name, &path.output_path_digest, ) && !valid_set.contains(&p) { - is_invalid = true; - } + true + } else { + false + }; if !is_invalid { continue; diff --git a/crates/core/src/commands/builder.rs b/crates/core/src/commands/builder.rs index 87ada4e..7442fb6 100644 --- a/crates/core/src/commands/builder.rs +++ b/crates/core/src/commands/builder.rs @@ -3,7 +3,7 @@ use std::fmt; -pub(crate) struct CommandStringBuilder { +pub struct CommandStringBuilder { command: String, } diff --git a/crates/core/src/commands/common.rs b/crates/core/src/commands/common.rs index 87e2aba..0d09637 100644 --- a/crates/core/src/commands/common.rs +++ b/crates/core/src/commands/common.rs @@ -64,6 +64,8 @@ pub async fn push( ) .await?; + drop(target); + let status = child.wait_till_success().await; let help = if let Err(ref error) = status { diff --git a/crates/core/src/commands/mod.rs b/crates/core/src/commands/mod.rs index 70d06d1..7cbdee4 100644 --- a/crates/core/src/commands/mod.rs +++ b/crates/core/src/commands/mod.rs @@ -105,13 +105,13 @@ impl> CommandArguments { } } -pub(crate) async fn run_command>( +pub(crate) async fn run_command + Sync>( arguments: &CommandArguments, ) -> Result, HiveLibError> { run_command_with_env(arguments, HashMap::new()).await } -pub(crate) async fn run_command_with_env>( +pub(crate) async fn run_command_with_env + Sync>( arguments: &CommandArguments, envs: HashMap, ) -> Result, HiveLibError> { @@ -214,10 +214,11 @@ pub(crate) fn trace_nix_log_message( }, }; - let lock = build_name_map.lock(); - let build_name = lock.get(&id).cloned(); - - (msg, VerbosityLevel::Info, build_name) + ( + msg, + VerbosityLevel::Info, + build_name_map.lock().get(&id).cloned(), + ) } _ => return None, }; diff --git a/crates/core/src/commands/noninteractive.rs b/crates/core/src/commands/noninteractive.rs index 7cb1e30..a0202d2 100644 --- a/crates/core/src/commands/noninteractive.rs +++ b/crates/core/src/commands/noninteractive.rs @@ -22,7 +22,7 @@ use tokio::{ }; use tracing::{Instrument, debug, instrument, trace}; -pub(crate) struct NonInteractiveChildChip { +pub struct NonInteractiveChildChip { error_collection: Arc>>, stdout_collection: Arc>>, child: Child, @@ -32,7 +32,7 @@ pub(crate) struct NonInteractiveChildChip { } #[instrument(skip_all, name = "run", fields(elevated = %arguments.is_elevated()))] -pub(crate) async fn non_interactive_command_with_env>( +pub async fn non_interactive_command_with_env + Sync>( arguments: &CommandArguments, envs: HashMap, ) -> Result { @@ -57,11 +57,10 @@ pub(crate) async fn non_interactive_command_with_env>( let command_string = command_string.replace('\'', "'\''"); - let command_string = if let Some(escalation_command) = &arguments.privilege_escalation_command { - format!("{escalation_command} bash -c '{command_string}'") - } else { - format!("bash -c '{command_string}'") - }; + let command_string = arguments.privilege_escalation_command.as_ref().map_or_else( + || format!("bash -c '{command_string}'"), + |escalation_command| format!("{escalation_command} bash -c '{command_string}'"), + ); debug!("{command_string}"); @@ -105,7 +104,7 @@ pub(crate) async fn non_interactive_command_with_env>( joinset.spawn( handle_io( stdout_handle, - output_mode.clone(), + output_mode, stdout_collection.clone(), false, arguments.log_stdout, @@ -138,10 +137,9 @@ impl WireCommandChip for NonInteractiveChildChip { return Err(CommandError::CommandFailed { command_ran: self.original_command, logs, - code: match status.code() { - Some(code) => format!("code {code}"), - None => "no exit code".to_string(), - }, + code: status + .code() + .map_or_else(|| "no exit code".to_string(), |code| format!("code {code}")), reason: "known-status", }); } @@ -195,6 +193,7 @@ pub async fn handle_io( debug!("io_handler: goodbye!"); } +#[allow(clippy::significant_drop_tightening)] async fn create_sync_ssh_command( target: &SharedTarget, modifiers: SubCommandModifiers, diff --git a/crates/core/src/commands/pty/logbuffer.rs b/crates/core/src/commands/pty/logbuffer.rs index 4136e6e..14499bf 100644 --- a/crates/core/src/commands/pty/logbuffer.rs +++ b/crates/core/src/commands/pty/logbuffer.rs @@ -2,7 +2,7 @@ // Copyright 2024-2025 wire Contributors /// Split into its own struct to be tested nicer -pub(crate) struct LogBuffer { +pub struct LogBuffer { buffer: Vec, } diff --git a/crates/core/src/commands/pty/mod.rs b/crates/core/src/commands/pty/mod.rs index feb3387..f0a31af 100644 --- a/crates/core/src/commands/pty/mod.rs +++ b/crates/core/src/commands/pty/mod.rs @@ -44,7 +44,7 @@ const THREAD_QUIT_SIGNAL: &[u8; 1] = b"q"; type Child = Box; -pub(crate) struct InteractiveChildChip { +pub struct InteractiveChildChip { child: Child, cancel_stdin_pipe_w: OwnedFd, @@ -101,7 +101,7 @@ fn create_starting_segment(start_needle: &Arc>) -> String { } #[instrument(skip_all, name = "run-int", fields(elevated = %arguments.is_elevated(), mode = ?arguments.output_mode))] -pub(crate) async fn interactive_command_with_env>( +pub async fn interactive_command_with_env + Sync>( arguments: &CommandArguments, envs: std::collections::HashMap, ) -> Result { @@ -221,7 +221,8 @@ pub(crate) async fn interactive_command_with_env>( }) } -async fn print_authenticate_warning>( +#[allow(clippy::significant_drop_tightening)] +async fn print_authenticate_warning + Sync>( arguments: &CommandArguments, ) -> Result<(), HiveLibError> { let Some(ref escalation_command) = arguments.privilege_escalation_command else { @@ -297,7 +298,7 @@ fn setup_master(pty_pair: &PtyPair) -> Result<(), HiveLibError> { Ok(()) } -async fn build_command>( +async fn build_command + Sync>( arguments: &CommandArguments, command_string: &str, ) -> Result { @@ -353,7 +354,7 @@ impl WireCommandChip for InteractiveChildChip { let _ = posix_write(&self.cancel_stdin_pipe_w, THREAD_QUIT_SIGNAL); - if let Status::Done { success: true } = *status { + if matches!(*status, Status::Done { success: true }) { let logs = self .stdout_collection .lock() @@ -408,7 +409,7 @@ impl StdinTermiosAttrGuard { termios.local_flags &= !(LocalFlags::ECHO | LocalFlags::ICANON); tcsetattr(stdin_fd, SetArg::TCSANOW, &termios).map_err(CommandError::TermAttrs)?; - Ok(StdinTermiosAttrGuard(original_termios)) + Ok(Self(original_termios)) } } @@ -421,6 +422,7 @@ impl Drop for StdinTermiosAttrGuard { } } +#[allow(clippy::significant_drop_tightening)] async fn create_int_ssh_command( target: &SharedTarget, modifiers: SubCommandModifiers, diff --git a/crates/core/src/commands/pty/output.rs b/crates/core/src/commands/pty/output.rs index 8fb135c..32122da 100644 --- a/crates/core/src/commands/pty/output.rs +++ b/crates/core/src/commands/pty/output.rs @@ -207,8 +207,10 @@ fn handle_normal_data( output_mode.trace_slice(stripped, build_name_map, print_build_logs); } - let mut queue = stdout_collection.lock().unwrap(); - queue.push_front(String::from_utf8_lossy(stripped).to_string()); + stdout_collection + .lock() + .unwrap() + .push_front(String::from_utf8_lossy(stripped).to_string()); return; } diff --git a/crates/core/src/errors.rs b/crates/core/src/errors.rs index 3743cbf..64cfb22 100644 --- a/crates/core/src/errors.rs +++ b/crates/core/src/errors.rs @@ -308,9 +308,7 @@ pub enum HiveLibError { #[error("{arg_name} environment variable not set! \n wire was not built with the ability to deploy keys to this platform. \n Please create an issue: https://github.com/forallsys/wire/issues/new?template=bug_report.md")] - KeyArchitectureNotFound { - arg_name: String - }, + KeyArchitectureNotFound { arg_name: String }, #[diagnostic(code(wire::Encoding))] #[error("error encoding length delimited data")] @@ -323,6 +321,6 @@ pub enum HiveLibError { impl From for HiveLibError { fn from(e: StorePathError) -> Self { - HiveLibError::StorePath(e) + Self::StorePath(e) } } diff --git a/crates/core/src/hive/mod.rs b/crates/core/src/hive/mod.rs index 6979604..b50aedd 100644 --- a/crates/core/src/hive/mod.rs +++ b/crates/core/src/hive/mod.rs @@ -28,7 +28,7 @@ pub mod node; pub mod plan; pub mod steps; -#[derive(Serialize, Deserialize, Debug, PartialEq)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] #[serde(deny_unknown_fields)] pub struct Hive { pub nodes: HashMap, @@ -55,7 +55,7 @@ impl Hive { location: &HiveLocation, cache: Arc>, modifiers: SubCommandModifiers, - ) -> Result { + ) -> Result { info!("evaluating hive {location:?}"); if let Some(ref cache) = *cache @@ -67,7 +67,7 @@ impl Hive { let output = evaluate_hive_attribute(location, &EvalGoal::Inspect, modifiers).await?; - let hive: Hive = serde_json::from_str(&output).map_err(|err| { + let hive: Self = serde_json::from_str(&output).map_err(|err| { HiveLibError::HiveInitialisationError(HiveInitialisationError::ParseEvaluateError(err)) })?; @@ -157,21 +157,20 @@ impl Display for Hive { .nodes .values() .flat_map(|node| node.keys.iter()) - .collect::>(); + .count(); let distinct_keys = self .nodes .values() .flat_map(|node| node.keys.iter()) .unique() - .collect::>() - .len(); + .count(); write!(f, "{}", "Summary:".bold())?; writeln!( f, " {} total node(s), totalling {} keys ({distinct_keys} distinct).", self.nodes.len(), - total_keys.len() + total_keys )?; writeln!( f, @@ -200,10 +199,7 @@ pub enum HiveLocation { } impl HiveLocation { - async fn get_flake( - uri: String, - modifiers: SubCommandModifiers, - ) -> Result { + async fn get_flake(uri: String, modifiers: SubCommandModifiers) -> Result { let mut command_string = CommandStringBuilder::nix(); command_string.args(&[ "flake", @@ -238,7 +234,7 @@ impl HiveLocation { debug!(prefetch = ?prefetch); - Ok(HiveLocation::Flake { uri, prefetch }) + Ok(Self::Flake { uri, prefetch }) } } diff --git a/crates/core/src/hive/node.rs b/crates/core/src/hive/node.rs index b917c7f..5f95bd4 100644 --- a/crates/core/src/hive/node.rs +++ b/crates/core/src/hive/node.rs @@ -81,16 +81,13 @@ impl Target { "-p".to_string(), self.port.to_string(), ]; - let mut options = vec![ - format!( - "StrictHostKeyChecking={}", - match modifiers.ssh_accept_host { - StrictHostKeyChecking::AcceptNew => "accept-new", - StrictHostKeyChecking::No => "no", - } - ) - .to_string(), - ]; + let mut options = vec![format!( + "StrictHostKeyChecking={}", + match modifiers.ssh_accept_host { + StrictHostKeyChecking::AcceptNew => "accept-new", + StrictHostKeyChecking::No => "no", + } + )]; options.extend(["BatchMode=yes".to_string()]); diff --git a/crates/core/src/hive/plan.rs b/crates/core/src/hive/plan.rs index cf13fae..41d5b5e 100644 --- a/crates/core/src/hive/plan.rs +++ b/crates/core/src/hive/plan.rs @@ -196,7 +196,7 @@ fn apply_plan( target: if *should_apply_locally { None } else { - Some(target.clone()) + Some(target) }, privilege_escalation_command: node.privilege_escalation_command.clone(), })); diff --git a/crates/core/src/hive/steps/activate.rs b/crates/core/src/hive/steps/activate.rs index 3671b7e..fd8b42c 100644 --- a/crates/core/src/hive/steps/activate.rs +++ b/crates/core/src/hive/steps/activate.rs @@ -27,6 +27,7 @@ impl Display for SwitchToConfiguration { } } +#[allow(clippy::significant_drop_tightening)] async fn wait_for_ping(target: &SharedTarget, ctx: &Context) -> Result<(), HiveLibError> { let target = target.0.read().await; let host = target.get_preferred_host()?; diff --git a/crates/core/src/hive/steps/evaluate.rs b/crates/core/src/hive/steps/evaluate.rs index 7b22798..ac138d6 100644 --- a/crates/core/src/hive/steps/evaluate.rs +++ b/crates/core/src/hive/steps/evaluate.rs @@ -10,7 +10,7 @@ use crate::{ hive::node::{Context, ExecuteStep}, }; -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub struct Evaluate { /// evaluation that was previously built & cached pub cached_evaluation: Option>, diff --git a/crates/core/src/hive/steps/keys.rs b/crates/core/src/hive/steps/keys.rs index ce1155c..a0c44eb 100644 --- a/crates/core/src/hive/steps/keys.rs +++ b/crates/core/src/hive/steps/keys.rs @@ -159,7 +159,7 @@ async fn process_key(key: &Key) -> Result<(wire_key_agent::keys::KeySpec, Vec Self { - SubCommandModifiers { + Self { show_trace: false, non_interactive: !std::io::stdin().is_terminal(), ssh_accept_host: StrictHostKeyChecking::default(), @@ -124,8 +124,8 @@ pub async fn open_remote_client( should_quit: Arc, ) -> Result<(NixClient, String), HiveLibError> where - D: Deref + std::fmt::Debug, - T: Fn(LogMessage, &Arc>>>, bool) -> Option, + D: Deref + std::fmt::Debug + Sync, + T: Fn(LogMessage, &Arc>>>, bool) -> Option + Send, { let mut command = Command::new("ssh") .args(target.create_ssh_args(modifiers, true)?) diff --git a/crates/core/src/status.rs b/crates/core/src/status.rs index efb460f..7d2aa11 100644 --- a/crates/core/src/status.rs +++ b/crates/core/src/status.rs @@ -194,6 +194,7 @@ pub async fn status_tick_worker(mut rx: UnboundedReceiver, show_progr }, UiMessage::Release => { taken_over = false; + #[allow(clippy::iter_with_drain)] for buf in log_queue.drain(..) { let _ = std::io::Write::write_all(&mut stderr, &buf); } @@ -207,7 +208,8 @@ pub async fn status_tick_worker(mut rx: UnboundedReceiver, show_progr log_queue.push_back(line); } else { status.clear(&mut stderr); - for buf in log_queue.drain(..) { + #[allow(clippy::iter_with_drain)] + for buf in log_queue.drain(..) { let _ = std::io::Write::write_all(&mut stderr, &buf); } let _ = std::io::Write::write_all(&mut stderr, &line); diff --git a/crates/nix_client/src/lib.rs b/crates/nix_client/src/lib.rs index 17b0127..0f6a026 100644 --- a/crates/nix_client/src/lib.rs +++ b/crates/nix_client/src/lib.rs @@ -145,7 +145,7 @@ pub struct NixClient { impl NixClient where - T: Fn(LogMessage, &Arc>>>, bool) -> Option, + T: Fn(LogMessage, &Arc>>>, bool) -> Option + Send, { #[instrument(skip(trace_callback))] pub async fn open_local( @@ -173,7 +173,8 @@ where impl NixClient where - T: Fn(LogMessage, &Arc>>>, bool) -> Option, + T: Fn(LogMessage, &Arc>>>, bool) -> Option + Send, + R: Send, { #[instrument(skip_all)] pub async fn handshake( @@ -182,7 +183,7 @@ where trace_callback: T, should_quit: Arc, print_build_logs: bool, - ) -> Result, NixDaemonClientError> + ) -> Result where R: AsyncReadExt + std::fmt::Debug + Unpin + Send, W: AsyncWriteExt + std::fmt::Debug + Unpin + Send, @@ -285,7 +286,7 @@ where async fn write_value(&mut self, value: &V) -> Result<(), NixDaemonClientError> where W: AsyncWriteExt + std::fmt::Debug + Unpin + Send, - V: NixSerialize + std::fmt::Debug + Send, + V: NixSerialize + std::fmt::Debug + Send + Sync, { self.shutdown_guard()?; @@ -995,7 +996,7 @@ impl NixDeserialize for QueryMissingResult { && let Some(download_size) = download_size && let Some(nar_size) = nar_size { - Ok(Some(QueryMissingResult { + Ok(Some(Self { will_build: will_build.into_iter().collect(), will_substitute: will_substitute.into_iter().collect(), _unknown: unknown.into_iter().collect(), diff --git a/crates/nix_client/src/store_path.rs b/crates/nix_client/src/store_path.rs index 0347a72..30c78a9 100644 --- a/crates/nix_client/src/store_path.rs +++ b/crates/nix_client/src/store_path.rs @@ -13,11 +13,12 @@ pub struct StorePathError { error: nix_compat::store_path::Error, } +/// A restricted `StorePath`. +/// /// This type exists to restrict `StorePath` usage to only methods that deal with /// absolute paths. By default, the `StorePath` type implements Display that /// does not include `/nix/store/` can introduce many hard to catch bugs. /// -/// /// If /// is ever closed, this can be dropped from the codebase. #[derive(Clone)] @@ -26,7 +27,7 @@ pub struct SafeStorePath(pub nix_compat::store_path::StorePath); #[allow(clippy::disallowed_types)] impl SafeStorePath { - pub fn from_absolute_path<'a>(s: &'a [u8]) -> Result, StorePathError> + pub fn from_absolute_path<'a>(s: &'a [u8]) -> Result where S: From<&'a str> + AsRef, { @@ -90,9 +91,9 @@ where where D: serde::Deserializer<'de>, { - Ok(SafeStorePath( - nix_compat::store_path::StorePath::deserialize(deserializer)?, - )) + Ok(Self(nix_compat::store_path::StorePath::deserialize( + deserializer, + )?)) } } @@ -145,24 +146,23 @@ impl nix_compat::wire::de::NixDeserialize for SafeStorePath { where R: ?Sized + nix_compat::wire::de::NixRead + Send, { - if let Some(store_path) = reader.try_read_value().await? { - Ok(Some(SafeStorePath(store_path))) - } else { - Ok(None) - } + reader + .try_read_value() + .await? + .map_or_else(|| Ok(None), |store_path| Ok(Some(Self(store_path)))) } } #[allow(clippy::disallowed_types)] impl From> for SafeStorePath { fn from(value: nix_compat::store_path::StorePath) -> Self { - SafeStorePath(value) + Self(value) } } #[allow(clippy::disallowed_types)] impl From> for nix_compat::store_path::StorePath { - fn from(value: SafeStorePath) -> nix_compat::store_path::StorePath { + fn from(value: SafeStorePath) -> Self { value.into_inner() } }