#![doc = include_str!("../docs/Concepts.md")]
pub use async_trait;
pub use color_eyre;
pub use tokio_stream;
#[cfg(feature = "log")]
pub use tracing::Level;
pub mod action;
pub mod filter;
pub mod generator;
pub mod launcher;
pub mod sorter;
pub mod source;
pub mod ui;
pub use crate::action::Action;
pub use crate::filter::Filter;
pub use crate::generator::Generator;
pub use crate::launcher::Launcher;
pub use crate::sorter::Sorter;
pub use crate::source::Source;
pub use crate::ui::UI;
use color_eyre::eyre::{OptionExt, Result};
#[cfg(feature = "log")]
fn init_subscriber_with_level(level: Level) -> Result<tracing_appender::non_blocking::WorkerGuard> {
use tracing_subscriber::fmt::format::FmtSpan;
fn db_dir() -> Option<std::path::PathBuf> {
let path = dirs::cache_dir().map(|p| p.join("ltrait/log"));
if let Some(parent) = path.as_ref().and_then(|p| p.parent()) {
std::fs::create_dir_all(parent).ok()?;
}
path
}
let file_appender = tracing_appender::rolling::hourly(
db_dir().ok_or_eyre("failed to get log dir")?,
"core.log",
);
let (non_blocking, guard) = tracing_appender::non_blocking(file_appender);
tracing_subscriber::fmt()
.with_writer(non_blocking)
.with_ansi(false)
.with_max_level(level) .with_span_events(FmtSpan::ACTIVE) .init();
Ok(guard)
}
pub fn setup(log_level: Level) -> Result<tracing_appender::non_blocking::WorkerGuard> {
color_eyre::install()?;
#[cfg(feature = "log")]
init_subscriber_with_level(log_level)
}