Compare commits

..

No commits in common. "f3b061a637c06bc3ada7a8b05ab9e892aa0433e9" and "46f6c77ecdcc0bd667e90a26cc13c7497a2354e9" have entirely different histories.

5 changed files with 166 additions and 205 deletions

View File

@ -11,13 +11,12 @@ edition = "2021"
[lints.rust] [lints.rust]
unsafe_code = "forbid" unsafe_code = "forbid"
missing_docs = "warn"
[lints.clippy] [lints.clippy]
enum_glob_use = "deny" # https://rust-lang.github.io/rust-clippy/master/index.html#/enum_glob_use enum_glob_use = "deny" # https://rust-lang.github.io/rust-clippy/master/index.html#/enum_glob_use
pedantic = "deny" # https://rust-lang.github.io/rust-clippy/master/index.html#/?groups=pedantic pedantic = "deny" # https://rust-lang.github.io/rust-clippy/master/index.html#/?groups=pedantic
nursery = "deny" # wip lints: https://rust-lang.github.io/rust-clippy/master/index.html#/?groups=nursery nursery = "deny" # wip lints: https://rust-lang.github.io/rust-clippy/master/index.html#/?groups=nursery
unwrap_used = "forbid" # https://rust-lang.github.io/rust-clippy/master/index.html#/unwrap_used unwrap_used = "deny" # https://rust-lang.github.io/rust-clippy/master/index.html#/unwrap_used
missing_const_for_fn = "warn" # https://rust-lang.github.io/rust-clippy/master/index.html#/missing_const_for_fn missing_const_for_fn = "warn" # https://rust-lang.github.io/rust-clippy/master/index.html#/missing_const_for_fn
missing_assert_message = "warn" # https://rust-lang.github.io/rust-clippy/master/index.html#/missing_assert_message missing_assert_message = "deny" # https://rust-lang.github.io/rust-clippy/master/index.html#/missing_assert_message
missing_errors_doc = "warn" # https://rust-lang.github.io/rust-clippy/master/index.html#/missing_assert_message missing_errors_doc = "deny" # https://rust-lang.github.io/rust-clippy/master/index.html#/missing_assert_message

View File

@ -6,17 +6,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
getset = { version = "0.1.2", default-features = false } getset = "0.1.2"
[lints.rust]
unsafe_code = "forbid"
missing_docs = "warn"
[lints.clippy]
enum_glob_use = "deny" # https://rust-lang.github.io/rust-clippy/master/index.html#/enum_glob_use
pedantic = "deny" # https://rust-lang.github.io/rust-clippy/master/index.html#/?groups=pedantic
nursery = "deny" # wip lints: https://rust-lang.github.io/rust-clippy/master/index.html#/?groups=nursery
unwrap_used = "forbid" # https://rust-lang.github.io/rust-clippy/master/index.html#/unwrap_used
missing_const_for_fn = "warn" # https://rust-lang.github.io/rust-clippy/master/index.html#/missing_const_for_fn
missing_assert_message = "warn" # https://rust-lang.github.io/rust-clippy/master/index.html#/missing_assert_message
missing_errors_doc = "warn" # https://rust-lang.github.io/rust-clippy/master/index.html#/missing_assert_message

View File

