intelli_shell/model/
completion.rs

1use std::fmt;
2
3use chrono::{DateTime, Utc};
4use uuid::Uuid;
5
6use crate::utils::{flatten_str, flatten_variable_name};
7
8/// Type to represent a variable completion
9#[derive(Clone, PartialEq, Eq)]
10#[cfg_attr(test, derive(Debug))]
11pub struct VariableCompletion {
12    /// The unique identifier for the completion
13    pub id: Uuid,
14    /// Category of the completion (`user`, `ai`, `tldr`, `import`, `workspace`)
15    pub source: String,
16    /// The root command (i.e., the first word)
17    pub root_cmd: String,
18    /// The flattened root command
19    pub flat_root_cmd: String,
20    /// The variable name
21    pub variable: String,
22    /// The flattened variable name
23    pub flat_variable: String,
24    /// The command to be executed to retrieve the suggestions
25    pub suggestions_provider: String,
26    /// The date and time when the completion was created
27    pub created_at: DateTime<Utc>,
28    /// The date and time when the completion was last updated
29    pub updated_at: Option<DateTime<Utc>>,
30}
31
32impl VariableCompletion {
33    /// Creates a new dynamic variable completion
34    pub fn new(
35        source: impl Into<String>,
36        root_cmd: impl AsRef<str>,
37        variable_name: impl AsRef<str>,
38        suggestions_provider: impl Into<String>,
39    ) -> Self {
40        let root_cmd = root_cmd.as_ref().trim().to_string();
41        let variable = variable_name.as_ref().trim().to_string();
42        Self {
43            id: Uuid::now_v7(),
44            source: source.into(),
45            flat_root_cmd: flatten_str(&root_cmd),
46            root_cmd,
47            flat_variable: flatten_variable_name(&variable),
48            variable,
49            suggestions_provider: suggestions_provider.into(),
50            created_at: Utc::now(),
51            updated_at: None,
52        }
53    }
54
55    /// Sets the root command of the variable completion
56    pub fn with_root_cmd(mut self, root_cmd: impl AsRef<str>) -> Self {
57        self.root_cmd = root_cmd.as_ref().trim().to_string();
58        self.flat_root_cmd = flatten_str(&self.root_cmd);
59        self
60    }
61
62    /// Sets the variable name of the variable completion
63    pub fn with_variable(mut self, variable_name: impl AsRef<str>) -> Self {
64        self.variable = variable_name.as_ref().trim().to_string();
65        self.flat_variable = flatten_variable_name(&self.variable);
66        self
67    }
68
69    /// Sets the suggestions command of the variable completion
70    pub fn with_suggestions_provider(mut self, suggestions_provider: impl Into<String>) -> Self {
71        self.suggestions_provider = suggestions_provider.into();
72        self
73    }
74
75    /// Returns `true` if this is a global variable completion (without root command)
76    pub fn is_global(&self) -> bool {
77        self.flat_root_cmd.is_empty()
78    }
79}
80
81impl fmt::Display for VariableCompletion {
82    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83        if self.is_global() {
84            write!(f, "$ {}: {}", self.variable, self.suggestions_provider)
85        } else {
86            write!(
87                f,
88                "$ ({}) {}: {}",
89                self.root_cmd, self.variable, self.suggestions_provider
90            )
91        }
92    }
93}