Skip to main content

luff/printer/
mod.rs

1//! File printing implementations
2
3mod colors;
4#[cfg(feature = "cli")]
5mod markdown;
6mod tree;
7
8use crate::{config::IgnorePatterns, format::OutputFormat};
9#[cfg(feature = "cli")]
10use crate::{error::Result, walker::WalkerEntry};
11use std::path::PathBuf;
12
13// Re-exports
14pub use colors::Colors;
15#[cfg(feature = "cli")]
16pub use markdown::MarkdownPrinter;
17pub use tree::{TreePrinter, format_tree};
18
19/// Type-safe wrapper for pattern filtering behavior
20///
21/// This newtype eliminates boolean blindness and makes the intent explicit
22/// at call sites. Instead of passing `true` or `false`, callers use
23/// `SkipPatterns::ENABLED` or `SkipPatterns::DISABLED`.
24///
25/// # Examples
26///
27/// ```
28/// use luff::printer::SkipPatterns;
29///
30/// // Clear intent at call site
31/// let patterns = SkipPatterns::ENABLED;
32/// assert!(patterns.should_skip());
33///
34/// let patterns = SkipPatterns::DISABLED;
35/// assert!(!patterns.should_skip());
36/// ```
37#[derive(Debug, Clone, Copy, PartialEq, Eq)]
38pub struct SkipPatterns(bool);
39
40impl SkipPatterns {
41    /// Enable pattern-based filtering
42    ///
43    /// Files matching ignore patterns (binary extensions, etc.) will be
44    /// filtered out before processing.
45    pub const ENABLED: Self = Self(true);
46
47    /// Disable pattern-based filtering
48    ///
49    /// All files will be processed regardless of extension or pattern
50    /// matches. This is typically used when files are explicitly specified
51    /// via the `-f` flag.
52    pub const DISABLED: Self = Self(false);
53
54    /// Check if pattern filtering should be applied
55    ///
56    /// Returns `true` if files should be filtered based on ignore patterns,
57    /// `false` if all files should be processed.
58    #[must_use]
59    pub const fn should_skip(self) -> bool {
60        self.0
61    }
62}
63
64/// Options for configuring printer output
65#[derive(Debug, Clone)]
66pub struct PrinterOptions {
67    /// The output format to use
68    pub format: OutputFormat,
69    /// Root directory for calculating relative paths
70    pub root: PathBuf,
71    /// Whether to apply pattern-based filtering
72    pub skip_patterns: SkipPatterns,
73    /// Ignore patterns to use for filtering
74    pub patterns: IgnorePatterns,
75}
76
77/// Print a file entry using the appropriate printer
78///
79/// # Errors
80///
81/// Returns an error if:
82/// - File cannot be read
83/// - File is not valid UTF-8 (for text formats)
84/// - Output cannot be written to stdout
85#[cfg(feature = "cli")]
86pub fn print_file(entry: &WalkerEntry, options: &PrinterOptions) -> Result<()> {
87    match options.format {
88        OutputFormat::Markdown => MarkdownPrinter::print(
89            entry,
90            &options.root,
91            &options.patterns,
92            options.skip_patterns,
93        ),
94        OutputFormat::Tree => TreePrinter::print(entry, &options.root),
95    }
96}