agentic_navigation_guide/
types.rs

1//! Core data types for the agentic navigation guide
2
3use serde::{Deserialize, Serialize};
4use std::path::PathBuf;
5
6/// Represents a filesystem item type
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
8pub enum FilesystemItem {
9    /// A regular file
10    File {
11        /// The file path relative to its parent
12        path: String,
13        /// Optional comment describing the file
14        comment: Option<String>,
15    },
16    /// A directory
17    Directory {
18        /// The directory path relative to its parent
19        path: String,
20        /// Optional comment describing the directory
21        comment: Option<String>,
22        /// Child items within this directory
23        children: Vec<NavigationGuideLine>,
24    },
25    /// A symbolic link
26    Symlink {
27        /// The symlink path relative to its parent
28        path: String,
29        /// Optional comment describing the symlink
30        comment: Option<String>,
31        /// The target of the symlink (if specified in the guide)
32        target: Option<String>,
33    },
34    /// A placeholder representing one or more unlisted items
35    Placeholder {
36        /// Optional comment describing what the placeholder represents
37        comment: Option<String>,
38    },
39}
40
41/// Represents a single line in the navigation guide
42#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
43pub struct NavigationGuideLine {
44    /// The line number in the original document
45    pub line_number: usize,
46    /// The indentation level (number of spaces / indent_size)
47    pub indent_level: usize,
48    /// The filesystem item this line represents
49    pub item: FilesystemItem,
50}
51
52impl NavigationGuideLine {
53    /// Get the path of the filesystem item
54    pub fn path(&self) -> &str {
55        match &self.item {
56            FilesystemItem::File { path, .. }
57            | FilesystemItem::Directory { path, .. }
58            | FilesystemItem::Symlink { path, .. } => path,
59            FilesystemItem::Placeholder { .. } => "...",
60        }
61    }
62
63    /// Get the comment of the filesystem item
64    pub fn comment(&self) -> Option<&str> {
65        match &self.item {
66            FilesystemItem::File { comment, .. }
67            | FilesystemItem::Directory { comment, .. }
68            | FilesystemItem::Symlink { comment, .. }
69            | FilesystemItem::Placeholder { comment, .. } => comment.as_deref(),
70        }
71    }
72
73    /// Check if this item is a directory
74    pub fn is_directory(&self) -> bool {
75        matches!(self.item, FilesystemItem::Directory { .. })
76    }
77
78    /// Check if this item is a placeholder
79    pub fn is_placeholder(&self) -> bool {
80        matches!(self.item, FilesystemItem::Placeholder { .. })
81    }
82
83    /// Get the children of a directory item
84    pub fn children(&self) -> Option<&[NavigationGuideLine]> {
85        match &self.item {
86            FilesystemItem::Directory { children, .. } => Some(children),
87            _ => None,
88        }
89    }
90}
91
92/// Represents a complete navigation guide
93#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
94pub struct NavigationGuide {
95    /// The root items in the guide
96    pub items: Vec<NavigationGuideLine>,
97    /// The original prologue content (before the guide block)
98    pub prologue: Option<String>,
99    /// The original epilogue content (after the guide block)
100    pub epilogue: Option<String>,
101    /// Whether this guide should be ignored during verification
102    pub ignore: bool,
103}
104
105impl NavigationGuide {
106    /// Create a new empty navigation guide
107    pub fn new() -> Self {
108        Self {
109            items: Vec::new(),
110            prologue: None,
111            epilogue: None,
112            ignore: false,
113        }
114    }
115
116    /// Get the full path for an item by traversing up the hierarchy
117    pub fn get_full_path(&self, item: &NavigationGuideLine) -> PathBuf {
118        // This is a simplified version - in practice we'd need to traverse
119        // the hierarchy to build the full path
120        PathBuf::from(item.path())
121    }
122}
123
124impl Default for NavigationGuide {
125    fn default() -> Self {
126        Self::new()
127    }
128}
129
130/// Execution mode for the CLI tool
131#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
132pub enum ExecutionMode {
133    /// Default execution mode
134    Default,
135    /// Running as a post-tool-use hook
136    PostToolUse,
137    /// Running as a pre-commit hook
138    PreCommitHook,
139    /// Running as a GitHub Actions check
140    GitHubActions,
141}
142
143impl Default for ExecutionMode {
144    fn default() -> Self {
145        Self::Default
146    }
147}
148
149/// Log level for output verbosity
150#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
151pub enum LogLevel {
152    /// Minimal output
153    Quiet,
154    /// Normal output
155    Default,
156    /// Verbose output
157    Verbose,
158}
159
160impl Default for LogLevel {
161    fn default() -> Self {
162        Self::Default
163    }
164}
165
166/// Configuration for the CLI tool
167#[derive(Debug, Clone, Serialize, Deserialize, Default)]
168pub struct Config {
169    /// The execution mode
170    pub execution_mode: ExecutionMode,
171    /// The log level
172    pub log_level: LogLevel,
173    /// The root directory for operations
174    pub root_path: Option<PathBuf>,
175    /// The path to the navigation guide file
176    pub guide_path: Option<PathBuf>,
177    /// The original guide path as provided by the user (for error messages)
178    pub original_guide_path: Option<String>,
179    /// The original root path as provided by the user (for error messages)
180    pub original_root_path: Option<String>,
181}