pocket_cli/models/
mod.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use uuid::Uuid;
4use anyhow::Result;
5
6/// Represents an entry in the pocket storage
7#[derive(Debug, Serialize, Deserialize, Clone)]
8pub struct Entry {
9    /// Unique identifier for the entry
10    pub id: String,
11    
12    /// Title or first line of the entry
13    pub title: String,
14    
15    /// When the entry was created
16    pub created_at: DateTime<Utc>,
17    
18    /// When the entry was last updated
19    pub updated_at: DateTime<Utc>,
20    
21    /// Source of the entry (file path, etc.)
22    pub source: Option<String>,
23    
24    /// Tags associated with the entry
25    pub tags: Vec<String>,
26    
27    /// Type of content (code, text, etc.)
28    pub content_type: ContentType,
29}
30
31/// Represents the type of content in an entry
32#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
33pub enum ContentType {
34    Code,
35    Text,
36    Script,
37    Other(String),
38}
39
40/// Represents a backpack for organizing entries
41#[derive(Debug, Serialize, Deserialize, Clone)]
42pub struct Backpack {
43    /// Name of the backpack
44    pub name: String,
45    
46    /// Description of the backpack
47    pub description: Option<String>,
48    
49    /// When the backpack was created
50    pub created_at: DateTime<Utc>,
51}
52
53/// Represents a saved workflow
54#[derive(Debug, Serialize, Deserialize, Clone)]
55pub struct Workflow {
56    /// Name of the workflow
57    pub name: String,
58    
59    /// Commands in the workflow
60    pub commands: Vec<WorkflowCommand>,
61    
62    /// When the workflow was created
63    pub created_at: DateTime<Utc>,
64}
65
66/// Represents a command in a workflow
67#[derive(Debug, Serialize, Deserialize, Clone)]
68pub struct WorkflowCommand {
69    /// The command to execute
70    pub command: String,
71    
72    /// Arguments for the command
73    pub args: Vec<String>,
74}
75
76impl Entry {
77    /// Create a new entry
78    pub fn new(title: String, content_type: ContentType, source: Option<String>, tags: Vec<String>) -> Self {
79        let now = Utc::now();
80        Self {
81            id: Uuid::new_v4().to_string(),
82            title,
83            created_at: now,
84            updated_at: now,
85            source,
86            tags,
87            content_type,
88        }
89    }
90}
91
92impl Backpack {
93    /// Create a new backpack
94    pub fn new(name: String, description: Option<String>) -> Self {
95        Self {
96            name,
97            description,
98            created_at: Utc::now(),
99        }
100    }
101}
102
103impl Workflow {
104    /// Create a new workflow
105    pub fn new(name: String, commands: Vec<WorkflowCommand>) -> Self {
106        Self {
107            name,
108            commands,
109            created_at: Utc::now(),
110        }
111    }
112}
113
114impl WorkflowCommand {
115    /// Parse a command string into a WorkflowCommand
116    pub fn parse(command_str: &str) -> Result<Self> {
117        let command_str = command_str.trim();
118        if command_str.is_empty() {
119            return Err(anyhow::anyhow!("Empty command"));
120        }
121        
122        let parts: Vec<&str> = command_str.split_whitespace().collect();
123        
124        Ok(Self {
125            command: parts[0].to_string(),
126            args: parts[1..].iter().map(|s| s.to_string()).collect(),
127        })
128    }
129}
130
131/// Configuration for the pocket application
132#[derive(Debug, Serialize, Deserialize)]
133pub struct Config {
134    /// User preferences
135    pub user: UserConfig,
136    
137    /// Display settings
138    pub display: DisplayConfig,
139    
140    /// Search settings
141    pub search: SearchConfig,
142    
143    /// Extension settings
144    pub extensions: ExtensionConfig,
145}
146
147/// User configuration
148#[derive(Debug, Serialize, Deserialize)]
149pub struct UserConfig {
150    /// Default editor for -e flag
151    pub editor: String,
152    
153    /// Default backpack for new entries
154    pub default_backpack: String,
155}
156
157/// Display configuration
158#[derive(Debug, Serialize, Deserialize)]
159pub struct DisplayConfig {
160    /// Enable colorful output
161    pub color: bool,
162    
163    /// Tree style (unicode, ascii, or minimal)
164    pub tree_style: TreeStyle,
165}
166
167/// Search configuration
168#[derive(Debug, Serialize, Deserialize)]
169pub struct SearchConfig {
170    /// Search algorithm (semantic or literal)
171    pub algorithm: SearchAlgorithm,
172    
173    /// Maximum number of search results
174    pub max_results: usize,
175}
176
177/// Extension configuration
178#[derive(Debug, Serialize, Deserialize)]
179pub struct ExtensionConfig {
180    /// Auto-reload extensions when they change
181    pub auto_reload: bool,
182}
183
184/// Tree style for display
185#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
186pub enum TreeStyle {
187    Unicode,
188    Ascii,
189    Minimal,
190}
191
192/// Search algorithm
193#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
194pub enum SearchAlgorithm {
195    Semantic,
196    Literal,
197}
198
199impl Default for Config {
200    fn default() -> Self {
201        Self {
202            user: UserConfig {
203                editor: "vim".to_string(),
204                default_backpack: "general".to_string(),
205            },
206            display: DisplayConfig {
207                color: true,
208                tree_style: TreeStyle::Unicode,
209            },
210            search: SearchConfig {
211                algorithm: SearchAlgorithm::Semantic,
212                max_results: 10,
213            },
214            extensions: ExtensionConfig {
215                auto_reload: true,
216            },
217        }
218    }
219}