#![allow(renamed_and_removed_lints)] #![allow(unknown_lints)] #![allow(clippy::cognitive_complexity)] #![allow(clippy::collapsible_if)] #![allow(clippy::let_unit_value)] #![allow(clippy::needless_lifetimes)] #![allow(clippy::needless_raw_string_hashes)] #![allow(clippy::result_large_err)] #![allow(clippy::significant_drop_in_scrutinee)] #![allow(clippy::uninlined_format_args)]
#![allow(mismatched_lifetime_syntaxes)] #![warn(noop_method_call)]
#![warn(unreachable_pub)]
#![warn(clippy::manual_ok_or)]
#![warn(clippy::needless_borrow)]
#![warn(clippy::needless_pass_by_value)]
#![warn(clippy::option_option)]
#![warn(clippy::rc_buffer)]
#![warn(clippy::semicolon_if_nothing_returned)]
#![warn(clippy::trait_duplication_in_bounds)]
#![warn(clippy::unseparated_literal_suffix)]
#![deny(clippy::all)]
#![deny(clippy::await_holding_lock)]
#![deny(clippy::cargo_common_metadata)]
#![deny(clippy::cast_lossless)]
#![deny(clippy::checked_conversions)]
#![deny(clippy::debug_assert_with_mut_call)]
#![deny(clippy::exhaustive_enums)]
#![deny(clippy::exhaustive_structs)]
#![deny(clippy::expl_impl_clone_on_copy)]
#![deny(clippy::fallible_impl_from)]
#![deny(clippy::implicit_clone)]
#![deny(clippy::large_stack_arrays)]
#![deny(missing_docs)]
#![deny(clippy::missing_docs_in_private_items)]
#![deny(clippy::mod_module_files)]
#![deny(clippy::print_stderr)]
#![deny(clippy::print_stdout)]
#![deny(clippy::ref_option_ref)]
#![deny(clippy::string_slice)] #![deny(clippy::unchecked_time_subtraction)]
#![deny(clippy::unnecessary_wraps)]
#![deny(clippy::unused_async)]
#![deny(clippy::unwrap_used)]
#![deny(clippy::pedantic)]
use anyhow::{Result, anyhow, bail};
use std::sync::OnceLock;
use tracing::level_filters::LevelFilter;
use tracing::{debug, error, info, warn};
use tracing_subscriber::{self};
pub mod traits;
use crate::traits::TorPtCommunicator;
pub mod prelude {
pub use super::traits::TorPtCommunicator;
pub use crate::{PtTracing, SEVERITY};
}
pub mod macros;
#[repr(u8)]
#[derive(Clone, Copy)]
#[non_exhaustive]
pub enum SEVERITY {
DEBUG = 1,
INFO = 2,
NOTICE = 3,
WARNING = 4,
ERROR = 5,
}
pub static PT_TRACING: OnceLock<PtTracing> = OnceLock::new();
impl From<SEVERITY> for LevelFilter {
fn from(severity: SEVERITY) -> Self {
match severity {
SEVERITY::DEBUG => LevelFilter::DEBUG,
SEVERITY::INFO => LevelFilter::INFO,
SEVERITY::WARNING | SEVERITY::NOTICE => LevelFilter::WARN,
SEVERITY::ERROR => LevelFilter::ERROR,
}
}
}
#[non_exhaustive]
pub struct PtTracing {
pub severity: SEVERITY,
}
impl PtTracing {
pub fn get_config() -> &'static Self {
match PT_TRACING.get() {
#[allow(clippy::print_stdout)]
None => {
println!("LOG SEVERITY=error MESSAGE=\"pt_tracing is never inited\"");
panic!("pt_tracing is never inited")
},
Some(pt_tracing) => pt_tracing,
}
}
#[must_use]
pub fn fmt() -> Self {
PtTracing {
severity: SEVERITY::NOTICE,
}
}
#[must_use]
pub fn with_severity(mut self, severity: SEVERITY) -> Self {
self.severity = severity;
self
}
pub fn try_init(self) -> Result<()> {
tracing_subscriber::fmt()
.with_max_level(self.severity)
.compact()
.with_level(false)
.with_target(false)
.with_thread_ids(false)
.with_thread_names(false)
.with_file(false)
.with_line_number(false)
.with_ansi(false)
.without_time()
.try_init()
.map_err(|e| anyhow::anyhow!(e))?;
match PT_TRACING.set(self) {
#[allow(clippy::print_stdout)]
Err(_) => {
println!("LOG SEVERITY=error MESSAGE=\"pt_tracing already inited\"");
bail!("pt_tracing already inited")
},
Ok(()) => {
PtTracing::notice("PT_TRACING is set")?;
},
}
Ok(())
}
}
impl TorPtCommunicator for PtTracing {
type DebugOutput = Result<()>;
type InfoOutput = Result<()>;
type ErrorOutput = Result<()>;
type NoticeOutput = Result<()>;
type WarnOutput = Result<()>;
fn debug(message: &str) -> Result<()> {
debug!("LOG SEVERITY=debug MESSAGE=\"{}\"", message);
Ok(())
}
fn info(message: &str) -> Result<()> {
info!("LOG SEVERITY=info MESSAGE=\"{}\"", message);
Ok(())
}
fn error(message: &str) -> Result<()> {
error!("LOG SEVERITY=error MESSAGE=\"{}\"", message);
Ok(())
}
#[allow(clippy::print_stdout)]
fn notice(message: &str) -> Result<()> {
match PT_TRACING
.get()
.ok_or_else(|| {
println!("LOG SEVERITY=error MESSAGE=\"pt_tracing is never inited\"");
anyhow!("pt_tracing is never inited")
})?
.severity
{
SEVERITY::DEBUG | SEVERITY::INFO | SEVERITY::NOTICE => {
warn!("LOG SEVERITY=notice MESSAGE=\"{}\"", message);
},
SEVERITY::WARNING | SEVERITY::ERROR => {},
}
Ok(())
}
fn warn(message: &str) -> Result<()> {
warn!("LOG SEVERITY=warning MESSAGE=\"{}\"", message);
Ok(())
}
fn env_error(msg: &str) {
error!("ENV-ERROR {msg}");
}
fn version_error(msg: &str) {
error!("VERSION-ERROR {}", &msg);
}
fn proxy_done() {
error!("PROXY DONE");
}
fn version(version: &str) {
error!("VERSION {version}");
}
fn proxy_error(msg: &str) {
error!("PROXY-ERROR {msg}");
}
fn cmethod(transport: &str, proxy_type: &str, address: &str) {
error!("CMETHOD {transport} {proxy_type} {address}");
}
fn cmethod_error(transport: &str, msg: &str) {
error!("CMETHOD-ERROR {transport} {msg}");
}
fn cmethods_done() {
error!("CMETHODS DONE");
}
fn smethod(transport: &str, address: &str, options: Option<&str>) {
match options {
Some(options) => {
error!("SMETHOD {transport} {address} {options}");
},
None => {
error!("SMETHOD {transport} {address}");
},
}
}
fn smethod_error(transport: &str, msg: &str) {
error!("SMETHOD-ERROR {transport} {msg}");
}
fn smethods_done() {
error!("SMETHODS DONE");
}
}
#[cfg(test)]
mod test {
#![allow(clippy::bool_assert_comparison)]
#![allow(clippy::clone_on_copy)]
#![allow(clippy::dbg_macro)]
#![allow(clippy::mixed_attributes_style)]
#![allow(clippy::print_stderr)]
#![allow(clippy::print_stdout)]
#![allow(clippy::single_char_pattern)]
#![allow(clippy::unwrap_used)]
#![allow(clippy::unchecked_time_subtraction)]
#![allow(clippy::useless_vec)]
#![allow(clippy::needless_pass_by_value)]
#![allow(clippy::string_slice)] #![allow(clippy::pedantic)]
use super::*;
impl PtTracing {
pub fn notice_for_test(message: &str) -> Result<()> {
match Self::get_config().severity {
SEVERITY::DEBUG | SEVERITY::INFO | SEVERITY::NOTICE => {
println!("LOG SEVERITY=notice MESSAGE={}", message);
},
SEVERITY::WARNING | SEVERITY::ERROR => {
anyhow::bail!("error!");
},
}
Ok(())
}
}
#[test]
fn test_for_notice() {
PtTracing::fmt()
.with_severity(SEVERITY::DEBUG)
.try_init()
.unwrap();
PtTracing::notice_for_test("notice").unwrap();
}
}