1#![warn(missing_docs)]
6#![warn(clippy::pedantic)]
7#![allow(clippy::module_name_repetitions)]
8#![allow(clippy::missing_errors_doc)]
9#![allow(clippy::missing_panics_doc)]
10
11pub mod cache;
12pub mod config;
13pub mod error;
14pub mod server;
15pub mod tools;
16pub mod utils;
17
18pub use crate::error::{Error, Result};
20pub use crate::server::{CratesDocsServer, ServerConfig};
21
22pub const VERSION: &str = env!("CARGO_PKG_VERSION");
24
25pub const NAME: &str = "crates-docs";
27
28#[deprecated(note = "Please use init_logging_with_config instead")]
33pub fn init_logging(debug: bool) -> Result<()> {
34 use tracing_subscriber::{fmt, prelude::*, EnvFilter};
35
36 let filter = if debug {
37 EnvFilter::new("debug")
38 } else {
39 EnvFilter::new("info")
40 };
41
42 let fmt_layer = fmt::layer()
43 .with_target(true)
44 .with_thread_ids(true)
45 .with_thread_names(true)
46 .compact();
47
48 tracing_subscriber::registry()
49 .with(filter)
50 .with(fmt_layer)
51 .try_init()
52 .map_err(|e| error::Error::Initialization(e.to_string()))?;
53
54 Ok(())
55}
56
57pub fn init_logging_with_config(config: &crate::config::LoggingConfig) -> Result<()> {
62 use tracing_subscriber::{fmt, prelude::*, EnvFilter};
63
64 let level = match config.level.to_lowercase().as_str() {
66 "trace" => "trace",
67 "debug" => "debug",
68 "warn" => "warn",
69 "error" => "error",
70 _ => "info",
71 };
72
73 let filter = EnvFilter::new(level);
74
75 match (config.enable_console, config.enable_file, &config.file_path) {
77 (true, true, Some(file_path)) => {
79 let log_dir = std::path::Path::new(file_path)
81 .parent()
82 .filter(|p| !p.as_os_str().is_empty())
83 .unwrap_or_else(|| std::path::Path::new("."));
84 let log_file_name = std::path::Path::new(file_path)
85 .file_name()
86 .unwrap_or(std::ffi::OsStr::new("crates-docs.log"));
87
88 std::fs::create_dir_all(log_dir).map_err(|e| {
90 error::Error::Initialization(format!("Failed to create log directory: {e}"))
91 })?;
92
93 let file_appender = tracing_appender::rolling::daily(log_dir, log_file_name);
95
96 tracing_subscriber::registry()
97 .with(filter)
98 .with(
99 fmt::layer()
100 .with_target(true)
101 .with_thread_ids(true)
102 .with_thread_names(true)
103 .compact(),
104 )
105 .with(
106 fmt::layer()
107 .with_writer(file_appender)
108 .with_target(true)
109 .with_thread_ids(true)
110 .with_thread_names(true)
111 .compact(),
112 )
113 .try_init()
114 .map_err(|e| error::Error::Initialization(e.to_string()))?;
115 }
116
117 (true, _, _) | (false, false, _) => {
119 tracing_subscriber::registry()
120 .with(filter)
121 .with(
122 fmt::layer()
123 .with_target(true)
124 .with_thread_ids(true)
125 .with_thread_names(true)
126 .compact(),
127 )
128 .try_init()
129 .map_err(|e| error::Error::Initialization(e.to_string()))?;
130 }
131
132 (false, true, Some(file_path)) => {
134 let log_dir = std::path::Path::new(file_path)
136 .parent()
137 .filter(|p| !p.as_os_str().is_empty())
138 .unwrap_or_else(|| std::path::Path::new("."));
139 let log_file_name = std::path::Path::new(file_path)
140 .file_name()
141 .unwrap_or(std::ffi::OsStr::new("crates-docs.log"));
142
143 std::fs::create_dir_all(log_dir).map_err(|e| {
145 error::Error::Initialization(format!("Failed to create log directory: {e}"))
146 })?;
147
148 let file_appender = tracing_appender::rolling::daily(log_dir, log_file_name);
150
151 tracing_subscriber::registry()
152 .with(filter)
153 .with(
154 fmt::layer()
155 .with_writer(file_appender)
156 .with_target(true)
157 .with_thread_ids(true)
158 .with_thread_names(true)
159 .compact(),
160 )
161 .try_init()
162 .map_err(|e| error::Error::Initialization(e.to_string()))?;
163 }
164
165 _ => {
167 tracing_subscriber::registry()
168 .with(filter)
169 .with(
170 fmt::layer()
171 .with_target(true)
172 .with_thread_ids(true)
173 .with_thread_names(true)
174 .compact(),
175 )
176 .try_init()
177 .map_err(|e| error::Error::Initialization(e.to_string()))?;
178 }
179 }
180
181 Ok(())
182}