Skip to main content

binocular/runtime/
config.rs

1use crate::cli::args::{Args, OutputFormat};
2use crate::cli::Cli;
3use crate::search::sources::git::{resolve_history_scope, resolve_repo_scope, GitSearchMode};
4use crate::search::types::SearchConfig;
5use std::path::PathBuf;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct RunConfig {
9    pub headless: bool,
10    pub output_format: OutputFormat,
11    pub output_file: Option<PathBuf>,
12    pub stdin: bool,
13    pub log: bool,
14    pub log_files: Vec<PathBuf>,
15    pub diff: Option<[PathBuf; 2]>,
16    pub preview_command: Option<String>,
17    pub preview_delimiter: String,
18    pub split: Option<String>,
19}
20
21impl RunConfig {
22    pub fn from_args(args: &Args) -> Self {
23        Self {
24            headless: args.headless,
25            output_format: args.output_format,
26            output_file: args.output_file.clone(),
27            stdin: args.stdin,
28            log: args.log,
29            log_files: args.log_files.clone(),
30            diff: args.diff.as_ref().and_then(|paths| match paths.as_slice() {
31                [left, right] => Some([left.clone(), right.clone()]),
32                _ => None,
33            }),
34            preview_command: args.preview.clone(),
35            preview_delimiter: args.delimiter.clone(),
36            split: args.split.clone(),
37        }
38    }
39
40    pub fn has_preview_command(&self) -> bool {
41        self.preview_command.is_some()
42    }
43
44    pub fn with_stdin(&self, stdin: bool) -> Self {
45        let mut config = self.clone();
46        config.stdin = stdin;
47        config
48    }
49}
50
51#[derive(Debug, Clone, PartialEq, Eq)]
52pub struct ResolvedCli {
53    pub run: RunConfig,
54    pub search: SearchConfig,
55}
56
57impl ResolvedCli {
58    pub fn from_cli(cli: Cli, stdin_is_piped: bool) -> anyhow::Result<Self> {
59        let args = cli.into_args();
60        let run = RunConfig::from_args(&args).with_stdin(stdin_is_piped);
61
62        let git_search_scope = if let Some(path) = args.git_history.as_deref() {
63            Some(resolve_history_scope(path)?)
64        } else if args.git_branches {
65            Some(resolve_repo_scope(
66                args.location.first().map(|p| p.as_path()),
67                GitSearchMode::Branches,
68            )?)
69        } else if args.git_commits {
70            Some(resolve_repo_scope(
71                args.location.first().map(|p| p.as_path()),
72                GitSearchMode::Commits,
73            )?)
74        } else {
75            None
76        };
77
78        let search = SearchConfig::from_args(&args).with_git_search_scope(git_search_scope);
79
80        Ok(Self { run, search })
81    }
82}