bubbletea_rs/logging.rs
1//! Logging utilities for bubbletea-rs applications.
2//!
3//! This module provides file-based logging functionality for Bubble Tea applications.
4//! Logging is controlled by the `logging` feature flag and requires the `log` crate
5//! for actual log output.
6//!
7//! # Features
8//!
9//! - File-based logging with automatic file creation
10//! - Append-only logging to preserve existing log data
11//! - Graceful degradation when logging feature is disabled
12//!
13//! # Usage
14//!
15//! ```rust,no_run
16//! use bubbletea_rs::logging::log_to_file;
17//!
18//! // Set up logging to a file
19//! if let Err(e) = log_to_file("app.log", "MyApp") {
20//! eprintln!("Failed to initialize logging: {}", e);
21//! }
22//!
23//! // Now you can use standard log macros
24//! log::info!("Application started");
25//! log::error!("Something went wrong");
26//! ```
27
28use crate::Error;
29use std::path::Path;
30
31/// Set up file logging for the application.
32///
33/// This function initializes file-based logging by creating or opening the specified
34/// log file in append mode. The file will be created if it doesn't exist, and new
35/// log entries will be appended to preserve existing log data.
36///
37/// # Arguments
38///
39/// * `path` - The file path where logs should be written. Can be any type that
40/// implements `AsRef<Path>`, such as `&str`, `String`, or `PathBuf`.
41/// * `prefix` - A prefix string used for identifying log entries from this application.
42/// This is logged as an info message when logging is initialized.
43///
44/// # Returns
45///
46/// Returns `Ok(())` if logging was successfully initialized, or an `Error` if:
47/// - The log file cannot be created or opened
48/// - File permissions prevent writing to the specified path
49/// - The logging feature is not enabled (when compiled without the `logging` feature)
50///
51/// # Examples
52///
53/// ```rust,no_run
54/// use bubbletea_rs::logging::log_to_file;
55/// use std::path::PathBuf;
56///
57/// // Using a string path
58/// log_to_file("application.log", "MyApp")?;
59///
60/// // Using a PathBuf
61/// let log_path = PathBuf::from("logs").join("app.log");
62/// log_to_file(log_path, "MyApp")?;
63///
64/// // Using a relative path
65/// log_to_file("./logs/debug.log", "Debug")?;
66/// # Ok::<(), bubbletea_rs::Error>(())
67/// ```
68///
69/// # Errors
70///
71/// This function will return an error if:
72/// - The file cannot be created due to permission issues
73/// - The parent directory doesn't exist and cannot be created
74/// - The logging feature is not enabled at compile time
75///
76/// # Feature Requirements
77///
78/// This function requires the `logging` feature to be enabled. When compiled
79/// without this feature, it will always return an error indicating that
80/// logging is not available.
81#[cfg(feature = "logging")]
82pub fn log_to_file(path: impl AsRef<Path>, prefix: &str) -> Result<(), Error> {
83 use std::fs::OpenOptions;
84
85 let _file = OpenOptions::new()
86 .create(true)
87 .append(true)
88 .open(path.as_ref())?;
89
90 log::info!("Logging initialized with prefix: {prefix}");
91
92 Ok(())
93}
94
95/// Set up file logging for the application (feature-disabled version).
96///
97/// This is a stub implementation that always returns an error when the `logging`
98/// feature is not enabled. It provides a graceful way to handle logging calls
99/// in code that may or may not have logging support enabled.
100///
101/// # Arguments
102///
103/// * `_path` - The file path (ignored when logging is disabled)
104/// * `_prefix` - The prefix string (ignored when logging is disabled)
105///
106/// # Returns
107///
108/// Always returns an `Error::Configuration` indicating that the logging feature
109/// is not enabled.
110///
111/// # Examples
112///
113/// ```rust,ignore
114/// // This will always fail when logging feature is disabled
115/// match log_to_file("app.log", "MyApp") {
116/// Ok(()) => println!("Logging enabled"),
117/// Err(e) => eprintln!("Logging not available: {}", e),
118/// }
119/// ```
120///
121/// # Errors
122///
123/// Always returns `Error::Configuration` with a message explaining that the
124/// logging feature must be enabled to use this function.
125#[cfg(not(feature = "logging"))]
126pub fn log_to_file(_path: impl AsRef<Path>, _prefix: &str) -> Result<(), Error> {
127 Err(Error::Configuration(
128 "Logging feature is not enabled. Enable the 'logging' feature to use log_to_file."
129 .to_string(),
130 ))
131}