📝 docs(cli): add comprehensive documentation for labels and messages modules

- Add extensive module-level documentation for labels_cli with usage examples
- Document complete messages_cli module with Gmail query syntax guide
- Add comprehensive struct and method documentation with safety considerations
- Include detailed parameter explanations and error handling guidance
- Document action types with safety levels and reversibility information
- Add practical usage patterns and safety recommendations
- Include extensive examples of Gmail query syntax and filtering options
This commit is contained in:
Jeremiah Russell
2025-10-20 15:33:03 +01:00
committed by Jeremiah Russell
parent a35b5f9248
commit 3a2f2ad31b
2 changed files with 439 additions and 6 deletions

View File

@@ -1,10 +1,123 @@
//! # Gmail Labels CLI Module
//!
//! This module provides command-line interface functionality for inspecting and displaying
//! Gmail labels. It enables users to list all available labels in their Gmail account
//! along with their internal Gmail IDs and display names.
//!
//! ## Purpose
//!
//! The labels command is essential for:
//! - Understanding the structure of Gmail labels in an account
//! - Finding correct label names for use in message queries
//! - Inspecting label IDs for advanced Gmail API usage
//! - Verifying label availability before creating rules
//!
//! ## Usage
//!
//! ```bash
//! cull-gmail labels
//! ```
//!
//! ## Output Format
//!
//! The command displays labels in a human-readable format showing:
//! - **Label Name**: User-visible label name
//! - **Label ID**: Internal Gmail identifier
//!
//! Example output:
//! ```text
//! INBOX: INBOX
//! IMPORTANT: IMPORTANT
//! promotions: Label_1234567890
//! newsletters: Label_0987654321
//! ```
//!
//! ## Integration
//!
//! This module integrates with:
//! - **GmailClient**: For Gmail API communication and authentication
//! - **Main CLI**: As a subcommand in the primary CLI application
//! - **Error handling**: Using the unified crate error types
use clap::Parser; use clap::Parser;
use cull_gmail::{Error, GmailClient}; use cull_gmail::{Error, GmailClient};
/// Command-line interface for Gmail label inspection and display.
///
/// This structure represents the `labels` subcommand, which provides functionality
/// to list and inspect all Gmail labels available in the user's account. The command
/// requires no additional arguments and displays comprehensive label information.
///
/// # Features
///
/// - **Complete label listing**: Shows all labels including system and user-created labels
/// - **ID mapping**: Displays both human-readable names and internal Gmail IDs
/// - **Simple usage**: No configuration or arguments required
/// - **Authentication handling**: Automatic OAuth2 authentication through GmailClient
///
/// # Usage Context
///
/// This command is typically used:
/// 1. **Before creating queries**: To understand available labels for message filtering
/// 2. **Before configuring rules**: To verify target labels exist
/// 3. **For debugging**: To inspect label structure and IDs
/// 4. **For exploration**: To understand Gmail organization structure
///
/// # Examples
///
/// ```rust,no_run
/// use cull_gmail::cli::labels_cli::LabelsCli;
/// use cull_gmail::GmailClient;
///
/// # async fn example(client: GmailClient) -> Result<(), cull_gmail::Error> {
/// let labels_cli = LabelsCli {};
/// labels_cli.run(client).await?;
/// # Ok(())
/// # }
/// ```
#[derive(Debug, Parser)] #[derive(Debug, Parser)]
pub struct LabelsCli {} pub struct LabelsCli {}
impl LabelsCli { impl LabelsCli {
/// Executes the labels command to display Gmail label information.
///
/// This method coordinates the label inspection workflow by utilizing the
/// Gmail client to retrieve and display all available labels in the user's account.
/// The output includes both system labels (like INBOX, SENT) and user-created labels.
///
/// # Arguments
///
/// * `client` - Authenticated Gmail client for API communication
///
/// # Returns
///
/// Returns `Result<(), Error>` indicating success or failure of the operation.
///
/// # Operation Details
///
/// The function performs the following steps:
/// 1. **Label Retrieval**: Fetches all labels from the Gmail API
/// 2. **Format Processing**: Organizes labels for display
/// 3. **Display Output**: Shows labels with names and IDs
///
/// # Output Format
///
/// Labels are displayed in the format:
/// ```text
/// <Label Name>: <Label ID>
/// ```
///
/// # Error Handling
///
/// Possible errors include:
/// - **Authentication failures**: OAuth2 token issues or expired credentials
/// - **API communication errors**: Network issues or Gmail API unavailability
/// - **Permission errors**: Insufficient OAuth2 scopes for label access
///
/// # Side Effects
///
/// This function produces output to stdout showing the label information.
/// No Gmail account modifications are performed.
pub async fn run(&self, client: GmailClient) -> Result<(), Error> { pub async fn run(&self, client: GmailClient) -> Result<(), Error> {
client.show_label(); client.show_label();
Ok(()) Ok(())

View File

@@ -1,20 +1,196 @@
//! # Gmail Messages CLI Module
//!
//! This module provides comprehensive command-line interface functionality for querying,
//! filtering, and performing batch operations on Gmail messages. It supports advanced
//! Gmail query syntax, label-based filtering, and safe batch operations with built-in
//! dry-run capabilities.
//!
//! ## Overview
//!
//! The messages command enables users to:
//! - **Query messages**: Using Gmail's powerful search syntax
//! - **Filter by labels**: Target specific message categories
//! - **Batch operations**: Perform actions on multiple messages efficiently
//! - **Safety controls**: Preview operations before execution
//!
//! ## Command Structure
//!
//! ```bash
//! cull-gmail messages [OPTIONS] <ACTION>
//! ```
//!
//! ### Available Actions
//!
//! - **`list`**: Display message information without modifications
//! - **`trash`**: Move messages to Gmail's Trash folder (recoverable)
//! - **`delete`**: Permanently delete messages (irreversible)
//!
//! ### Filtering Options
//!
//! - **`-l, --labels`**: Filter by Gmail labels (can be specified multiple times)
//! - **`-Q, --query`**: Advanced Gmail query string using Gmail search syntax
//! - **`-m, --max-results`**: Maximum results per page (default: 200)
//! - **`-p, --pages`**: Maximum number of pages to process (0 = all pages)
//!
//! ## Gmail Query Syntax
//!
//! The module supports Gmail's full query syntax including:
//!
//! ### Date Queries
//! - `older_than:1y` - Messages older than 1 year
//! - `newer_than:30d` - Messages newer than 30 days
//! - `after:2023/1/1` - Messages after specific date
//!
//! ### Label Queries
//! - `label:promotions` - Messages with promotions label
//! - `-label:important` - Messages WITHOUT important label
//!
//! ### Content Queries
//! - `subject:newsletter` - Subject contains "newsletter"
//! - `from:example.com` - Messages from domain
//! - `has:attachment` - Messages with attachments
//!
//! ## Safety Features
//!
//! - **Preview mode**: List action shows what would be affected
//! - **Pagination**: Controlled processing with page limits
//! - **Error handling**: Graceful handling of API errors and network issues
//! - **Logging**: Comprehensive operation logging for audit trails
//!
//! ## Examples
//!
//! ### List Recent Messages
//! ```bash
//! cull-gmail messages -m 10 list
//! ```
//!
//! ### Find Old Promotional Emails
//! ```bash
//! cull-gmail messages -Q "label:promotions older_than:1y" list
//! ```
//!
//! ### Batch Trash Operation
//! ```bash
//! cull-gmail messages -Q "label:newsletters older_than:6m" trash
//! ```
//!
//! ### Multi-Label Query
//! ```bash
//! cull-gmail messages -l "promotions" -l "newsletters" -Q "older_than:3m" list
//! ```
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use cull_gmail::{GmailClient, MessageList, Result, RuleProcessor}; use cull_gmail::{GmailClient, MessageList, Result, RuleProcessor};
/// Available actions for Gmail message operations.
///
/// This enum defines the three primary operations that can be performed on Gmail messages
/// through the CLI, each with different levels of safety and reversibility.
///
/// # Action Safety Levels
///
/// - **List**: Safe inspection operation with no modifications
/// - **Trash**: Recoverable operation (messages can be restored for ~30 days)
/// - **Delete**: Permanent operation (irreversible)
///
/// # Usage Context
///
/// Actions are typically used in this progression:
/// 1. **List** - Preview messages that match criteria
/// 2. **Trash** - Move messages to recoverable trash
/// 3. **Delete** - Permanently remove messages (use with extreme caution)
#[derive(Debug, Subcommand)] #[derive(Debug, Subcommand)]
enum MessageAction { enum MessageAction {
/// Display message information without making any changes.
///
/// This is the safest operation, showing message details including:
/// - Message subject and sender
/// - Date and size information
/// - Labels and threading information
/// - Internal Gmail message IDs
List, List,
/// Move messages to Gmail's Trash folder.
///
/// This operation:
/// - Moves messages to the Trash label
/// - Allows recovery for approximately 30 days
/// - Is reversible through Gmail's web interface
/// - Provides a safety buffer before permanent deletion
Trash, Trash,
/// Permanently delete messages from Gmail.
///
/// **WARNING**: This operation is irreversible!
/// - Messages are permanently removed from Gmail
/// - No recovery is possible after deletion
/// - Use extreme caution and always test with list first
/// - Consider using trash instead for safety
Delete, Delete,
} }
/// Command line options for the list subcommand /// Command-line interface for Gmail message querying and batch operations.
///
/// This structure encapsulates all configuration options for the messages subcommand,
/// providing comprehensive filtering, pagination, and action capabilities for Gmail
/// message management. It supports complex queries using Gmail's search syntax and
/// multiple filtering mechanisms.
///
/// # Configuration Categories
///
/// - **Pagination**: Control result set size and page limits
/// - **Filtering**: Label-based and query-based message selection
/// - **Actions**: Operations to perform on selected messages
///
/// # Usage Patterns
///
/// ## Safe Exploration
/// ```bash
/// # Start with list to preview results
/// cull-gmail messages -Q "older_than:1y" list
///
/// # Then perform actions on the same query
/// cull-gmail messages -Q "older_than:1y" trash
/// ```
///
/// ## Controlled Processing
/// ```bash
/// # Process in small batches
/// cull-gmail messages -m 50 -p 5 -Q "label:newsletters" list
/// ```
///
/// ## Multi-Criteria Filtering
/// ```bash
/// # Combine labels and query filters
/// cull-gmail messages -l "promotions" -l "social" -Q "older_than:6m" trash
/// ```
///
/// # Safety Considerations
///
/// - Always use `list` action first to preview results
/// - Start with small page sizes for destructive operations
/// - Use `trash` instead of `delete` when possible for recoverability
/// - Test queries thoroughly before batch operations
#[derive(Debug, Parser)] #[derive(Debug, Parser)]
pub struct MessagesCli { pub struct MessagesCli {
/// Maximum results per page /// Maximum number of messages to retrieve per page.
///
/// Controls the batch size for Gmail API requests. Larger values are more
/// efficient but may hit API rate limits. Smaller values provide more
/// granular control and progress feedback.
///
/// **Range**: 1-500 (Gmail API limit)
/// **Performance**: 100-200 is typically optimal
#[arg(short, long,display_order = 1, help_heading = "Config", default_value = cull_gmail::DEFAULT_MAX_RESULTS)] #[arg(short, long,display_order = 1, help_heading = "Config", default_value = cull_gmail::DEFAULT_MAX_RESULTS)]
max_results: u32, max_results: u32,
/// Maximum number of pages (0=all)
/// Maximum number of pages to process.
///
/// Limits the total number of API requests and messages processed.
/// Use 0 for unlimited pages (process all matching messages).
///
/// **Safety**: Start with 1-2 pages for testing destructive operations
/// **Performance**: Higher values process more messages but take longer
#[arg( #[arg(
short, short,
long, long,
@@ -23,18 +199,89 @@ pub struct MessagesCli {
default_value = "1" default_value = "1"
)] )]
pages: u32, pages: u32,
/// Labels to filter the message list
/// Gmail labels to filter messages (can be specified multiple times).
///
/// Filters messages to only those containing ALL specified labels.
/// Use `cull-gmail labels` to see available labels in your account.
///
/// **Examples**:
/// - `-l "INBOX"` - Messages in inbox
/// - `-l "promotions" -l "unread"` - Unread promotional messages
#[arg(short, long, display_order = 1, help_heading = "Config")] #[arg(short, long, display_order = 1, help_heading = "Config")]
labels: Vec<String>, labels: Vec<String>,
/// Query string to select messages to list
/// Gmail query string using Gmail's advanced search syntax.
///
/// Supports the same query syntax as Gmail's web interface search box.
/// Can be combined with label filters for more precise targeting.
///
/// **Examples**:
/// - `"older_than:1y"` - Messages older than 1 year
/// - `"from:noreply@example.com older_than:30d"` - Old automated emails
/// - `"has:attachment larger:10M"` - Large attachments
#[arg(short = 'Q', long, display_order = 1, help_heading = "Config")] #[arg(short = 'Q', long, display_order = 1, help_heading = "Config")]
query: Option<String>, query: Option<String>,
/// Action: what to do with the message list
/// Action to perform on the filtered messages.
///
/// Determines what operation to execute on messages matching the filter criteria.
/// Actions range from safe inspection (list) to permanent deletion (delete).
#[command(subcommand)] #[command(subcommand)]
action: MessageAction, action: MessageAction,
} }
impl MessagesCli { impl MessagesCli {
/// Executes the messages command with the configured parameters and action.
///
/// This method orchestrates the complete message processing workflow:
/// 1. **Parameter Configuration**: Apply filters, pagination, and query settings
/// 2. **Message Retrieval**: Fetch messages from Gmail API based on criteria
/// 3. **Action Execution**: Perform the specified operation on retrieved messages
///
/// # Arguments
///
/// * `client` - Mutable Gmail client for API operations and state management
///
/// # Returns
///
/// Returns `Result<()>` indicating success or failure of the complete operation.
///
/// # Processing Flow
///
/// ## Parameter Setup
/// - Apply label filters to restrict message scope
/// - Configure Gmail query string for advanced filtering
/// - Set pagination parameters for controlled processing
///
/// ## Message Retrieval
/// - Execute Gmail API requests to fetch matching messages
/// - Handle pagination according to configured limits
/// - Process results in manageable batches
///
/// ## Action Execution
/// - **List**: Display message information with logging level awareness
/// - **Trash**: Move messages to Gmail Trash (recoverable)
/// - **Delete**: Permanently remove messages (irreversible)
///
/// # Error Handling
///
/// The method handles various error conditions:
/// - **Parameter errors**: Invalid labels or malformed queries
/// - **API errors**: Network issues, authentication failures, rate limits
/// - **Action errors**: Failures during trash or delete operations
///
/// # Performance Considerations
///
/// - **Batch processing**: Messages are processed in configurable batches
/// - **Rate limiting**: Respects Gmail API quotas and limits
/// - **Memory management**: Efficient handling of large result sets
///
/// # Safety Features
///
/// - **Logging awareness**: List output adapts to logging verbosity
/// - **Error isolation**: Individual message failures don't stop batch processing
/// - **Progress tracking**: Detailed logging for operation monitoring
pub(crate) async fn run(&self, client: &mut GmailClient) -> Result<()> { pub(crate) async fn run(&self, client: &mut GmailClient) -> Result<()> {
self.set_parameters(client)?; self.set_parameters(client)?;
@@ -55,6 +302,49 @@ impl MessagesCli {
// Ok(()) // Ok(())
} }
/// Configures the Gmail client with filtering and pagination parameters.
///
/// This method applies all user-specified configuration to the Gmail client,
/// preparing it for message retrieval operations. It handles label filters,
/// query strings, and pagination settings with comprehensive error checking.
///
/// # Arguments
///
/// * `client` - Mutable Gmail client to configure
///
/// # Returns
///
/// Returns `Result<()>` indicating success or failure of parameter configuration.
///
/// # Configuration Steps
///
/// ## Label Filtering
/// - Validates label names against available Gmail labels
/// - Applies multiple label filters with AND logic
/// - Skips label configuration if no labels specified
///
/// ## Query Configuration
/// - Applies Gmail query string if provided
/// - Combines with label filters for refined targeting
/// - Uses Gmail's native query syntax parsing
///
/// ## Pagination Setup
/// - Configures maximum results per page for API efficiency
/// - Logs configuration values for debugging and verification
/// - Ensures values are within Gmail API limits
///
/// # Error Conditions
///
/// The method can fail due to:
/// - **Invalid labels**: Label names that don't exist in the Gmail account
/// - **Malformed queries**: Query syntax that Gmail API cannot parse
/// - **Parameter limits**: Values outside Gmail API acceptable ranges
///
/// # Logging
///
/// Configuration steps are logged at appropriate levels:
/// - **Trace**: Detailed parameter values for debugging
/// - **Debug**: Configuration confirmation and validation results
fn set_parameters(&self, client: &mut GmailClient) -> Result<()> { fn set_parameters(&self, client: &mut GmailClient) -> Result<()> {
if !self.labels().is_empty() { if !self.labels().is_empty() {
client.add_labels(self.labels())?; client.add_labels(self.labels())?;
@@ -71,14 +361,44 @@ impl MessagesCli {
Ok(()) Ok(())
} }
/// Returns a reference to the configured Gmail labels for filtering.
///
/// This accessor provides access to the list of labels that will be used
/// to filter messages. Labels are combined with AND logic, meaning messages
/// must have ALL specified labels to be included in results.
///
/// # Returns
///
/// Returns a reference to the vector of label names as configured by the user.
/// An empty vector indicates no label-based filtering will be applied.
pub(crate) fn labels(&self) -> &Vec<String> { pub(crate) fn labels(&self) -> &Vec<String> {
&self.labels &self.labels
} }
/// Returns a reference to the configured Gmail query string.
///
/// This accessor provides access to the advanced query string that will be
/// applied to message filtering. The query uses Gmail's native search syntax
/// and can be combined with label filters for precise targeting.
///
/// # Returns
///
/// Returns a reference to the optional query string. `None` indicates
/// no advanced query filtering will be applied.
pub(crate) fn query(&self) -> &Option<String> { pub(crate) fn query(&self) -> &Option<String> {
&self.query &self.query
} }
/// Returns the maximum number of messages to retrieve per page.
///
/// This accessor provides the configured batch size for Gmail API requests.
/// The value determines how many messages are fetched in each API call,
/// affecting both performance and memory usage.
///
/// # Returns
///
/// Returns the maximum results per page as configured by the user or default value.
/// The value is guaranteed to be within Gmail API acceptable limits.
pub(crate) fn max_results(&self) -> u32 { pub(crate) fn max_results(&self) -> u32 {
self.max_results self.max_results
} }