@ -16,105 +16,92 @@ use getset::Setters;
* Represents a valid `WANessa` configuration. Intended as a read-only singleton. * Represents a valid `WANessa` configuration. Intended as a read-only singleton.
* See [`DEFAULTS`] * See [`DEFAULTS`]
*/ */
#[derive(Clone, PartialEq, Eq, Getters, Setters)] #[derive(Clone,PartialEq, Eq)]
#[getset(get = "pub", set = "pub")] #[derive(Getters, Setters)]
#[getset(get = "pub")]
#[allow(clippy::struct_excessive_bools)] // False positive, since it is a config struct. #[allow(clippy::struct_excessive_bools)] // False positive, since it is a config struct.
pub struct Config { pub struct Config {
/// See [`LogVerbosity`].<br> /// See [`LogVerbosity`].<br>
/// Default: [`Warning`] /// Default: [`Warning`]
log_verbosity: LogVerbosity, pub log_verbosity: LogVerbosity,
/// Logs UTC time and date of message, if true.<br> /// Logs UTC time and date of message, if true.<br>
/// Default: `false` /// Default: `false`
log_time: bool, pub log_time: bool,
/// Time and date format.<br> /// Time and date format.<br>
/// Defaults to `%F/%T:%f`.<br> /// Defaults to `%F/%T:%f`.<br>
/// See [chrono](https://docs.rs/chrono/latest/chrono/format/strftime/index.html).<br> /// See [chrono](https://docs.rs/chrono/latest/chrono/format/strftime/index.html).<br>
/// Default example : `2001-12-31/23:59:33:26490000` /// Default example : `2001-12-31/23:59:33:26490000`
#[getset(skip)] #[getset(skip)]
log_time_format: Option<String>, pub log_time_format: Option<String>,
/// Logs location in code, where the message was logged, if true.<br> /// Logs location in code, where the message was logged, if true.<br>
/// Default: `false` /// Default: `false`
log_location: bool, pub log_location: bool,
/// If `Some(path)` tries to also write the log to `path` in addition to stderr/stderr.<br> /// If `Some(path)` tries to also write the log to `path` in addition to stderr/stderr.<br>
/// Default: [None] /// Default: [None]
log_path: Option<PathBuf>, pub log_path: Option<PathBuf>,
/// Logs to standard out, if true.<br> /// Logs to standard out, if true.<br>
/// Default: `true` /// Default: `true`
log_stdout: bool, pub log_stdout: bool,
/// Logs to standard err, if true.<br> /// Logs to standard err, if true.<br>
/// Default: `true` /// Default: `true`
log_stderr: bool, pub log_stderr: bool,
/// Database connection address. /// Database connection address.
/// Is an option to allow constructing a default config during compile time.<br> /// Is an option to allow constructing a default config during compile time.<br>
/// Default: `localhost`. /// Default: `localhost`.
#[getset(skip)] #[getset(skip)]
db_addr: Option<String>, pub db_addr: Option<String>,
/// Database connection port.<br> /// Database connection port.<br>
/// Default: `6969` (nice). /// Default: `6969` (nice).
db_port: u16, pub db_port: u16,
} }
impl Config { impl Config {
/// Getter for [`Self::db_addr`]. /// Getter for [`Self::db_addr`].
#[must_use]
pub fn db_addr(&self) -> &str { pub fn db_addr(&self) -> &str {
self.db_addr.as_ref().map_or("localhost", |addr| addr) self.db_addr.as_ref().map_or("localhost", |addr| addr)
} }
/// Setter for [`Self::db_addr`]. /// Getter for the [`Self::log_time_format`].
pub fn set_db_addr(&mut self, db_addr: impl Into<String>) { pub fn log_time_format(&self) -> &str
self.db_addr = Some(db_addr.into()); {
} self.log_time_format.as_ref().map_or("%F-%T:%f", |fmt| fmt)
}
/// Getter for [`Self::log_time_format`].
#[must_use]
pub fn log_time_format(&self) -> &str {
todo!();
// self.log_time_format.as_ref().map_or("%F-%T:%f", |fmt| fmt)
}
/// Setter for [`Self::log_time_format`].
pub fn set_log_time_format(&mut self, format: impl Into<String>) {
self.log_time_format = Some(format.into());
}
} }
/// See [`DEFAULTS`]. /// See [`DEFAULTS`].
impl Default for Config { impl Default for Config {
/// See [`DEFAULTS`]. /// See [`DEFAULTS`].
fn default() -> Self { fn default() -> Self {
DEFAULTS DEFAULTS
} }
} }
/** /// Default configuration.
* Default configuration. /// ```rust
* ```rust /// # use config::Config;
* # use config::Config; /// # use config::LogVerbosity::Warning;
* # use config::LogVerbosity::Warning; /// let DEFAULTS = Config
* let DEFAULTS = Config /// {
* { /// log_verbosity: Warning,
* log_verbosity: Warning, /// log_time: false,
* log_time: false, /// log_time_format: None,
* log_time_format: None, /// log_location: false,
* log_location: false, /// log_stdout: true,
* log_stdout: true, /// log_stderr: true,
* log_stderr: true, /// log_path: None,
* log_path: None, /// db_addr: None,
* db_addr: None, /// db_port: 6969,
* db_port: 6969, /// };
* }; /// # assert!(DEFAULTS == config::DEFAULTS)
* # assert!(DEFAULTS == config::DEFAULTS) /// ```
* ```
*/
pub const DEFAULTS: Config = Config { pub const DEFAULTS: Config = Config {
log_verbosity: Warning, log_verbosity: Warning,
log_time: false, log_time: false,
log_time_format: None, log_time_format: None,
log_location: false, log_location: false,
log_stdout: true, log_stdout: true,
log_stderr: true, log_stderr: true,
log_path: None, log_path: None,
db_addr: None, db_addr: None,
db_port: 6969, db_port: 6969,
}; };
@ -126,31 +113,36 @@ pub static CONFIG: RwLock<Config> = RwLock::new(DEFAULTS);
* Each level includes the previous ones. * Each level includes the previous ones.
*/ */
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum LogVerbosity { pub enum LogVerbosity
/// Critical Errors, may lead to crashes or deactivating certain features. {
Error, /// Critical Errors, may lead to crashes or deactivating certain features.
/// Very minor and recovered errors, such as invalid configs. Error,
Warning, /// Very minor and recovered errors, such as invalid configs.
/// Very verbose and detailed. Basically gives a step-by-step instruction on what is currently done. Warning,
Information, /// Very verbose and detailed. Basically gives a step-by-step instruction on what is currently done.
/// Very technical and even more verbose. Information,
/// May contain secrets and private information. /// Very technical and even more verbose.
/// **Do not use in production environments!** /// May contain secrets and private information.
Debugging, /// **Do not use in production environments!**
Debugging,
} }
impl PartialOrd for LogVerbosity { impl PartialOrd for LogVerbosity
/// Some operator overloading of comparison symbols (==, <,>=, etc.) as syntactic sugar. {
/// See [`PartialOrd`]. /// Some operator overloading of comparison symbols (==, <,>=, etc.) as syntactic sugar.
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { /// See [`PartialOrd`].
Some(self.cmp(other)) fn partial_cmp(&self, other: &Self) -> Option<Ordering>
} {
(*self as usize).partial_cmp(&(*other as usize))
}
} }
impl Ord for LogVerbosity { impl Ord for LogVerbosity
/// Some operator overloading of comparison symbols (==, <,>=, etc.) as syntactic sugar. {
/// See [`Ord`]. /// Some operator overloading of comparison symbols (==, <,>=, etc.) as syntactic sugar.
fn cmp(&self, other: &Self) -> Ordering { /// See [`Ord`].
(*self as usize).cmp(&(*other as usize)) fn cmp(&self, other: &Self) -> Ordering
} {
(*self as usize).cmp(&(*other as usize))
}
} }

