use noyalib::compat::serde_yaml;
use serde::Deserialize;
use super::DocError;
#[derive(Debug, Clone, PartialEq)]
pub struct LogsAssertion {
pub contains: Vec<String>,
pub regex: Vec<String>,
pub no_level_above: Option<LogLevel>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LogLevel {
Trace,
Debug,
Info,
Warn,
Error,
}
#[derive(Deserialize)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
struct RawLogs {
contains: Option<Vec<String>>,
regex: Option<Vec<String>>,
no_level_above: Option<String>,
}
pub(super) fn logs_from_raw(value: serde_yaml::Value) -> Result<LogsAssertion, DocError> {
let block_error = |detail: String| DocError::LogsBlock { detail };
let raw: RawLogs = serde_yaml::from_value(value).map_err(|e| block_error(e.to_string()))?;
let no_level_above = raw
.no_level_above
.as_deref()
.map(|raw_level| match raw_level {
"trace" => Ok(LogLevel::Trace),
"debug" => Ok(LogLevel::Debug),
"info" => Ok(LogLevel::Info),
"warn" => Ok(LogLevel::Warn),
"error" => Ok(LogLevel::Error),
other => Err(block_error(format!(
"`logs.noLevelAbove` must be one of trace|debug|info|warn|error, got `{other}`"
))),
})
.transpose()?;
for pattern in raw.regex.iter().flatten() {
if let Err(error) = regex::Regex::new(pattern) {
return Err(block_error(format!(
"`logs.regex` entry `{pattern}` does not compile: {error}"
)));
}
}
Ok(LogsAssertion {
contains: raw.contains.unwrap_or_default(),
regex: raw.regex.unwrap_or_default(),
no_level_above,
})
}