use super::{RollingFileAppender, Rotation};
use std::{io, path::Path};
use thiserror::Error;
#[derive(Debug)]
pub struct Builder {
pub(super) rotation: Rotation,
pub(super) prefix: Option<String>,
pub(super) suffix: Option<String>,
pub(super) latest_symlink: Option<String>,
pub(super) max_files: Option<usize>,
}
#[derive(Error, Debug)]
#[error("{context}: {source}")]
pub struct InitError {
context: &'static str,
#[source]
source: io::Error,
}
impl InitError {
pub(crate) fn ctx(context: &'static str) -> impl FnOnce(io::Error) -> Self {
move |source| Self { context, source }
}
}
impl Builder {
#[must_use]
pub const fn new() -> Self {
Self {
rotation: Rotation::NEVER,
prefix: None,
suffix: None,
latest_symlink: None,
max_files: None,
}
}
#[must_use]
pub fn rotation(self, rotation: Rotation) -> Self {
Self { rotation, ..self }
}
#[must_use]
pub fn filename_prefix(self, prefix: impl Into<String>) -> Self {
let prefix = prefix.into();
let prefix = if prefix.is_empty() {
None
} else {
Some(prefix)
};
Self { prefix, ..self }
}
#[must_use]
pub fn filename_suffix(self, suffix: impl Into<String>) -> Self {
let suffix = suffix.into();
let suffix = if suffix.is_empty() {
None
} else {
Some(suffix)
};
Self { suffix, ..self }
}
#[must_use]
pub fn max_log_files(self, n: usize) -> Self {
Self {
max_files: Some(n).filter(|&n| n > 0),
..self
}
}
#[must_use]
pub fn latest_symlink(self, name: impl Into<String>) -> Self {
let name = name.into();
let latest_symlink = if name.is_empty() { None } else { Some(name) };
Self {
latest_symlink,
..self
}
}
pub fn build(&self, directory: impl AsRef<Path>) -> Result<RollingFileAppender, InitError> {
RollingFileAppender::from_builder(self, directory)
}
}
impl Default for Builder {
fn default() -> Self {
Self::new()
}
}