View File

@ -8,16 +8,3 @@ edition = "2021"
[dependencies] [dependencies]
chrono = { version = "0.4.34", default-features = false, features = ["now"] } chrono = { version = "0.4.34", default-features = false, features = ["now"] }
config = { path = "../config"} config = { path = "../config"}
[lints.rust]
unsafe_code = "forbid"
missing_docs = "warn"
[lints.clippy]
enum_glob_use = "deny" # https://rust-lang.github.io/rust-clippy/master/index.html#/enum_glob_use
pedantic = "deny" # https://rust-lang.github.io/rust-clippy/master/index.html#/?groups=pedantic
nursery = "deny" # wip lints: https://rust-lang.github.io/rust-clippy/master/index.html#/?groups=nursery
unwrap_used = "forbid" # https://rust-lang.github.io/rust-clippy/master/index.html#/unwrap_used
missing_const_for_fn = "warn" # https://rust-lang.github.io/rust-clippy/master/index.html#/missing_const_for_fn
missing_assert_message = "warn" # https://rust-lang.github.io/rust-clippy/master/index.html#/missing_assert_message
missing_errors_doc = "warn" # https://rust-lang.github.io/rust-clippy/master/index.html#/missing_assert_message

View File

@ -11,13 +11,13 @@ use config::LogVerbosity;
use chrono::Utc; use chrono::Utc;
use LogVerbosity::Information;
use LogVerbosity::Warning; use LogVerbosity::Warning;
use LogVerbosity::Information;
use LogMessageType::GenericDebug;
use LogMessageType::GenericErr; use LogMessageType::GenericErr;
use LogMessageType::GenericInfo;
use LogMessageType::GenericWarn; use LogMessageType::GenericWarn;
use LogMessageType::GenericInfo;
use LogMessageType::GenericDebug;
/** /**
* Logs the given message. * Logs the given message.
@ -27,57 +27,55 @@ use LogMessageType::GenericWarn;
* or if another error occurs, such as a full disk. * or if another error occurs, such as a full disk.
*/ */
// TODO: Create macro to make last three parameters optional. // TODO: Create macro to make last three parameters optional.
pub fn log_message(msg: &LogMessage, file: &str, line: &str, column: &str) { pub fn log_message(msg: &LogMessage, file: &str, line: &str, column: &str)
let conf = config::CONFIG.read().unwrap_or_else(|_| { {
panic!("Failed aqcuire read lock on config\nTried to log message: {msg}") let conf = config::CONFIG.read().expect(&format!("Failed aqcuire read lock on config\nTried to log message: {msg}"));
});
if conf.log_verbosity() < &msg.1 { if conf.log_verbosity() < &msg.1 { return; }
return;
}
let mut log_line = String::new(); let mut log_line = String::new();
// add time substring // add time substring
if *conf.log_time() { if *conf.log_time()
log_line += &format!("{} ", Utc::now().format(conf.log_time_format())); {
} log_line += &format!("{} ", Utc::now().format(conf.log_time_format()));
}
// add code location substring // add code location substring
if *conf.log_location() { if *conf.log_location()
log_line += &format!("{file}:{line},{column} "); {
} log_line += &format!("{file}:{line},{column} ");
}
log_line += &msg.to_string(); log_line += &msg.to_string();
// May panic if file cannot be opened or written to. // May panic if file cannot be opened or written to.
conf.log_path().as_ref().map_or_else( conf.log_path().as_ref().map_or_else(
|| {}, || {}, |path|
|path| { {
let mut file = OpenOptions::new() let mut file = OpenOptions::new()
.write(true) .write(true)
.append(true) .append(true)
.open(path) .open(path)
.unwrap_or_else(|_| { .expect(
panic!( &format!("Could not open log file: {path:#?}")
"Could not open log fil );
e: {path:#?}" writeln!(file, "{log_line}").expect(&format!("Could not write log to file: {path:#?}"));
) }
}); );
writeln!(file, "{log_line}")
.unwrap_or_else(|_| panic!("Could not write log to file: {path:#?}"));
},
);
if msg.1 <= Warning && *conf.log_stderr() { if msg.1 <= Warning && *conf.log_stderr()
// May panic if writing to stderr fails. {
eprintln!("{log_line}"); // May panic if writing to stderr fails.
} else if msg.1 >= Information && *conf.log_stdout() { eprintln!("{log_line}");
// May panic if writing to stdout fails. }
println!("{log_line}"); else if msg.1 >= Information && *conf.log_stdout()
} {
// May panic if writing to stdout fails.
println!("{log_line}");
}
drop(conf); // remove read lock drop(conf); // remove read lock
} }
/** /**
@ -85,10 +83,12 @@ pub fn log_message(msg: &LogMessage, file: &str, line: &str, column: &str) {
*/ */
pub struct LogMessage(LogMessageType, LogVerbosity); pub struct LogMessage(LogMessageType, LogVerbosity);
impl Display for LogMessage { impl Display for LogMessage
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { {
self.0.fmt(f) // just display LogMessageType fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>
} {
self.0.fmt(f) // just display LogMessageType
}
} }
/** /**
@ -118,36 +118,32 @@ pub enum LogMessageType {
* respectively and (hopefully) detailed messages. * respectively and (hopefully) detailed messages.
*/ */
impl LogMessageType { impl LogMessageType
/// Returns a new [`LogMessage`] based on the default verbosity of the given [`LogMessageType`]. {
#[must_use] /// Returns a new [`LogMessage`] based on the default verbosity of the given [`LogMessageType`].
pub fn log_message(&self) -> LogMessage { pub fn log_message(&self) -> LogMessage
let verbosity = match self { {
GenericErr(_) => LogVerbosity::Error, let verbosity = match self
GenericWarn(_) => LogVerbosity::Warning, {
GenericInfo(_) => LogVerbosity::Information, GenericErr(_) => LogVerbosity::Error,
GenericDebug(_) => LogVerbosity::Debugging, GenericWarn(_) => LogVerbosity::Warning,
}; GenericInfo(_) => LogVerbosity::Information,
GenericDebug(_) => LogVerbosity::Debugging,
};
LogMessage(self.clone(), verbosity) LogMessage(self.clone(), verbosity)
} }
} }
impl Display for LogMessageType { impl Display for LogMessageType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>
match self { {
GenericErr(err) => { match self
write!(f, "Generic Error: {err}") {
} GenericErr(err) => { write!(f, "Generic Error: {err}") },
GenericWarn(warn) => { GenericWarn(warn) => { write!(f, "Generic Warning: {warn}") },
write!(f, "Generic Warning: {warn}") GenericInfo(info) => { write!(f, "Generic Information: {info}") },
} GenericDebug(debug) => { write!(f, "Generic Debug Message: {debug}") },
GenericInfo(info) => { }
write!(f, "Generic Information: {info}") }
}
GenericDebug(debug) => {
write!(f, "Generic Debug Message: {debug}")
}
}
}
} }