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