Skip to main content

dry4rust/cli/
ignore_command.rs

1// Copyright (c) 2026 Matjaz Domen Pecan
2// Copyright 2026 Umberto Gotti <umberto.gotti@umbertogotti.dev>
3// Licensed under the MIT License
4// SPDX-License-Identifier: MIT
5
6use std::path::Path;
7
8use crate::cli::cli_error::CliError;
9use crate::cli::cli_error::CliResult;
10use crate::cli::command_outcome::CommandOutcome;
11use crate::fingerprint::Fingerprint;
12use crate::suppression::ignore_file::IgnoreFile;
13
14/// `ignore`: record one fingerprint as a duplicate that is meant to be there.
15pub struct IgnoreCommand<'a> {
16    root: &'a Path,
17    fingerprint: &'a str,
18    reason: Option<&'a str>,
19}
20
21impl<'a> IgnoreCommand<'a> {
22    #[must_use]
23    pub const fn new(root: &'a Path, fingerprint: &'a str, reason: Option<&'a str>) -> Self {
24        Self {
25            root,
26            fingerprint,
27            reason,
28        }
29    }
30
31    /// Add the fingerprint to the ignore file.
32    ///
33    /// # Errors
34    ///
35    /// Returns [`CliError::InvalidFingerprint`] if the string is not a
36    /// fingerprint this tool could have produced, and [`CliError::Io`] if the
37    /// ignore file cannot be written.
38    pub fn run(&self) -> CliResult<CommandOutcome> {
39        let fingerprint = Fingerprint::from_hex(self.fingerprint)
40            .ok_or_else(|| CliError::InvalidFingerprint(self.fingerprint.to_owned()))?;
41        IgnoreFile::load(self.root)
42            .with_ignored(&fingerprint, self.reason.map(ToOwned::to_owned), vec![])
43            .save(self.root)?;
44        Ok(CommandOutcome::succeeded(format!(
45            "Added {} to ignore list.\n",
46            self.fingerprint
47        )))
48    }
49}