luff 0.2.1

Print files with formatting
Documentation
//! File printing implementations

mod colors;
#[cfg(feature = "cli")]
mod markdown;
mod tree;

use crate::{config::IgnorePatterns, format::OutputFormat};
#[cfg(feature = "cli")]
use crate::{error::Result, walker::WalkerEntry};
use std::path::PathBuf;

// Re-exports
pub use colors::Colors;
#[cfg(feature = "cli")]
pub use markdown::MarkdownPrinter;
pub use tree::{TreePrinter, format_tree};

/// Type-safe wrapper for pattern filtering behavior
///
/// This newtype eliminates boolean blindness and makes the intent explicit
/// at call sites. Instead of passing `true` or `false`, callers use
/// `SkipPatterns::ENABLED` or `SkipPatterns::DISABLED`.
///
/// # Examples
///
/// ```
/// use luff::printer::SkipPatterns;
///
/// // Clear intent at call site
/// let patterns = SkipPatterns::ENABLED;
/// assert!(patterns.should_skip());
///
/// let patterns = SkipPatterns::DISABLED;
/// assert!(!patterns.should_skip());
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SkipPatterns(bool);

impl SkipPatterns {
    /// Enable pattern-based filtering
    ///
    /// Files matching ignore patterns (binary extensions, etc.) will be
    /// filtered out before processing.
    pub const ENABLED: Self = Self(true);

    /// Disable pattern-based filtering
    ///
    /// All files will be processed regardless of extension or pattern
    /// matches. This is typically used when files are explicitly specified
    /// via the `-f` flag.
    pub const DISABLED: Self = Self(false);

    /// Check if pattern filtering should be applied
    ///
    /// Returns `true` if files should be filtered based on ignore patterns,
    /// `false` if all files should be processed.
    #[must_use]
    pub const fn should_skip(self) -> bool {
        self.0
    }
}

/// Options for configuring printer output
#[derive(Debug, Clone)]
pub struct PrinterOptions {
    /// The output format to use
    pub format: OutputFormat,
    /// Root directory for calculating relative paths
    pub root: PathBuf,
    /// Whether to apply pattern-based filtering
    pub skip_patterns: SkipPatterns,
    /// Ignore patterns to use for filtering
    pub patterns: IgnorePatterns,
}

/// Print a file entry using the appropriate printer
///
/// # Errors
///
/// Returns an error if:
/// - File cannot be read
/// - File is not valid UTF-8 (for text formats)
/// - Output cannot be written to stdout
#[cfg(feature = "cli")]
pub fn print_file(entry: &WalkerEntry, options: &PrinterOptions) -> Result<()> {
    match options.format {
        OutputFormat::Markdown => MarkdownPrinter::print(
            entry,
            &options.root,
            &options.patterns,
            options.skip_patterns,
        ),
        OutputFormat::Tree => TreePrinter::print(entry, &options.root),
    }
}