Skip to main content

dry4rust/cli/
cli_overrides.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::PathBuf;
7
8use crate::config::Config;
9use crate::error::Result;
10use crate::threshold::Threshold;
11
12/// Optional CLI overrides applied on top of file-based config.
13#[derive(Debug, Clone, Default)]
14pub struct CliOverrides {
15    pub min_nodes: Option<usize>,
16    pub min_lines: Option<usize>,
17    pub threshold: Option<f64>,
18    pub exclude: Vec<String>,
19    pub exclude_tests: Option<bool>,
20    pub sub_function: Option<bool>,
21    pub min_sub_nodes: Option<usize>,
22    pub baseline: Option<PathBuf>,
23}
24
25impl CliOverrides {
26    /// Apply these overrides to a loaded `Config`, returning the result.
27    ///
28    /// An absent override leaves the loaded value alone; `exclude` is the one
29    /// exception, and is *appended* to the config-file excludes rather than
30    /// replacing them.
31    ///
32    /// # Errors
33    ///
34    /// Returns [`crate::error::Error::InvalidConfig`] when `--threshold` is
35    /// outside the range a similarity score can occupy.
36    pub fn apply_to(&self, config: Config) -> Result<Config> {
37        let mut config = config;
38        if let Some(min_nodes) = self.min_nodes {
39            config.min_nodes = min_nodes;
40        }
41        if let Some(min_lines) = self.min_lines {
42            config.min_lines = min_lines;
43        }
44        if let Some(threshold) = self.threshold {
45            config.similarity_threshold = Threshold::fraction("--threshold", threshold)?;
46        }
47        if !self.exclude.is_empty() {
48            config.exclude.extend(self.exclude.iter().cloned());
49        }
50        if let Some(v) = self.exclude_tests {
51            config.exclude_tests = v;
52        }
53        if let Some(v) = self.sub_function {
54            config.sub_function = v;
55        }
56        if let Some(min_sub_nodes) = self.min_sub_nodes {
57            config.min_sub_nodes = min_sub_nodes;
58        }
59        if let Some(ref baseline) = self.baseline {
60            config.baseline = Some(baseline.clone());
61        }
62        Ok(config)
63    }
64}