···5656tokio-util = "0.7.18"
5757signal-hook = "0.4.3"
5858strum = { version = "0.28.0", features = ["derive"] }
5959-lazy_static = "1.5.0"
6059directories = "6.0.0"
6060+tracing-subscriber = { version = "0.3.22", features = ["env-filter"] }
6161+tracing-error = "0.2.1"
+21-23
src/config.rs
···11use directories::ProjectDirs;
22-use lazy_static::lazy_static;
32use serde::Deserialize;
43use std::{env, path::PathBuf, sync::LazyLock};
5466-// #[expect(dead_code)]
77-static PROJECT_NAME: LazyLock<String> = LazyLock::new(|| env!("CARGO_CRATE_NAME").to_uppercase());
55+/// Project Name: Filaments
66+pub static PROJECT_NAME: LazyLock<String> =
77+ LazyLock::new(|| env!("CARGO_CRATE_NAME").to_uppercase());
8899-#[expect(dead_code)]
1010-static DATA_FOLDER: LazyLock<Option<PathBuf>> = LazyLock::new(|| {
99+/// The OS-agnostic data directory for the project.
1010+pub static DATA_DIRECTORY: LazyLock<Option<PathBuf>> = LazyLock::new(|| {
1111 env::var(format!("{}_DATA", PROJECT_NAME.clone()))
1212 .ok()
1313 .map(PathBuf::from)
1414});
1515-#[expect(dead_code)]
1616-static CONFIG_FOLDER: LazyLock<Option<PathBuf>> = LazyLock::new(|| {
1515+1616+/// The OS-agnostic config directory for the project.
1717+pub static CONFIG_DIRECTORY: LazyLock<Option<PathBuf>> = LazyLock::new(|| {
1718 env::var(format!("{}_CONFIG", PROJECT_NAME.clone()))
1819 .ok()
1920 .map(PathBuf::from)
···47484849/// Returns the path to the OS-agnostic data directory.
4950pub fn get_data_dir() -> PathBuf {
5050- let directory = if let Some(s) = DATA_FOLDER.clone() {
5151- s
5252- } else if let Some(proj_dirs) = project_directory() {
5353- proj_dirs.data_local_dir().to_path_buf()
5454- } else {
5555- PathBuf::from(".").join(".data")
5656- };
5757- directory
5151+ DATA_DIRECTORY.clone().unwrap_or_else(|| {
5252+ project_directory().map_or_else(
5353+ || PathBuf::from(".").join(".data"),
5454+ |proj_dirs| proj_dirs.data_local_dir().to_path_buf(),
5555+ )
5656+ })
5857}
59586059/// Returns the path to the OS-agnostic config directory.
6060+#[expect(dead_code)]
6161pub fn get_config_dir() -> PathBuf {
6262- let directory = if let Some(s) = CONFIG_FOLDER.clone() {
6363- s
6464- } else if let Some(proj_dirs) = project_directory() {
6565- proj_dirs.config_local_dir().to_path_buf()
6666- } else {
6767- PathBuf::from(".").join(".config")
6868- };
6969- directory
6262+ CONFIG_DIRECTORY.clone().unwrap_or_else(|| {
6363+ project_directory().map_or_else(
6464+ || PathBuf::from(".").join(".config"),
6565+ |proj_dirs| proj_dirs.config_local_dir().to_path_buf(),
6666+ )
6767+ })
7068}
71697270fn project_directory() -> Option<ProjectDirs> {
+52
src/logging.rs
···11+use std::{
22+ fs::{File, create_dir_all},
33+ sync::LazyLock,
44+};
55+66+use color_eyre::eyre::Result;
77+use tracing::Level;
88+use tracing_error::ErrorLayer;
99+use tracing_subscriber::{EnvFilter, Layer, fmt, layer::SubscriberExt, util::SubscriberInitExt};
1010+1111+use crate::config;
1212+1313+/// The user-set log level if it exists.
1414+pub static LOG_LEVEL_ENV: LazyLock<String> =
1515+ LazyLock::new(|| format!("{}_LOG_LEVEL", config::PROJECT_NAME.clone()));
1616+1717+/// The logfile name set by our package name.
1818+pub static LOG_FILE: LazyLock<String> = LazyLock::new(|| format!("{}.log", env!("CARGO_PKG_NAME")));
1919+2020+/// Initializes the logger, which writes logs to a `log_file` in the data dir.
2121+///
2222+/// NOTE: log level is configurable via the `RUST_LOG` env var or the
2323+/// `FILAMENTS_LOG_LEVEL` env var
2424+pub fn init() -> Result<()> {
2525+ let directory = config::get_data_dir();
2626+2727+ create_dir_all(&directory)?;
2828+2929+ let log_path = directory.join(LOG_FILE.clone());
3030+ let log_file = File::create(log_path)?;
3131+3232+ let env_filter = EnvFilter::builder().with_default_directive(Level::INFO.into());
3333+3434+ // If `RUST_LOG` is set, use that as default,, or use value of `LOG_ENV` variable.
3535+ let env_filter = env_filter
3636+ .try_from_env()
3737+ .or_else(|_| env_filter.with_env_var(LOG_LEVEL_ENV.clone()).from_env())?;
3838+3939+ let file_subscriber = fmt::layer()
4040+ .with_file(true)
4141+ .with_line_number(true)
4242+ .with_writer(log_file)
4343+ .with_target(false)
4444+ .with_ansi(false)
4545+ .with_filter(env_filter);
4646+ tracing_subscriber::registry()
4747+ .with(file_subscriber)
4848+ .with(ErrorLayer::default())
4949+ .try_init()?;
5050+5151+ Ok(())
5252+}